diff --git a/.babelrc b/.babelrc index b34fc21bf4..1e14605139 100644 --- a/.babelrc +++ b/.babelrc @@ -1,9 +1,31 @@ { - "presets": [ "env" ], - "plugins": [ - [ "module-resolver", { - "alias": { "pods-dfv": "./ui/js/pods-dfv" } - } ], - "transform-html-import-to-string" - ] + "presets": [ + [ "@babel/preset-env" ], + [ "@babel/preset-react" ] + ], + "plugins": [ + [ + "babel-plugin-module-resolver", + { + "alias": { + "dfv": "./ui/js/dfv" + } + } + ], + "babel-plugin-transform-html-import-to-string", + "@babel/plugin-transform-strict-mode", + "@babel/plugin-proposal-optional-chaining" + ], + "env": { + "development": { + "presets": [ + [ "@babel/preset-react", { "development": true } ] + ] + }, + "production": { + "plugins": [ + "transform-react-remove-prop-types" + ] + } + } } diff --git a/.env b/.env new file mode 100644 index 0000000000..8f373f8619 --- /dev/null +++ b/.env @@ -0,0 +1,63 @@ +# Custom vars for Pods. +PODS_LOAD_DATA=true +PODS_REBUILD_DATA=false + +# This file will be consumed by both the CI and the tests. +# Some environment variables might not apply to one but might apply to the other: modify with care. + +# What version of WordPress we want to install and test against. +# This has to be compatible with the `wp core download` command, see https://developer.wordpress.org/cli/commands/core/download/. +# WP_VERSION=latest # NOTE: Already defined in .travis.yml matrix. + +# A space-separated list of plugin repositories that will be cloned in the WordPress installation folder and that are +# required for the plugin tests. +# E.g. "acme/plugin-one acme/plugin-two pirates/plugin-three". +# This value will be used in a bash array declaration to iterate and clone the plugins one by one; validate locally the +# format of this array using this bash command after exporting the var: +# declare -a plugins=(`echo ${REQUIRED_PLUGIN_REPOS}`); for p in "${plugins[@]}"; do echo "$p"; done +REQUIRED_PLUGIN_REPOS="" + +# This is where, in the context of the CI, we'll install and configure WordPress. +# See `.travis.yml` for more information. +WP_ROOT_FOLDER=/tmp/wordpress + +# The WordPress installation will be served from the Docker container. +# See `dev/docker/ci-compose.yml` for more information. +WP_URL=http://localhost:8080 +WP_DOMAIN=localhost:8080 + +# The credentials that will be used to access the site in acceptance tests +# in methods like `$I->loginAsAdmin();`. +WP_ADMIN_USERNAME=admin +WP_ADMIN_PASSWORD=password + +WP_DB_PORT=4306 + +# The database is served from the Docker `db` container. +# See `dev/docker/ci-compose.yml` for more information. +WP_TABLE_PREFIX=wp_ +WP_DB_HOST=127.0.0.1:4306 +WP_DB_NAME=wordpress +WP_DB_USER=root +WP_DB_PASSWORD= + +# The test database is served from the Docker `db` container. +# See `dev/docker/ci-compose.yml` for more information. +WP_TEST_DB_HOST=127.0.0.1:4306 +WP_TEST_DB_NAME=test +WP_TEST_DB_USER=root +WP_TEST_DB_PASSWORD= + +# We're using Selenium and Chrome for acceptance testing. +# In CI context we're starting a Docker container to handle that. +# See the `dev/docker/ci-compose.yml` file. +CHROMEDRIVER_HOST=localhost +CHROMEDRIVER_PORT=4444 + +# The URL of the WordPress installation from the point of view of the Chromedriver container. +# Why not just use `wordpress`? While Chrome will accept an `http://wordpress` address WordPress +# will not, we call the WordPress container with a seemingly looking legit URL and leverage the +# lines that, in the `wp-config.php` file, will make it so that WordPress will use as its home +# URL whatever URL we reach it with. +# See the `dev/docker/wp-config.php` template for more information. +WP_CHROMEDRIVER_URL="wp.test" diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000..f3b297d358 --- /dev/null +++ b/.env.example @@ -0,0 +1,15 @@ +WP_ROOT_FOLDER="/Users/you/Local Sites/test-pods-dev/app/public" +WP_DOMAIN="test.pods.dev" +WP_URL="http://test.pods.dev" +WP_ADMIN_USERNAME="admin" +WP_ADMIN_PASSWORD="password" +DB_HOST="192.168.95.100:1234" +DB_NAME="local" +DB_USER="root" +DB_PASSWORD="root" +TEST_DB_HOST="192.168.95.100:1234" +TEST_DB_NAME="local" +TEST_DB_USER="root" +TEST_DB_PASSWORD="root" +PODS_LOAD_DATA=true +PODS_REBUILD_DATA=false diff --git a/.env.testing.tric b/.env.testing.tric new file mode 100644 index 0000000000..ea0b0fffa8 --- /dev/null +++ b/.env.testing.tric @@ -0,0 +1,66 @@ +# Custom vars for Pods. +PODS_LOAD_DATA=true +PODS_REBUILD_DATA=false + +# This file will be consumed by both the CI and the tests. +# Some environment variables might not apply to one but might apply to the other: modify with care. + +# What version of WordPress we want to install and test against. +# This has to be compatible with the `wp core download` command, see https://developer.wordpress.org/cli/commands/core/download/. +# WP_VERSION=latest # NOTE: Already defined in .travis.yml matrix. + +# A space-separated list of plugin repositories that will be cloned in the WordPress installation folder and that are +# required for the plugin tests. +# E.g. "acme/plugin-one acme/plugin-two pirates/plugin-three". +# This value will be used in a bash array declaration to iterate and clone the plugins one by one; validate locally the +# format of this array using this bash command after exporting the var: +# declare -a plugins=(`echo ${REQUIRED_PLUGIN_REPOS}`); for p in "${plugins[@]}"; do echo "$p"; done +REQUIRED_PLUGIN_REPOS="" + +# This is where, in the context of the CI, we'll install and configure WordPress. +# See `.travis.yml` for more information. +WP_ROOT_FOLDER=/var/www/html + +# The WordPress installation will be served from the Docker container. +# See `dev/docker/ci-compose.yml` for more information. +WP_URL=http://wordpress.test +WP_DOMAIN=wordpress.test + +# The credentials that will be used to access the site in acceptance tests +# in methods like `$I->loginAsAdmin();`. +WP_ADMIN_USERNAME=admin +WP_ADMIN_PASSWORD=password + +WP_DB_PORT=3306 + +# The database is served from the Docker `db` container. +# See `dev/docker/ci-compose.yml` for more information. +WP_TABLE_PREFIX=wp_ +WP_DB_HOST=db +WP_DB_NAME=test +WP_DB_USER=root +WP_DB_PASSWORD=password + +# The test database is served from the Docker `db` container. +# See `dev/docker/ci-compose.yml` for more information. +WP_TEST_DB_HOST=db +WP_TEST_DB_NAME=test +WP_TEST_DB_USER=root +WP_TEST_DB_PASSWORD=password + +# We're using Selenium and Chrome for acceptance testing. +# In CI context we're starting a Docker container to handle that. +# See the `dev/docker/ci-compose.yml` file. +CHROMEDRIVER_HOST=chrome +CHROMEDRIVER_PORT=4444 + +# The URL of the WordPress installation from the point of view of the Chromedriver container. +# Why not just use `wordpress`? While Chrome will accept an `http://wordpress` address WordPress +# will not, we call the WordPress container with a seemingly looking legit URL and leverage the +# lines that, in the `wp-config.php` file, will make it so that WordPress will use as its home +# URL whatever URL we reach it with. +# See the `dev/docker/wp-config.php` template for more information. +WP_CHROMEDRIVER_URL=http://wordpress.test + +# We're using Docker to run the tests. +USING_CONTAINERS=1 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..0bc1780b1c --- /dev/null +++ b/.eslintignore @@ -0,0 +1,10 @@ +# Ignore everything except `blocks` and `dfv` +ui/js/codemirror +ui/js/marionette +ui/js/selectWoo +ui/js/sprintf +ui/js/timepicker +ui/js/*.js + +# Ignore minified files +**/*.min.js diff --git a/.eslintrc.json b/.eslintrc.json index be46f1f5a1..e463afbddc 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,32 +1,34 @@ { + "parser": "babel-eslint", + "parserOptions": { "ecmaVersion": 2016, + "ecmaFeatures": { + "jsx": true + }, "sourceType": "module" }, "extends": [ - "wordpress", - "plugin:react/recommended" + "plugin:@wordpress/eslint-plugin/custom", + "plugin:@wordpress/eslint-plugin/esnext", + "plugin:@wordpress/eslint-plugin/es5", + "plugin:@wordpress/eslint-plugin/jsx-a11y", + "plugin:@wordpress/eslint-plugin/react", + "plugin:@wordpress/eslint-plugin/i18n", + "plugin:@wordpress/eslint-plugin/test-e2e", + "plugin:@wordpress/eslint-plugin/test-unit" ], - "rules": { - "object-curly-spacing": ["error", "always"], - - "space-in-parens": ["error", "always"], - - "space-before-function-paren": ["error", { - "anonymous": "always", - "named": "always", - "asyncArrow": "always" - }], - - "lines-around-comment": [ "error", { - "beforeLineComment": false, - "beforeBlockComment": false - }], + "rules": {}, - "space-unary-ops": [ "error", { - "nonwords": false - }] - } + "overrides": [ + { + "excludedFiles": "*.min.js", + "files": [ "**/test/*.js" ], + "env": { + "jest": true + } + } + ] } diff --git a/.gitattributes b/.gitattributes index 27ab1a0c85..09a4fed665 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,46 +1,61 @@ # Auto detect text files and perform LF normalization * text=auto -# Ignore +*.css linguist-generated=true +*.min.css linguist-generated=true +*.min.js linguist-generated=true +*.snap linguist-generated=true +tests/_support/_generated/* linguist-generated=true + +# Export ignore handling # Directories -/.wordpress-org export-ignore /.github export-ignore +/.wordpress-org export-ignore /bin export-ignore +/dev export-ignore /docs export-ignore /tests export-ignore -/ui/js/pods-dfv/src export-ignore -/ui/js/pods-dfv/pods-dfv.min.js.map export-ignore +/ui/js/blocks/src export-ignore +/ui/js/dfv/pods-dfv.min.js.map export-ignore +/ui/js/dfv/src export-ignore /ui/styles/src export-ignore -# Files -.gitattributes export-ignore -.gitignore export-ignore - +# Dot-files .babelrc export-ignore .editorconfig export-ignore .env export-ignore .env.example export-ignore +.env.testing.tric export-ignore +.eslintignore export-ignore .eslintrc.json export-ignore +.gitattributes export-ignore +.gitignore export-ignore .jshintrc export-ignore +.nvmrc export-ignore +.phpstorm.meta.php export-ignore .scrutinizer.yml export-ignore .travis.yml export-ignore -CODEOWNERS export-ignore +# Other files CODE_OF_CONDUCT.md export-ignore -CONTRIBUTING.md export-ignore -Gruntfile.js export-ignore -README.md export-ignore -TESTS.md export-ignore codeception.dist.yml export-ignore codeception.example.yml export-ignore +codeception.tric.yml export-ignore +CODEOWNERS export-ignore composer.json export-ignore +CONTRIBUTING.md export-ignore +Gruntfile.js export-ignore jest-setup-wordpress-globals.js export-ignore jest.config.json export-ignore +package-lock.json export-ignore package.json export-ignore +phpcs.xml export-ignore phpcs.xml.dist export-ignore phpunit.xml.dist export-ignore +README.md export-ignore rollup.config.js export-ignore +TESTS.md export-ignore webpack.common.js export-ignore webpack.dev.js export-ignore webpack.prod.js export-ignore diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 100ac84863..2adc845703 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,10 +13,17 @@ name: "CodeQL" on: push: + # The branches below must be a subset of the branches above branches: [ main, release/* ] + paths-ignore: + - 'tribe-common/*' + - 'vendor/*' pull_request: # The branches below must be a subset of the branches above branches: [ main, release/* ] + paths-ignore: + - 'tribe-common/*' + - 'vendor/*' schedule: - cron: '41 15 * * 4' diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml index 00dc7c9a42..1488892595 100644 --- a/.github/workflows/phpcs.yml +++ b/.github/workflows/phpcs.yml @@ -1,19 +1,21 @@ name: 'PHP CodeSniffer' on: pull_request: - paths-ignore: - - 'lang/**' - - '**.txt' - - '**.md' - - '.editorconfig' - - 'CODEOWNERS' + paths: + - 'classes/**.php' + - 'components/**.php' + - 'includes/**.php' + - 'src/**.php' + - 'sql/**.php' + - 'ui/**.php' + - '*.php' jobs: phpcs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: - fetch-depth: 100 + ref: ${{ github.event.pull_request.head.sha }} - name: Get Composer Cache Directory id: composer-cache run: | @@ -24,6 +26,8 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-composer- - - uses: the-events-calendar/action-tribe-phpcs@master - with: - github-bot-token: ${{ secrets.GH_BOT_TOKEN }} + - name: Run PHPCS inspection + uses: rtCamp/action-phpcs-code-review@v2 + env: + GH_BOT_TOKEN: ${{ secrets.GH_BOT_TOKEN }} + SKIP_FOLDERS: "tests,.github,tribe-common,vendor" diff --git a/.github/workflows/tests-js.yml b/.github/workflows/tests-js.yml new file mode 100644 index 0000000000..df4f1d9282 --- /dev/null +++ b/.github/workflows/tests-js.yml @@ -0,0 +1,26 @@ +name: 'JS Tests' +on: + pull_request: + paths: + - 'ui/js/**' + - 'package.json' + - 'webpack.*.js' + - 'jest-setup-wordpress-globals.js' + - 'jest.config.json' + - '.github/workflows/tests-js.yml' +jobs: + test: + strategy: + matrix: + suite: [ 'jest' ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: '12.x' + - name: Install dependencies + run: npm install + - name: Run JS test suite + run: npm run ${{ matrix.suite }} diff --git a/.github/workflows/tests-php.yml b/.github/workflows/tests-php.yml new file mode 100644 index 0000000000..79e7a1a808 --- /dev/null +++ b/.github/workflows/tests-php.yml @@ -0,0 +1,129 @@ +name: 'Codeception Tests' +on: + pull_request: + paths: + - 'classes/**.php' + - 'components/**.php' + - 'includes/**.php' + - 'src/**.php' + - 'sql/**.php' + - 'tests/codeception/**' + - 'ui/**.php' + - '*.php' + - 'composer.json' + - 'codeception.*.yml' + - '.github/workflows/tests-php.yml' +jobs: + test: + strategy: + fail-fast: false + matrix: + suite: + - wpunit --skip-group=pods-shortcode + - wpunit --group=pods-shortcode + - wpunit-traversal + - restv1 + runs-on: ubuntu-latest + steps: + # ------------------------------------------------------------------------------ + # Checkout the repo and tric + # ------------------------------------------------------------------------------ + - name: Checkout the repository + uses: actions/checkout@v2 + with: + fetch-depth: 1 + token: ${{ secrets.GH_BOT_TOKEN }} + submodules: recursive + - name: Checkout tric + uses: actions/checkout@v2 + with: + repository: the-events-calendar/tric + ref: main + path: tric + fetch-depth: 1 + # ------------------------------------------------------------------------------ + # Prepare our composer cache directory + # ------------------------------------------------------------------------------ + - name: Get Composer Cache Directory + id: get-composer-cache-dir + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + - uses: actions/cache@v2 + id: composer-cache + with: + path: ${{ steps.get-composer-cache-dir.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + # ------------------------------------------------------------------------------ + # Initialize tric + # ------------------------------------------------------------------------------ + - name: Set up tric env vars + run: | + echo "TRIC_BIN=${GITHUB_WORKSPACE}/tric/tric" >> $GITHUB_ENV + echo "TRIC_WP_DIR=${GITHUB_WORKSPACE}/tric/_wordpress" >> $GITHUB_ENV + echo "TRIC_WORDPRESS_DOCKERFILE=Dockerfile.base" >> $GITHUB_ENV + - name: Set run context for tric + run: echo "TRIC=1" >> $GITHUB_ENV && echo "CI=1" >> $GITHUB_ENV + - name: Start ssh-agent + run: | + mkdir -p "${HOME}/.ssh"; + ssh-agent -a /tmp/ssh_agent.sock; + - name: Export SSH_AUTH_SOCK env var + run: echo "SSH_AUTH_SOCK=/tmp/ssh_agent.sock" >> $GITHUB_ENV + - name: Set up tric for CI + run: | + cd ${GITHUB_WORKSPACE}/.. + ${TRIC_BIN} here + ${TRIC_BIN} interactive off + ${TRIC_BIN} build-prompt off + ${TRIC_BIN} build-subdir off + ${TRIC_BIN} xdebug off + ${TRIC_BIN} composer-cache set /home/runner/.cache/composer + ${TRIC_BIN} debug on + ${TRIC_BIN} info + ${TRIC_BIN} config + # ------------------------------------------------------------------------------ + # Set up Pods + # ------------------------------------------------------------------------------ + - name: Set up pods + run: | + docker network prune -f + ${TRIC_BIN} use pods + ${TRIC_BIN} composer install + # ------------------------------------------------------------------------------ + # Set up ET (npm install and build) + # ------------------------------------------------------------------------------ + - name: Set up Pods (npm) + if: ${{ matrix.suite == 'acceptance' }} + run: | + ${TRIC_BIN} npm install + ${TRIC_BIN} npm run build + # ------------------------------------------------------------------------------ + # Init WordPress container + # ------------------------------------------------------------------------------ + - name: Init the WordPress container + run: | + ${TRIC_BIN} up wordpress + ${TRIC_BIN} site-cli core version + # ------------------------------------------------------------------------------ + # Install and activate TwentyTwenty + # ------------------------------------------------------------------------------ + - name: Install and activate TwentyTwenty + if: ${{ matrix.suite == 'acceptance' }} + run: ${TRIC_BIN} site-cli theme install twentytwenty --activate + # ------------------------------------------------------------------------------ + # Run tests + # ------------------------------------------------------------------------------ + - name: Run suite tests + run: ${TRIC_BIN} run ${{ matrix.suite }} --ext DotReporter + # ------------------------------------------------------------------------------ + # Upload artifacts (On failure) + # ------------------------------------------------------------------------------ + - name: Upload artifacts + uses: actions/upload-artifact@v2 + if: failure() + with: + name: output ${{ matrix.suite }} + path: tests/_output/ + retention-days: 7 diff --git a/.gitignore b/.gitignore index 07d17d034e..37d95407b9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,24 +31,29 @@ $RECYCLE.BIN/ .metadata /build/ /tmp/ -tests/clover.xml # NPM / Composer -composer.lock +/composer.lock /node_modules/ vendor/* npm-debug.log -# PHPunit config -phpunit.xml - # Source maps should just be built locally ui/js/pods-ui-ready.min.js.map -/package-lock.json -/phpcs.xml -# PHPCS reports +# PHPCS phpcs-report-*.txt + +# Tests - local config files +codeception.yml +tests/codeception/*.suite.yml +tests/codeception/_support/_generated +.env.local + +# Tests - local output files +tests/codeception/_output +/coverage/ + # Allowed vendor files !vendor/freemius diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index ec8b104b11..0000000000 --- a/.jshintrc +++ /dev/null @@ -1,31 +0,0 @@ -{ - "esversion": 6, - "mocha": true, - "module": true, - "node": true, - "browser": true, - - "trailing": true, - "white": true, - "noempty": true, - "nomen": true, - "noarg": true, - "smarttabs": true, - "eqeqeq": true, - "newcap": true, - "nocomma": true, - "immed": true, - "nonbsp": true, - "bitwise": true, - "curly": true, - "undef": true, - "nonew": true, - "forin": true, - - "globals": { - "jQuery": false, - "_": false, - "Backbone": false, - "Marionette": false - } -} \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..9cd25a1fec --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +12.18.3 diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 0000000000..bcd0ecace0 --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,12 @@ + '@', + '' => '@Class', + ] ) + ); +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 663aff8e40..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,56 +0,0 @@ -language: php - -sudo: false - -services: - - mysql - -php: - - 7.1 - -env: - - WP_VERSION=nightly WP_MULTISITE=0 NODE_RELEASE=stable - - WP_VERSION=latest WP_MULTISITE=0 NODE_RELEASE=stable - - WP_VERSION=latest WP_MULTISITE=1 NODE_RELEASE=stable - -matrix: - allow_failures: - - env: WP_VERSION=nightly WP_MULTISITE=0 NODE_RELEASE=stable - - php: 7.3 - env: WP_VERSION=latest WP_MULTISITE=0 NODE_RELEASE=stable - - include: - - php: 7.2 - env: WP_VERSION=latest WP_MULTISITE=0 NODE_RELEASE=stable - - php: 7.0 - env: WP_VERSION=latest WP_MULTISITE=0 NODE_RELEASE=stable - - php: 5.6 - env: WP_VERSION=latest WP_MULTISITE=0 NODE_RELEASE=stable - -## Cache composer and node bits -cache: - apt: true - directories: - - vendor - - node_modules - - $HOME/.composer/cache - -before_install: - - | # Only do npm install if we're running the latest stable node (Pipe preserves subsequent whitespace) - if [ $NODE_RELEASE == "stable" ]; then - . $HOME/.nvm/nvm.sh; - nvm install ${NODE_RELEASE}; - npm install; - fi - -before_script: - - bash bin/init.sh - - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION - - ln -s . /tmp/wordpress/wp-content/plugins/pods - -script: - - vendor/bin/phpunit - - | # Only run js tests if we're running the latest stable node (Pipe preserves subsequent whitespace) - if [ $NODE_RELEASE == "stable" ]; then - npm run test-dfv; - fi diff --git a/.wordpress-org/screenshot-1.jpg b/.wordpress-org/screenshot-1.jpg deleted file mode 100644 index 87266f16f8..0000000000 Binary files a/.wordpress-org/screenshot-1.jpg and /dev/null differ diff --git a/.wordpress-org/screenshot-1.png b/.wordpress-org/screenshot-1.png new file mode 100644 index 0000000000..d936888e9e Binary files /dev/null and b/.wordpress-org/screenshot-1.png differ diff --git a/.wordpress-org/screenshot-2.jpg b/.wordpress-org/screenshot-2.jpg deleted file mode 100644 index 052b822890..0000000000 Binary files a/.wordpress-org/screenshot-2.jpg and /dev/null differ diff --git a/.wordpress-org/screenshot-2.png b/.wordpress-org/screenshot-2.png new file mode 100644 index 0000000000..793e79058c Binary files /dev/null and b/.wordpress-org/screenshot-2.png differ diff --git a/.wordpress-org/screenshot-3.jpg b/.wordpress-org/screenshot-3.jpg deleted file mode 100644 index 2e232daf25..0000000000 Binary files a/.wordpress-org/screenshot-3.jpg and /dev/null differ diff --git a/.wordpress-org/screenshot-3.png b/.wordpress-org/screenshot-3.png new file mode 100644 index 0000000000..f2b3d24822 Binary files /dev/null and b/.wordpress-org/screenshot-3.png differ diff --git a/.wordpress-org/screenshot-4.jpg b/.wordpress-org/screenshot-4.jpg deleted file mode 100644 index c720835376..0000000000 Binary files a/.wordpress-org/screenshot-4.jpg and /dev/null differ diff --git a/.wordpress-org/screenshot-4.png b/.wordpress-org/screenshot-4.png new file mode 100644 index 0000000000..c730cbd0b4 Binary files /dev/null and b/.wordpress-org/screenshot-4.png differ diff --git a/.wordpress-org/screenshot-5.jpg b/.wordpress-org/screenshot-5.jpg deleted file mode 100755 index 6a74ff52c9..0000000000 Binary files a/.wordpress-org/screenshot-5.jpg and /dev/null differ diff --git a/.wordpress-org/screenshot-5.png b/.wordpress-org/screenshot-5.png new file mode 100644 index 0000000000..83bf3eae5c Binary files /dev/null and b/.wordpress-org/screenshot-5.png differ diff --git a/.wordpress-org/screenshot-6.jpg b/.wordpress-org/screenshot-6.jpg deleted file mode 100644 index 6fad9096a2..0000000000 Binary files a/.wordpress-org/screenshot-6.jpg and /dev/null differ diff --git a/.wordpress-org/screenshot-6.png b/.wordpress-org/screenshot-6.png new file mode 100644 index 0000000000..25dc5cefd4 Binary files /dev/null and b/.wordpress-org/screenshot-6.png differ diff --git a/.wordpress-org/screenshot-7.jpg b/.wordpress-org/screenshot-7.jpg deleted file mode 100755 index 354bf97459..0000000000 Binary files a/.wordpress-org/screenshot-7.jpg and /dev/null differ diff --git a/Gruntfile.js b/Gruntfile.js index 0ad40e764c..db1e2e3ef3 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,5 @@ /*jshint node: true */ -module.exports = function ( grunt ) { +module.exports = function( grunt ) { 'use strict'; // load all grunt tasks in package.json matching the `grunt-*` pattern @@ -8,25 +8,51 @@ module.exports = function ( grunt ) { grunt.loadNpmTasks( 'grunt-exec' ); const config = { - pkg : grunt.file.readJSON( 'package.json' ), replace : { - version_readme_txt : { - src : ['readme.txt'], overwrite : true, replacements : [ + pkg: grunt.file.readJSON( 'package.json' ), + replace: { + version_readme_txt: { + src: [ 'readme.txt' ], + overwrite: true, + replacements: [ { - from : /Stable tag: (.*)/, to : "Stable tag: <%= pkg.version %>" - } - ] - }, version_init_php : { - src : ['init.php'], overwrite : true, replacements : [ + from: /Stable tag: ([\.\d\w\-]*)/, + to() { + return 'Stable tag: ' + grunt.option( 'ver' ) || pkg.version; + }, + }, + ], + }, + version_init_php: { + src: [ 'init.php' ], + overwrite: true, + replacements: [ + { + from: /Version:\s+([\.\d\w\-]*)/, + to() { + return 'Version: ' + grunt.option( 'ver' ) || pkg.version; + }, + }, { - from : /Version: (.*)/, to : "Version: <%= pkg.version %>" + from: /define\( 'PODS_VERSION', '([\.\d\w\-]*)' \);/, + to() { + return "define( 'PODS_VERSION', '" + ( grunt.option( 'ver' ) || pkg.version ) + "' );"; + }, }, + ], + }, + version_package: { + src: [ 'package.json' ], + overwrite: true, + replacements: [ { - from : /define\( 'PODS_VERSION', '([\.\d\w\-]*)' \);/, - to : "define( 'PODS_VERSION', '<%= pkg.version %>' );" - } - ] - } - } + from: /"version": "([\.\d\w\-]*)"/, + to() { + return '"version": "' + ( grunt.option( 'ver' ) || pkg.version ) + '"'; + }, + }, + ], + }, + }, }; // Project configuration. @@ -34,7 +60,8 @@ module.exports = function ( grunt ) { // dev tasks grunt.registerTask( 'version_number', [ + 'replace:version_package', 'replace:version_readme_txt', - 'replace:version_init_php' + 'replace:version_init_php', ] ); }; diff --git a/README.md b/README.md index 8acace905e..b2a50d97d2 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,22 @@ This is where we develop Pods Framework itself and should _not_ be used for supp If you find an issue that you believe to be a *bug*, [let us know](https://github.com/pods-framework/pods/issues?state=open). +## Requirements + +### Recommended + +* WordPress 5.2+ +* PHP 7.3+ +* MySQL 5.6+ or MariaDB 10.1+ + +### Minimum + +If you have restrictions on your server or site, these are the minimum versions that Pods will be supported to run on. Running the following minimum versions does bring with it their own risks including security and exposure to additional bugs that may have been resolved by the recommended versions above. + +* WordPress 4.9+ +* PHP 5.6+ +* MySQL 5.5+ + ## Contributions Welcome Anyone is welcome to contribute to Pods Framework. Please read the [guidelines for contributing](CONTRIBUTING.md) to this repository. diff --git a/TESTS.md b/TESTS.md new file mode 100644 index 0000000000..84cd7816d1 --- /dev/null +++ b/TESTS.md @@ -0,0 +1,46 @@ +# Pods Tests + +## Setup + +Before you run tests, you'll want to ensure you run the composer install: + +``` +composer install +``` + +Now you'll want to ensure you have a local WP/DB set up. Once you confirm you have that done, you can setup your .env.local file. Copy the `.env.example` file to `.env.local` and fill in your local paths and DB connection information. + +Copy the `codeception.example.yml` file to `codeception.yml`, and you're all set to run tests. + + +## Running Tests + +Running tests is pretty simple, you just run the codeception command `codecept` and which suite to run: + +``` +vendor/bin/codecept run wpunit -vvv +``` + +## Testing Traversal (find/field/display) + +Running traversal tests requires use a different codeception test suite `wpunit-traversal` which makes use of special configuration files (see tests/codeception/_data/traversal-*.json). These tests have to be run apart from the other tests to prevent pollution of their configurations or data in the much more cleaner `wpunit` tests: + +``` +vendor/bin/codecept run wpunit-traversal -vvv +``` + +## Testing NPM + +To run the JS tests, you'll want to first follow instructions to [setup nvm/npm](https://gist.github.com/d2s/372b5943bce17b964a79). + +Once you have that setup, you can run the npm install: + +``` +npm install +``` + +Now you can run the tests: + +``` +npm run jest +``` diff --git a/bin/after.sh b/bin/after.sh deleted file mode 100644 index f1f641af19..0000000000 --- a/bin/after.sh +++ /dev/null @@ -1 +0,0 @@ -#!/usr/bin/env bash diff --git a/bin/ide-before-launch.sh b/bin/ide-before-launch.sh deleted file mode 100755 index 2481c95b88..0000000000 --- a/bin/ide-before-launch.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -DB_NAME=wordpress_test -DB_USER=root -DB_PASS=root -DB_HOST=localhost - -set -ex - -install_db() { - echo "Setting up Database for Unit Tests" - - # parse DB_HOST for port or socket references - local PARTS=(${DB_HOST//\:/ }) - local DB_HOSTNAME=${PARTS[0]}; - local DB_SOCK_OR_PORT=${PARTS[1]}; - local EXTRA="" - - if ! [ -z $DB_HOSTNAME ] ; then - if [[ "$DB_SOCK_OR_PORT" =~ ^[0-9]+$ ]] ; then - EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" - elif ! [ -z $DB_SOCK_OR_PORT ] ; then - EXTRA=" --socket=$DB_SOCK_OR_PORT" - elif ! [ -z $DB_HOSTNAME ] ; then - EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" - fi - fi - - echo "Removing existing Database" - - # drop database - mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA -e "DROP DATABASE IF EXISTS $DB_NAME" - - echo "Creating Database" - - # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA - - echo "Database set up" -} - -cd .. -install_db \ No newline at end of file diff --git a/bin/init.sh b/bin/init.sh deleted file mode 100644 index 322a9d4736..0000000000 --- a/bin/init.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - - -echo "Removing xdebug from PHP" -phpenv config-rm xdebug.ini - -# @todo: TRAVIS_PHP_VERSION = PHPEnv -# https://github.com/travis-ci/travis-ci/issues/780 - -if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.3" ]]; - then - composer require --dev --no-update "phpunit/phpunit:4.8" - echo "PHP: 5.3 / PHPUnit 4.8" -elif [[ ${TRAVIS_PHP_VERSION:0:3} == "5.6" ]]; - then - composer require --dev --no-update "phpunit/phpunit:5.*" - echo "PHP: 5.6 / PHPUnit 5" -elif [[ ${TRAVIS_PHP_VERSION:0:3} == "7.0" ]]; - then - composer require --dev --no-update "phpunit/phpunit:6.*" - echo "PHP: 7.0 / PHPUnit 6" -elif [[ ${TRAVIS_PHP_VERSION:0:3} == "7.1" ]]; - then - composer require --dev --no-update "phpunit/phpunit:6.*" - echo "PHP: 7.1 / PHPUnit 6" - -elif [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]]; - then - composer require --dev --no-update "phpunit/phpunit:6.*" - echo "PHP: 7.2 / PHPUnit 6" -else - Echo "Cannot determine PHP version, therefore using PHPUnit as specified in composer" -fi - -echo "Composer: update" -composer self-update -echo "Composer: installing dependancies" -composer install --no-interaction --prefer-source diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh deleted file mode 100755 index 253c8eac65..0000000000 --- a/bin/install-wp-tests.sh +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env bash - -if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version] [force download] [skip-database-creation]" - exit 1 -fi - -DB_NAME=$1 -DB_USER=$2 -DB_PASS=$3 -DB_HOST=${4-localhost} -WP_VERSION=${5-latest} -FORCE=${6-false} -SKIP_DB_CREATE=${7-false} - -WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} - -# Placeholder for download agent -# @todo replace back to wget everywhere in this file -download() { - - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi - -} - -# Detect version tag -# Format: N.N.N -if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then - WP_TESTS_TAG="tags/$WP_VERSION" -elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - WP_TESTS_TAG="trunk" -else - # http serves a single offer, whereas https serves multiple. we only want one - download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json - grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json - LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') - - if [[ -z "$LATEST_VERSION" ]]; then - echo "Latest WordPress version could not be found" - exit 1 - fi - - WP_TESTS_TAG="tags/$LATEST_VERSION" -fi - -if [[ $WP_TESTS_TAG == *"beta"* ]] -then - WP_TESTS_TAG="trunk" -fi - -set -ex - -install_wp() { - - echo "Installing WordPress for Unit Tests" - - if [[ $FORCE == 'true' || -z TRAVIS_JOB_ID ]]; then - echo "Removing existing core WordPress directory" - - rm -Rf $WP_CORE_DIR - fi - - if [ -d $WP_CORE_DIR ]; then - return; - fi - - echo "Downloading WordPress" - - mkdir -p $WP_CORE_DIR - - if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - mkdir -p /tmp/wordpress-nightly - download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip - unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ - mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR - else - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' - else - local ARCHIVE_NAME="wordpress-$WP_VERSION" - fi - - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - fi - - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php - - echo "WordPress installed" - -} - -install_test_suite() { - - echo "Installing Tests Suite for Unit Tests" - - if [[ $FORCE == 'true' || -z TRAVIS_JOB_ID ]]; then - echo "Removing existing Tests Suite directory" - - rm -Rf $WP_TESTS_DIR - fi - - # portable in-place argument for both GNU sed and Mac OS X sed - if [[ $(uname -s) == 'Darwin' ]]; then - local ioption='-i .bak' - else - local ioption='-i' - fi - - # set up testing suite if it doesn't yet exist - if [ ! -d $WP_TESTS_DIR ]; then - echo "Downloading Tests Suite" - - # set up testing suite - mkdir -p $WP_TESTS_DIR - svn export --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes $WP_TESTS_DIR/includes - svn export --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data $WP_TESTS_DIR/data - fi - - cd $WP_TESTS_DIR - - if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php - # remove all forward slashes in the end - WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php - fi - - echo "Tests Suite installed" - -} - -install_db() { - - if [ ${SKIP_DB_CREATE} = "true" ]; then - return 0 - fi - - echo "Setting up Database for Unit Tests" - - # parse DB_HOST for port or socket references - local PARTS=(${DB_HOST//\:/ }) - local DB_HOSTNAME=${PARTS[0]}; - local DB_SOCK_OR_PORT=${PARTS[1]}; - local EXTRA="" - - if ! [ -z $DB_HOSTNAME ] ; then - if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then - EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" - elif ! [ -z $DB_SOCK_OR_PORT ] ; then - EXTRA=" --socket=$DB_SOCK_OR_PORT" - elif ! [ -z $DB_HOSTNAME ] ; then - EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" - fi - fi - - if [[ $FORCE == 'true' || -z TRAVIS_JOB_ID ]]; then - echo "Removing existing Database" - - # drop database - mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA -e "DROP DATABASE IF EXISTS $DB_NAME" - fi - - echo "Creating Database" - - # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA - - echo "Database set up" - -} - -install_wp -install_test_suite -install_db \ No newline at end of file diff --git a/bin/local-flywheel-wp-tests.sh b/bin/local-flywheel-wp-tests.sh deleted file mode 100755 index 5d3324fd39..0000000000 --- a/bin/local-flywheel-wp-tests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -./bin/install-wp-tests.sh wordpress_test root root localhost latest true false \ No newline at end of file diff --git a/bin/phpcs-audit.sh b/bin/phpcs-audit.sh deleted file mode 100755 index 6c1b3bb0eb..0000000000 --- a/bin/phpcs-audit.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Run this command from the repo root. -# The path argument you pass will be relative to the repo root. - -# Example usage: -# bash bin/phpcs-audit.sh -# bash bin/phpcs-audit.sh classes/fields -# bash bin/phpcs-audit.sh classes/fields/text.php - -# Generate custom report files like report-full-text.txt using second argument for affix: -# bash bin/phpcs-audit.sh classes/fields/text.php -text - -default_path="." -file_path=${1:-$default_path} - -default_file_affix="" -file_affix=${2:-$default_file_affix} - -declare -a types=("full" "source") - -echo Running PHPCS reports - -for type in ${types[@]} -do - echo Running PHPCS report: ${type} - ./vendor/bin/phpcs --report="${type}" --report-file="phpcs-report-${type}${file_affix}.txt" ${file_path} -done; diff --git a/bin/phpcs-autofix.sh b/bin/phpcs-autofix.sh deleted file mode 100755 index 875da37bfb..0000000000 --- a/bin/phpcs-autofix.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# Run this command from the repo root. -# The path argument you pass will be relative to the repo root. - -# Example usage: -# bash bin/phpcs-autofix.sh -# bash bin/phpcs-autofix.sh classes/fields -# bash bin/phpcs-autofix.sh classes/fields/text.php - -default_path="." -file_path=${1:-$default_path} - -echo Running PHPCS autofix -./vendor/bin/phpcbf ${file_path} diff --git a/bin/run-tests.sh b/bin/run-tests.sh deleted file mode 100644 index 7ab7fc9df7..0000000000 --- a/bin/run-tests.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -default_path='' -test_path=${1:-$default_path} - -./vendor/bin/phpunit ${test_path} \ No newline at end of file diff --git a/bin/vagrant-wp-tests.sh b/bin/vagrant-wp-tests.sh deleted file mode 100755 index 5d3324fd39..0000000000 --- a/bin/vagrant-wp-tests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -./bin/install-wp-tests.sh wordpress_test root root localhost latest true false \ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000000..3f9cb28f72 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,1006 @@ +Found a bug? Have a great feature idea? Get on GitHub and tell us about it and we'll get right on it: https://pods.io/submit/ + +Our GitHub has the full list of all prior releases of Pods: https://github.com/pods-framework/pods/releases + += 2.8 - October 12th, 2021 = + +Read the full [Pods 2.8 Field Guide](https://pods.io/2021/02/11/pods-2-8-beta-1-released-and-the-field-guide-to-pods-2-8/) which includes information about all of the features, enhancements, and changes in this major Pods release. + +**Breaking compatability warning:** +* New minimum required versions have been updated as follows which includes notices to let you know if you need to update something. +* New minimum WP version required: WordPress 5.5+ (previously: WP 4.5+) โ€” Going forward we will support the last two major WP releases on each major feature release of Pods. +* New minimum PHP version required: PHP 5.6+ (previously: PHP 5.3+) โ€” Hey! You should take the time to update to PHP 7.4+ because thereโ€™s major speed improvements to be had ๐Ÿ™‚ +* New minimum MySQL version required: MySQL 5.5+ (previously: MySQL 5.1+) +* Refactored object handling for Pod and Field configurations โ€” instead of passing around arrays we now are using a fully scoped object for these configs. This gives us flexibility to lazy load and pull things as-needed from the database instead of always pulling entire Pods and Fields configurations all at once on any page it may not be needed. This also reduces how much we have to use/cache on each page further reducing overall memory usage on every page. It remains backward compatible in most array usage cases like `$pod['name']` but be aware that PHP ArrayAccess overloading errors may occur when manipulating Pod configs like `$pod['fields']['your_field']['name'] = 'My new field name';` or `$pod['options']['some_option'] = 1;` + +**Features and changes in this release** +* Feature: Now you can add multiple groups of fields. (@sc0ttkclark, @zrothauser) +* Feature: Our Edit Pod screen is powered by our all new React form interfaces, tooltips, and they use our new Pods Admin REST API endpoints. (@sc0ttkclark, @zrothauser) +* Feature: All of our form fields are powered by React now in preparation for Pods 2.9 repeatable fields that we're working on next. (@sc0ttkclark, @zrothauser) +* Feature: New field types for Heading and HTML. (@sc0ttkclark, @zrothauser) +* Feature: New Pods Blocks available and the underlying Pods Block PHP API is compatible with ACF Blocks if you've ever used those before. (@sc0ttkclark, @zrothauser) +* Feature: REST API endpoints are now available to create/edit various objects: Pods, Pod Groups, and Pod Fields. (@sc0ttkclark) +* Feature: WP-CLI commands that mirror the REST API endpoints we have. (@sc0ttkclark) +* Feature: The new WYSIWYG editor option to use [Quill Editor](https://github.com/zenoamaro/react-quill) is now available and the CLEditor has been removed. (@sc0ttkclark, @zrothauser) + += 2.7.31 - September 23rd, 2021 = + +* Pods 2.8 is coming on October 12th! Check out the [Pods 2.8 Field Guide](https://pods.io/2021/02/11/pods-2-8-beta-1-released-and-the-field-guide-to-pods-2-8/) for more information. +* Fixed: Resolve issues where searching a Pod would cause queries like `post_title.t` or `display_name.t` unexpectedly. #6050 (@sc0ttkclark, @unknownnf) + += 2.7.30 - August 12th, 2021 = + +* Fixed: Prevented a few PHP notices from showing on the new WordPress 5.8+ widgets screen. + += 2.7.29 - August 4th, 2021 = + +* Security: Clean up post type and taxonomy labels so they avoid potential output escaping problems in WordPress core (@sc0ttkclark, reported by Muhammad Daffa via WPScan) +* Friends of Pods: Updated CTA text about our 2021 donor goals. (@sc0ttkclark) +* Added: Support for Timezones in datetime / time fields. #6042 (@JoryHogeveen) +* Added: Support for Pantheon WP Native Sessions plugin. (@sc0ttkclark) +* Enhancement: Optimized the PNG image assets using PNG8+Alpha with ImageAlpha and ImageOptim. #6028 (@lowwebtech) +* Fixed: Hidden fields now properly submit correctly. (@sc0ttkclark) +* Fixed: Post type `has_archive` no gets set to a false properly when disabled. #6069 (@JoryHogeveen) +* Fixed: Resolve PHP `strlen()`` warnings when validating text values being saved. #6062 (@pd-cm, @sc0ttkclark, @JoryHogeveen) +* Fixed: Sorting URLs in `PodsUI` include `post_type` and `taxonomy` when Advanced Content Types are set to be underneath a Post Type's top level menu. #6040 (@JoryHogeveen) +* Fixed: Fallback to the manage fields in `PodsUI` for reordering when reorder fields are not overridden. #6058 (@JoryHogeveen) +* Fixed: Depend on plupload when showing custom upload directory option for file fields. (@JoryHogeveen) + += 2.7.28 - May 20th, 2021 = + +* Added: New upload directory option for File fields using Plupload that lets you choose to customize which directory the files end up in. #6021 (@JoryHogeveen) +* Added: Relationship fields now support custom selectors in the REST API. You can specify `my_field.some_field` to output a specific field in your REST API options for each relationship field. (@sc0ttkclark) +* Added: New `pods_image_for_post()` and `pods_image_url_for_post()` functions have been added for certain page builders like Oxygen. (@sc0ttkclark) +* Added: New query variable prefix option (`num_prefix`) for PodsUI instances. (@sc0ttkclark) +* Added: `pagination_type` and `pagination_location` options for PodsUI instances to support more flexible pagination options. (@sc0ttkclark) +* Enhancement: Implement `search` and `sort` field sets for PodsUI instances to more easily specify which fields are searchable or sortable. (@sc0ttkclark) +* Fixed: PHP fatal errors no longer occur for avatar fields in certain situations. #6007 (@JoryHogeveen) +* Fixed: PHP fatal errors no longer occur for PHP 8 in certain situations. #6012 (@JoryHogeveen) +* Fixed: Resolved an issue with relationship fields not outputting their full data to the REST API when the related object is not a valid pod. (@sc0ttkclark) +* Fixed: Resolved an issue with not saving the fields for the extended Media pod when making update requests through the REST API. (@sc0ttkclark) +* Fixed: Implemented a temporary PHP 7.4+ fix for Freemius. (@sc0ttkclark) +* Fixed: Searching WP-based objects in PodsUI interfaces now resolves to the proper fields. (@sc0ttkclark) + += 2.7.27 - March 4th, 2021 = + +* Fixed: Resolved PHP notice in the PodsAPI. #5952 (@sc0ttkclark) +* Fixed: Resolved PHP notice when using `?pods_debug_sql=1` on Pods Admin UI screens. (@sc0ttkclark) + += 2.7.26 - January 8th, 2021 = + +* Fixed: Prevent PHP warnings in the `components/Templates/includes/element-pod_reference.php` file. #5914 (@JoryHogeveen) +* Added: New filter `pods_shortcode_detect_from_current_post` allows you to override whether a shortcode should detect the post object outside of the loop (default is only when `in_the_loop()`). This helps to fix problems that are part of the integration which the free Pods Beaver Themer Add-On uses. (@sc0ttkclark) + += 2.7.25 - December 28th 2020 = + +**New Features & Enhancements** + +* Added: Custom no access message for templates. #5875 (@JoryHogeveen) +* Added: New filter `pods_field_validate_{$type}`. #1106 (@JoryHogeveen) + +**Bug Fixes** + +* Fixed: Ensure compatibility with the WordPress 5.6 jQuery update. #5892, #5896 & #5897 (@JoryHogeveen) +* Fixed: Prevent `wp_unslash()` from unnecessarily over sanitizing input. #5040 & #4424 (@JoryHogeveen) +* Fixed: Prevent issues with HTML entities in custom relationship values when it gets to JavaScript. #5894 (@JoryHogeveen) +* Fixed: Better support multiple languages in the Relationship AJAX search. #5888 (@JoryHogeveen) +* Fixed: Include the `post_type` value in attachment saves so that the more WordPress core actions trigger. #5748 (@JoryHogeveen) +* Fixed: Allow `the_excerpt` to be used as custom filter on singular pages. #5899 (@JoryHogeveen) +* Fixed: Better support caching of the avatar images/data and integrate with the `get_avatar_data` filter. #5771 (@JoryHogeveen) + + += 2.7.24 - November 5th 2020 = + +**Bug Fixes** + +* Fixed: Fix media `[each]` loop if no `media` Pod exists. #5882 (@JoryHogeveen) +* Fixed: Fallback to default display field if custom option is invalid for relationship fields. #5839 & #5859 (@JoryHogeveen) +* Fixed: Use `pathinfo` to properly validate file extension. #5876 (@JoryHogeveen) + += 2.7.23 - October 30th 2020 = + +**New Features & Enhancements** + +* Added: Support auto-templates for taxonomies, users and comments. #3962 & #5832 (@JoryHogeveen, @sc0ttkclark, @gwhitney) +* Added: Support template parameter and nested shortcode content for field shortcodes. #5801 (@JoryHogeveen) +* Added: Allow function calls in all tags, not just template tags. #4887 (@JoryHogeveen) +* Added: Support custom image sizes for all image field types in magic tags. #5870 (@JoryHogeveen) +* Added/Fixed: Support special magic tags in Pods Templates. #5697 (@JoryHogeveen) +* Added/Fixed: Support Pod related magic tags in shortcode query parameters. #5734 (@JoryHogeveen) +* Enhancement: Allow traversing in avatar attachment. #5870 (@JoryHogeveen) +* Enhancement: If the media Pod exists, use it's context to run media loops to support other fields and traversal. #5855 (@JoryHogeveen) +* Enhancement: Implement PHP 5.4 `session_status()` function. #5840 (@JoryHogeveen) +* Enhancement: Allow WP objects to be passed in `pods()`. #5845 (@JoryHogeveen) +* Compatibility: Enqueue DFV scripts when editing the page with Beaver Builder to fully support the media window. #5799 (@JoryHogeveen) +* Updated: Primary Branch header for GitHub Updater. #5847 (@afragen) + +**Bug Fixes** + +* Fixed: `.src` tags for PDF's now render the PDF file link instead of the thumbnail in templates `[each]` loops. #4040 (@JoryHogeveen) +* Fixed. HTML entities for relationship fields UI. #5843, #5835 & #5796 (@JoryHogeveen, @sc0ttkclark) +* Fixed: Select2/SelectWoo now also enqueue the locale files when available. #5860 (@JoryHogeveen) +* Fixed: Support lowercase ID's for magic tags in media loops #5852 (@JoryHogeveen, @sc0ttkclark) +* Fixed: Avatar should always return a square image. #2738 (@JoryHogeveen) +* Fixed: Selected items query for autocomplete relationships. #5542 & #5831 (@JoryHogeveen) +* Fixed: Prevent SQL errors on magic tags in some cases. #5797 (@JoryHogeveen, @sc0ttkclark) +* Fixed: Error if there is no DB prefix available. #5803 (@JoryHogeveen, @sc0ttkclark) +* Fixed: Fix edge case "No Access" error when all Pods were deleted. Redirect to next Pod admin page if needed. #4842 (@JoryHogeveen) +* Fixed: Removed empty filter in `ui/admin/setup-edit-field.php`. #5686 (@sc0ttkclark, @JoryHogeveen) +* Fixed: Prevent possible notice if image doesn't exist. #5866 (@JoryHogeveen) +* Fixed: Remove source maps from production builds. #5822 (@sc0ttkclark) +* Fixed: PHP warning in file field gallery view. #5809 (@JoryHogeveen) + += 2.7.22 - August 13th 2020 = + +**Bug Fixes** + +* Fixed: WP 5.5+ compatibility layer for postbox headers so they appear and work correctly while still working for previous versions of WordPress. #5806 (@sc0ttkclark) +* Fixed: Patched a Freemius JS file that needed updating for WP 5.5+ compatibility. #5806 (@sc0ttkclark) +* Fixed: Prevent fatal errors about memory when using preview links for Advanced Content Types. #5783 (@JoryHogeveen) +* Fixed: Prevent fatal errors about memory when using certain magic tag / thumbnail combinations. #5805 (@JoryHogeveen) +* Fixed: Resolve our DFV JS `
` issues with `PodsUI` filters and add `.toggle-row` class handling for frontend. #5806 (@sc0ttkclark) +* Fixed: Ensure REST API responses for Media returns correct value when extended by Pods. #5763 (@JoryHogeveen) +* Fixed: Ensure pods_permission() unserializes when role/capability data is serialized. #5768 (@JoryHogeveen) + += 2.7.21 - June 30th 2020 = + +**New Features & Enhancements** + +* Added: New filter: `pods_field_pick_object_data_params`. #5756 (@JoryHogeveen) +* Added: Pods fields & magic tags: Traverse through serialized metadata. #5603 (@JoryHogeveen) +* Added: Support `get_query_var()` in pods_v (and thus special magic tags: `{@query.##}`). #5719 (@JoryHogeveen) +* Added: WYSIWYG field option for custom editor height. #5673 (@JoryHogeveen) +* Enhancement: REST field options: Only display depth for array response type. #5714 (@JoryHogeveen) +* Updated: Refactor Pods::field() method. #5682 (@JoryHogeveen) + +**Bug Fixes** + +* Fixed: Relationship dropdown error & encoding. #5740 (@JoryHogeveen) +* Fixed: Getting single vs multiple metadata values edge case errors. #5661 (@JoryHogeveen) +* Fixed: Nested relationship fields should render as array of objects in REST. #5745 (@lkraav) +* Fixed: Add `noopener` and `noreferrer` for all target `_blank` links. #5742 (@JoryHogeveen) +* Fixed: Only check `delete_users` for single installations in `pods_is_admin()`. #5712 (@JoryHogeveen) +* Fixed: Deprecated taxonomy form actions. #5700 (@JoryHogeveen) +* Fixed: DateTime field: Allow input values compatible with the display format. #5687 (@JoryHogeveen) +* Fixed: Whitespace trimming for templates. #5672 (@sc0ttkclark) +* Fixed: Taxonomy option rewrite with front label tooltip. #5681 (@JoryHogeveen) +* Fixed: Pods test factory compatibility with WP core text factory. #5716 (@JoryHogeveen) + += 2.7.20.1 - June 4th 2020 = + +* Security: Remove deprecated usage of escapeMarkup in selectWoo and tighten JS rendering (@sc0ttkclark, @miha.jirov) + += 2.7.20 - April 5th 2020 = + +**Bug Fixes** + +* Fixed: Resolved issues with Freemius notices not being able to be properly dismissed. (@sc0ttkclark) + += 2.7.19 - April 5th 2020 = + +This version was bugged due to a deployment that sent out a copy of 2.7.18 as 2.7.19. + += 2.7.18 - April 3rd 2020 = + +**New Features & Enhancements** + +* Added: Add is_required() helper method for fields objects to abstract some logic. #5657 (@JoryHogeveen) +* Updated: Removed duplicate code from pods_list_filter() that is now in wp_list_filter(). #5644 (@JoryHogeveen) +* Updated: Now prefixing the Templates and Pages component menu items with "Pod" so they aren't as easily confused with normal WordPress menu items. #5647 (@JoryHogeveen) + +**Bug Fixes** + +* Fixed: Compatibility layer for ACF so it won't conflict anymore. #5667 (@sc0ttkclark) +* Fixed: Remove PHP 5.6+ only code that was causing issues for those running older PHP versions. #5659 (@JoryHogeveen) +* Fixed: Prevent PHP errors when enforcing numeric values during validation of number fields. #5666 (@JoryHogeveen) +* Fixed: Prevent deprecated warnings with special magic tags usage like `{@user.id}` instead of `{@user.ID}`. #5642 (@JoryHogeveen) +* Fixed: Fix the decimal/thousands separator logic used for number and currency field validation and saving. #5653 (@JoryHogeveen) +* Fixed: Resolve issues with `[if]` and `[else]` logic for boolean fields that was causing it to always evaluate to true. #5656 (@JoryHogeveen) +* Fixed: Only load Freemius on Pods Admin, Plugins, or the Updates screens. (@sc0ttkclark) + += 2.7.17.1 - March 27th 2020 = + +**Bug Fixes** + +* Fixed: Double comma in custom pick display formats. #5637 (@JoryHogeveen) +* Fixed: Auto `use_current` not working correctly outside the loop. #5636 (@JoryHogeveen) +* Fixed: pods_trim() does not trim whitespaces by default. #5640 (@JoryHogeveen) + += 2.7.17 - March 26th 2020 = + +**New Features & Enhancements** + +* Added: New callout for our Friends of Pods program will show up on the Pods Admin > Pods list so we can let people know how to donate. #5571 (@nicdford, @sc0ttkclark, @JoryHogeveen) +* Added: Freemius integration to support our new Friends of Pods add-ons and enable us to let people opt-in to usage stats for planning future compatibility decisions. #5624 (@sc0ttkclark) +* Added: New `not_found` tag to the Pods shortcode to return default string if no output is empty. #5580 (@JoryHogeveen) +* Added: New hooks when saving field table definitions (table-based Pods). #5623 (@sc0ttkclark) +* Added: New custom multi-relationship display format. #5612 (@JoryHogeveen) +* Added: Support traversing into post thumbnails objects. #5610 (@JoryHogeveen) +* Compatibility: Add ACF backwards compatibility functions/shortcode. #4855 (@sc0ttkclark) +* Compatibility: WordPress 5.4 - Add user Pod fields to privacy export data. #5606 (@JoryHogeveen) +* Compatibility: Match WordPress 5.4 CSS changes. #5608 (@JoryHogeveen) +* Enhancement: Shortcodes now automatically revert to the current queried object. #5598 (@JoryHogeveen) +* Enhancement: Add "full" to available image sizes. #5185 (@JoryHogeveen) +* Enhancement: Set Pods current queried object detection based on class instances instead of class parameters. #5617 (@JoryHogeveen) +* Docs: Update inline docs for pick field selected logic. #5014 & #5017 (@sc0ttkclark) + +**Bug Fixes** + +* Fixed: Date/Time - Correct empty value validation. #5534 & #5544 (@JoryHogeveen) +* Fixed: Date/Time - Allow midnight (00:00:00) as time value. #5616 (@JoryHogeveen) +* Fixed: Number/Currency - Parsing error for number format 9'999.99. #5559 & #5597 (@JoryHogeveen) +* Fixed: Number/Currency - Do not set default value of `0` if field is empty. #5539 (@JoryHogeveen) +* Fixed: CLI export/export-item commands. #5041 (@0xLBF) +* Fixed: Allow No (0) as an answer for radio and select boolean fields. #5549 (@JoryHogeveen) +* Fixed: Prevent get_meta() cache loop. #5577 (@JoryHogeveen) +* Fixed: Pods component descriptions. #5543 (@JoryHogeveen) +* Fixed: PHP 7.4 - Array and string offset access syntax with curly braces is deprecated. #5582 (@JoryHogeveen) +* Fixed: PHP 7.4 - Trying to access array offset on value of type bool. #5556 & #5615 (@JoryHogeveen) +* Fixed: PHP 7.4 - Array access notices. #5631 (@JoryHogeveen) +* Fixed: Replaced hook used for meta boxes in admin for custom component integrations to avoid deprecated notices from WordPress. #5622 (@sc0ttkclark) +* Fixed: Prevented potential fatal errors on Pod Template editor screen when pod configuration is broken. #5622 (@sc0ttkclark) +* Docs: Link to Gallery Documentation in Image field inline help doc. #5541 (@wpacademy) + += 2.7.16.2 - November 14th 2019 = + +* Fixed: The last SVN tag was temporarily missing files, this release just ensures people get the update that has all files. + += 2.7.16.1 - November 13th 2019 = + +* Fixed: Reverted changes in #5289 to auto templates that introduced breaking changes. We will revisit this in a future maintenance release. #5531 + += 2.7.16 - November 13th 2019 = + +**Enhancements** + +* Enhancement: CSS fixes for WP 5.3. #5501 (@JoryHogeveen) +* Enhancement: Format traversed fields properly. #4932 (@jamesgol) +* Enhancement: ACT list view pagination. #5510 (@JoryHogeveen) +* Enhancement: Add PODS_SHORTCODE_ALLOW_EVALUATE_TAGS to debug info. #5310 (@JoryHogeveen) + +**Bug Fixes** + +* Fixed: Avoid SQL errors when using special magic tags. #5310 (@sc0ttkclark) +* Fixed: Validate shortcode query tags before default to current object. #5520 (@JoryHogeveen) +* Fixed: Unslash simple relationship values to support saving quoted values. #5517 (@JoryHogeveen) +* Fixed: Add sanitize_title optional to sluggables instead of applying default. #5516 (@JoryHogeveen) +* Fixed: DateTime: Always parse any manual input data. Also fixes clearing values. #5488 (@JoryHogeveen) +* Fixed: DateTime: jQuery date & time picker overlapping formats. #5467 (@JoryHogeveen) +* Fixed: DateTime: Fix datetime-local HTML5 input format. #5460 (@JoryHogeveen) +* Fixed: Could not submit a form if required checkbox not ticked. #5481 (@Turkal) +* Fixed: Allow migrate packages to import pages. #5476 (@jamesgol) +* Fixed: Allow pods_str_replace() function to handle non-strings. #5254 (@jamesgol) +* Fixed: Refactor and fix issues with Advanced Content Types capabilities. #5504 (@JoryHogeveen) +* Fixed: Add `object` key to prevent undefined index notice. #5493 (@JoryHogeveen) +* Fixed: Make sure number of arguments passed to PodsMeta->save_post() is correct. #5512 (@jamesgol) +* Fixed: ACT pagination URL for child type. #5510 (@JoryHogeveen) +* Fixed: Custom table relationships SQL error. #5505 (@JoryHogeveen) +* Fixed: Allow Pods to ALTER table if the SQL field definition has changed. #5507 (@jamesgol) +* Fixed: Admin menu: set hook priority to 9 instead of 99 to fix CPT submenu placement. #5497 (@JoryHogeveen) +* Fixed: Make auto templates for a Taxonomy Pod behave sensibly. #5289 (@gwhitney, @sc0ttkclark, @JoryHogeveen) + += 2.7.15 - September 5th 2019 = + +**Enhancements** + +* Enhancement: Add year range option to date & datetime fields. #5442 (@JoryHogeveen) +* Enhancement: Support single select relationships in templates when using `[each]`. #4507 (@sc0ttkclark, @JoryHogeveen) +* Enhancement: Prevent creation of Pods using reserved keywords from WordPress Codex and Pods. #5428 (@JoryHogeveen) +* Enhancement: Allow all callables to be passed in magic tags. #5436 (@JoryHogeveen) + +**Bug Fixes** + +* Fixed: Always convert database value for date/time fields without timezone to maintain the actual value. #5423 & #5424 (@JoryHogeveen) +* Fixed: Solve issues with saving date/time fields in other locales. #5444, #5421, #5415 & #5451 (@JoryHogeveen) +* Fixed: Import from file with absolute path. #5430 (@mistraloz) +* Fixed: Fix numeric soft format issue removing decimals & numeric slider input formatting. #5281 & #5215 (@JoryHogeveen) +* Fixed: Fix & improve error handling & debug logs. #5452, #5450, #5440, #5419, #5435 & #5453 (@JoryHogeveen) +* Fixed: Corrected Malaysian Ringgit currency sign. #5446 (@JoryHogeveen) +* Fixed: Flush Pod cache before returning errors, #5420 (@JoryHogeveen) + += 2.7.14 - July 9th 2019 = + +**Bug Fixes** + +* Fixed: Always convert database value for date/time fields with UTC timezone to maintain the actual value, #5382, #5402, #5403 (@JoryHogeveen) +* Fixed: Stop add new button from being disabled when no selection has been made yet for single select, #5401 (@pglewis) +* Fixed: Resolved PHP notices in `PodsAPI::save_pod_item()`, #5411 (@pglewis) + += 2.7.13 - June 28th 2019 = + +**Enhancements** + +* Enhancement: Support meta fields as display field for relationships, #5299 (@sc0ttkclark) +* Enhancement: DateTime/Time field code and performance #5302 (@JoryHogeveen) +* Enhancement: Added Nigerian Naira currency, #5377 (@webcreativeng) +* Enhancement: Added filter `pods_enqueue_dfv_on_front` for enqueueing DFV scripts on frontend, #5313 & #5303 (@nicdford) +* Added: Add debug information for Pods to Site Health Info area, #5399 (@sc0ttclark, @JoryHogeveen) + +**Bug Fixes** + +* Fixed: Cursor is jumping to the start of the block when Gutenberg autosaves, #5274 (@pglewis) +* Fixed: Select drop-downs set to required, #5031 (@pglewis) +* Fixed: HTML escaping issue in the Manage Fields list, #5246 (@pglewis) +* Fixed: Translate Pods stuck with Portuguese translation in the Admin menus, #5259 (@JoryHogeveen) +* Fixed: option cache handling when using external object cache, #5294 (@sc0ttkclark) +* Fixed: Fix force WWW option on website/URL fields, #4881 (@pglewis) +* Fixed: Phone field should not put anything in the field input on 'blank' values, #4881 (@pglewis) +* Fixed: Versioned tag names are not compatible with Composer, #5278 (@pglewis) +* Fixed: `get_post_meta()` always retriggers `pods_transient_set()`, #4690 (@pglewis) +* Fixed: Date output in magic tags for date fields uses DateTime class by default instead of date_il8n, #5296 (@JoryHogeveen) +* Fixed: PHP 7.3 `compact()` notices due to undefined var names, #5266 (@sc0ttkclark) +* Fixed: Use `Marionette.noConflict()` to keep a private copy of Marionette, #5237 & #5354 (@pglewis) +* Fixed: Remove floats from fields within pods manage fields (UI), #5362 (@nicdford) +* Fixed: Set table charset for Pods Advanced Content Types to WP default charset, #5276 (@JoryHogeveen) +* Fixed: Avoid PHP warnings by removing unused $check_value logic in PodsField_Pick, #5205 (@ziqbal, @JoryHogeveen) +* Fixed: Fix PodsData fetch for when using object cache and settings pages, #4960 (@pcfreak30, @sc0ttclark, @JoryHogeveen) +* Fixed: Moved session_id() check outside the big conditional so it's always executed, #5182 (@mastef) +* Fixed: Change deprecated (since WP 5.1) hook `wpmu_new_blog` to `wp_insert_site` with backwards compatibility, #5369 (@JoryHogeveen) +* Fixed: Error when PodsInit isn't available on network pages, #3353 (@JoryHogeveen) +* Fixed: Shortcodes no longer stop the page from loading when they encounter SQL errors, #5279 (@sc0ttclark, @JoryHogeveen) + += 2.7.12 - December 20th 2018 = + +**Enhancements** + +* Enhancement: Sort currency list alphabetically by name, add Indonesian Rupiah (Rp) and US Cent currency support, #5247 (@sc0ttkclark) + +**Bug Fixes** + +Fixed: Serial comma display works again for Users, Comments, and Media relationships when used in Pods::display() and magic tag templating without specifying the object field you want to display, #5251 (@sc0ttkclark) + += 2.7.11 - December 7th 2018 = + +**Enhancements** + +* Enhancement: Added: New pods_data_auto_calculate_total_found filter can be set to true to auto-calculate total_found() number right away after a Pods::find() query runs, defaults to false, #5232, (@sc0ttkclark) + +**Bug Fixes** + +* Fixed: Javascript errors on pages without the Gutenberg editor active under certain circumstances, #5225 (@pglewis) +* Fixed: Avoid extra user queries when not necessary, #5230 (@sc0ttkclark) + += 2.7.10 - December 5th 2018 = + +**Gutenberg / WordPress 5.0 Compatibility** + +* Fixed: TinyMCE Compatibility Bug for Gutenberg, #5217 (@pglewis) +* Fixed: Read-only Checkboxes now properly save values as 0 or 1, #4961 (@atanas-angelov-dev) +* Fixed: Scrollbar Compatibility bug for List View in Gutenberg Editor, #5220 (@pglewis) +* Fixed: Modal Support for Gutenberg, Add/edit Modal now triggers save and close to the modal, #5191 (@pglewis) +* Fixed: Component header parsing for developer/tableless mode, #5222 (@sc0ttkclark) +* Fixed: Currency symbol no longer overlays input field in WP 5.0, #5219 (@pglewis, @sc0ttkclark) + +**Enhancements** + +* Enhancement: Added support for new WP 5.0 custom post type labels used by Gutenberg, #5223 (@wpstudio, @sc0ttkclark) +* Enhancement: Add pods conditional logic handling on frontend forms, #5136 (@JoryHogeveen) +* Enhancement: Add current memory usage to stats, #5178 (@sc0ttkclark) +* Enhancement: Add support for Taxonomy descriptions, #4766 (@sc0ttkclark) +* Enhancement: Component Pages does not allow adding page templates in plugins, #4734 (@creabrain) +* Enhancement: Add Pods functions to Query Monitor conditional, #5208 (@JoryHogeveen) +* Enhancement: Add bi-directional status label to relationship fields, #5200 (@JoryHogeveen) +* Enhancement: Removed old forum feed, inserted the wordpress.org feed, and squelched warnings from SimplePie/PHP 7+, #5172, #4363 (@pglewis) + +**Bug Fixes** + +* Fixed: pods->save() does not clear fields with shorthand syntax, #5166 (@mastef) +* Fixed: Comma character breaks custom post type dropdown, #2042 (@sc0ttkclark) +* Fixed: Compatibility with Admin Columns 3.2+, #5129 (@JoryHogeveen, @DGStefan) +* Fixed: Missing Styles of DFV form field using $pods->form, #5056 (@pglewis) +* Fixed: "Single Select" Relationship Return differently depending on Format, #5138 (@pglewis) +* Fixed: Media modal doesn't work on frontend using pods form, #4715 (@pglewis) +* Fixed: Use minified versions of Backbone.Marionette and Backbone.Radio, #5115 +* Fixed: Always enqueue the DFV script by default if in the admin, #5111 (@pglewis, @sc0ttkclark) +* Fixed: Add static groups cache for PodsMeta::groups_get() to improve memory usage on bulk wp_insert_post and other similar calls, #5088 (@sc0ttkclark) +* Fixed: Only disable components when using PODS_TABLELESS if the component is relying on custom tables, #5206 (@JoryHogeveen) +* Fixed: PHP Warning for array key pods_rel not found, #5210 (@JoryHogeveen) + += 2.7.9 - August 9th 2018 = + +**Features/Enhancements** + +* Added: Support for Pods::fields() argument keyed which when set to true will return the array for relationship fields with the IDs used as keys, #5092 (@sc0ttkclark) +* Added: pods_shortcode_output filter to allow customization of shortcode output based on shortcode attributes, #5083 (@sc0ttkclark) + +**Bug Fixes** + +* Fixed: Fix compatibility issue with Polylang & WPML when getting the current language from the edit post and edit tax pages. #5060 (JoryHogeveen) + += 2.7.8 - July 26th 2018 = + +* Hotfix: Time field generates a fatal error on PHP prior to 5.5, #5079 (@davegaeddert) + += 2.7.7 - July 26th 2018 = + +**Features/Enhancements/Improvements** + +* Code Quality: Disallow multiple assignments and assignment inside conditions, #5021 (@GaryJones) +* Code Quality: WordPress.WhiteSpace.PrecisionAlignment compliance, #5026 (@GaryJones) +* Code Quality: Use interpolation to construct all dynamic hook names, #4992 (@GaryJones) + +**Bug Fixes** + +* Fixed: 'others' capability checks for current_user_can pods_{$action}{$pod} vs pods{$action}others{$pod} capabilities, #5043 (@Ulminia, @sc0ttkclark) +* Fixed: "Export all" button for ACTs does not work, #5005 (@pglewis) +* Fixed: Pods Template Editor is adding two 'tabs' to the front of the template during Save. #5022 (@pglewis) +* Fixed: Midnight (00:00) results as 'empty' in an [if][/if] Template Tag. #4999 (@pglewis) +* Fixed: Non-internationalized string "Add Another Custom Capability". #5028 (@GaryJones, @pglewis) + += 2.7.6 - June 8th 2018 = + +* Fixed: Records added modally via DFV's 'Add New' are not selected and don't refresh list view in 2.7.5, #5014 (@sc0ttkclark, @pglewis) + += 2.7.5 - June 7th 2018 = + +**Bug Fixes** + +* Fixed: Only flush rewrite rules in an admin context, #5006 (@sc0ttkclark) +* Fixed: SelectWoo fields would sometimes call `focus()` inappropriately #4725 (@GaryJones) + += 2.7.4 - June 6th 2018 = + +**Features/Enhancements** + +* Code Quality: Address some i18n code standard violations, #4982 (@GaryJones) +* Code Quality: All @since and @deprecated tags updated to use three digits everywhere, #4995 (@GaryJones) +* Added: Tooltip for the Hierarchical option for taxonomies, #4949 (@pglewis) + +**Bug Fixes** + +* Fixed: jQuery.fn.size() is deprecated #3898 (@GaryJones) +* Fixed: CLI: Fix missing negation on valid & exists checks #4989 (@GaryJones) +* Fixed: Check for localized 'help' before adding tooltip #4614 (@davidatwhieltrue, @GaryJones) +* Fixed: Autocomplete/List View broken with "Other WP Objects", #4504 (@pglewis, @sc0ttkclark) +* Fixed: HTML entities in a field's description are converted when the Pod is loaded again, #4495 (@pglewis) +* Fixed: Relationship fields related to the _pods_pod or _pods_field post type would not return the correct value, #4979 (@sc0ttkclark) +* Fixed: Code Editor for Pods Template double-escapes HTML when Visual Editor is OFF in WordPress, #3462 (@pglewis) +* Fixed: Pods breaks Theme Editor for PHP files, hangs loopback test #4595, #4931 (@jamesgol, @pglewis) +* Fixed: Time field cannot save midnight #3488, #4937 (@pglewis) +* Fixed: Resolve file uploads directory check logic for file exports #4970 (@elia-senatore-cippest, @sc0ttkclark) +* Fixed: Media modal issues in post edits, #4945, #4967 (@pglewis) +* Fixed: Fatal error if not logged in and accessing wp-admin, #4828 (@therealgilles) +* Fixed: Pick fields with predefined/custom lists using numeric keys not loading values #4892, #4753 (@pglewis) +* Fixed: Non-required color-picker field did not allow saving empty value #4919 (@JoryHogeveen) +* Fixed: CodeMirror fields in Taxonomy and User edit forms #4913 (@pglewis) + += 2.7.3 - May 6th 2018 = + +**Bug Fixes** + +* Fixed: 'search' param for Pods shortcodes #4909 (@pglewis) +* Fixed: 'before_content' and 'after_content' were ignored in widgets #4891 (@pglewis) + += 2.7.2.1 - May 5th 2018 = + +**Developer and deployment enhancements** + +* Added: .editorconfig file [http://editorconfig.org/](http://editorconfig.org/) #4571 (@JoryHogeveen) +* Updated: export-ignore list #4898 (@pglewis) + +**Bug Fixes** + +* Fixed: Pods Widget output #4891 (@pglewis) +* Fixed: Slider controls not showing #4895 (@pglewis) +* Fixed: Fatal exception attempting to parse Persian DateTime strings #4896 (@sc0ttkclark) +* Fixed: Array to string conversion notice in Pods form #4886 (@sc0ttkclark) + += 2.7.2 - May 3rd 2018 = + +**New Features Added** + +* Added WP-CLI commands for Pods, more details at [https://docs.pods.io/advanced-topics/pods-wp-cli/](https://docs.pods.io/advanced-topics/pods-wp-cli/) (@sc0ttkclark) +* Added: Filter HTML class for li.pods-field form element to allow for more styling options. #4813 (@paddelboot) +* Added: Currency field enhancement: Add a currency sign before the field input. #4714 (@JoryHogeveen) +* Added: Currency formats with spacing between currency sign and value #4838 (@JoryHogeveen) + +**Bug Fixes & Corrections** + +* Fixed: Missing thickbox styles for `PodsUI::filters()` #4797 Fixes #4693 which was preventing Advanced Content Type Filters Popup from Loading (@pglewis) +* Fixed: Text field readonly no longer defaults to `true` #4794 Fixes #4791 (@pglewis) +* Fixed: Simplify how we inject the PHP string into the JS #4787 Fixes #4786 which was creating syntax error in JS for number fields (@pglewis) +* Fixed: Tooltips were not working in the Pods Templates or Roles and Capabilities components #4851 (Fixes #4850) (@pglewis) +* Fixed: Isolates qtip styles and functionality to pods only which should hopefully resolve any issues with conflicting with other plugins/themes that may use the tooltip functionality [#4834] Fixes #4832 where tooltips were not displaying (@nicdford) +* Fixed: Tooltip corrections: Update Pods Add New screen for extended taxonomies as Table Storage is not required since Term Meta was added by WordPress. #4609 (@pglewis) +* Fixed: Issue where fields with particularly long post titles would extend past the width of the container #4831( Fixes #4700) (@nicdford) +* Added: appropriate CSS namespace prefixes to avoid style conflicts #4632 (#4612) (@nicdford) +* Fixed: Prefix all form styles with `form.pods-manage`. Namespace prefix all pods-manage styles to avoid CSS conflicts with Gravity forms (#4615,#4612) (@JoryHogeveen) +* Fixed: Pods DFV fields no longer depend upon the specific instance of jQuery shipped with WordPress (#4680). (@pglewis) +* Fixed: Update all storage type tooltips. Many were still referencing old Custom Taxonomy Table Storage requirements that were no longer required after Term Meta support. Fixes #4835 (@pglewis) +* Fixed: Bug with decimal handler when converting to dash (-) #4829 (@JoryHogeveen) +* Fixed: Checkbox misalignment on custom settings pages (#4711) (@JoryHogeveen) +* Fixed: Quality of life visual updates and optimizations for the CLEditor (#4633) (@nicdford) +* Fixed: `%F` with PHP's `sprintf` function defaults to a precision of 6 decimal places, we now include the precision specifier whenever more than 6 decimal places of precision is needed. (#4741) (@0xLBF) +* Fixed: Extend the condition for WPML validation exception to cover the Translation Editor so required fields don't break the Translation Editor in WPML. (#4802) (@dgwatkins) +* Fixed: Corrects most relationship fields on media items when editing in grid mode. Select2 based fields still need a workaround (Autocomplete, List View). (#4795) (@pglewis) +* Fixed: Avoid printing null message in PodsUI #4796 (@davidatwhiletrue) +* Fixed: Single-select Post Thumbnail does not display in Pods Template traversal. Allow traversing into post_thumbnail. (#4719) (@jamesgol) +* Fixed: Disable the "Add New" button for relationships when we're inside a media modal window (#4864). This is just a workaround until we can iron out the CSS and display for a modal from a modal. (@pglewis) +* Fixed: Autotemplate hook validation to verify filter before applying Auto Templates (#4695) (@JoryHogeveen) +* Fixed: Allow user-meta (and other extended Pods) to work in templates (#4847) (@jamesgol) +* Fixed: Corrected conflicts with container CSS/JS around Date/Time Fields (#4878) (@pglewis,@nicdford) + +**Fixes for Unit Testing and Workflow** + +* Fixed: Skip npm install and js tests on the PHP 5.3/Precise box to fix #4788 (#4789) (@pglewis) +* Fixed: mockery 1.0 requires php >=5.6.0; downgrade to 0.9 for now #4818 @pglewis +* Fixed: PHP Codesniffer Fixes #4569 (@sc0ttkclark) +* Fixed: eslint rules and formatting for Javascript (DFV only) #4590 (@sc0ttkclark) + += 2.7.1 - December 8th 2017 = + +* Fix table join logic for taxonomies when renaming meta fields #4613 @sc0ttkclark +* Fix Pods Form submit errors and 404s #4618 @pglewis +* Fix dashicons style conflicts with Pods Form #4626 @nicdford +* Roll-back minimum version requirement for MySQL from 5.5 to 5.1 #4634 @sc0ttkclark + += 2.7 - December 4th 2017 = + +**New PHP & WP Minimum Version Requirements:** + +* PHP Version Change Requirement 5.3+ +* WP Version Change Required 4.5+ + +**Major Changes in 2.7 Release: Flexible Relationships:** + +* New Relationship Field Format "List View": The power of the new flexible relationships is our new modal window that opens within the existing record for relationship fields. This is modeled after the Media Modal from WordPress and provides full functionality to Add New related records or edit existing records all from within the parent record of the relationship. This is provided through our new List View field format for relationship fields. To see a demo of this field in action [head on over to our YouTube](https://youtu.be/V8c067GAEcA) +* Add New with Flexible Relationships: The new flexible relationships will automatically enable Add New on all your existing relationships, but you can disable this from the Additional Options tab for each relationship field. You can switch field formats to the new List View from additional options tab as well. +* Dynamic Field Views: The relationship fields and file upload fields have been rewritten to take advantage of "Dynamic Field Views", driven by JavaScript. More technical details about the directions we went towards these field changes can be read about in our ["Pods 2.7: What We Did and Why We Did It"](https://pods.io/2017/12/05/pods-2-7-developer-notes/) + +**Significant Improvements and Fixes:** + +* Enhancements for Date, Time & Date/Time Fields to improve class inheritance, use WP Defaults and allow for custom options for saving and display @JoryHOgeveen +* Gallery & Tile View for Upload/Media Fields #3589 @JoryHogeveen +* IsEmpty for all Date/Time Fields, Number, Currency, etc. improvements for `[if field][/if]` for Templates @JoryHogeveen +* Major fixes for Pods Templates: Proper handling of shortcodes within Pods Templates and in if/each blocks. Proper handling of all image tags and user traversal @jamesgol +* Comment Traversal #4118 @sc0ttkclark +* Update Compatibility with Admin Columns 3.0+ #4570 @JoryHogeveen +* Filter Added for Select2 Overrides #4571 @sc0ttkclark +* Fix for Advanced Content Types and Relationships in `[each][/each]` tags correcting for lowercase id. #4585 @0xLBF + +**Behind the Scenes Fixes and Improvements:** + +* js unit tests #3640, #4049 @pglewis +* pods_ui_get_params hook #3785 @telwing +* table storage list fields #4420 @jamesgol +* Refactor CSS @nicdford +* Built with Node @pglewis +* Pods Templates added for Polylang Translation Compatibility @JoryHogeveen +* SelectWoo migration from Select2 to address version incompatibilities #4546 @pglewis + +**Known Issues with this Release:** + +* Relationships to Taxonomy have Flexible Relationships disabled as the input screen for Taxonomy was not able to be accessed in an iFrame. Weโ€™re working on this for a future release. + += 2.6.11.2 - August 4th, 2021 = +* Security: Clean up post type and taxonomy labels so they avoid potential output escaping problems in WordPress core (@sc0ttkclark, reported by Muhammad Daffa via WPScan) + += 2.6.11.1 - June 4th, 2020 = +* Security: Remove deprecated usage of escapeMarkup in Select2 (@sc0ttkclark, @miha.jirov) + += 2.6.11 - September 20th 2017 = +* Fixed: WordPress 4.8.2 introduced a breaking change that no longer correctly prepared number/currency queries. It did not introduce a vulnerability but only produced Database errors. +* Stay tuned for Pods 2.7 which will be out soon -- [Download Pods 2.7 RC1](https://github.com/pods-framework/pods/archive/release/2.7.zip) and join our [Pods Slack channel #pods-beta](https://pods.io/chat/) to help us finish the final testing + += 2.6.10 - July 14th 2017 = +* Fixed: Pods Templates were creating erroneous output with nested `[if _fieldname_][else][/if]` and `[each _fieldname_][/each]` template tags inside HTML entities after 2.6.9 upgrade. This fix bypasses `do_shortcode` and also bypasses `do_shortcodes_in_html_tags` which was the problem with this particular fix. Fixes (#4324,#4307,#4307). (#4335). [@pglewis] +* Fixed: Multi-file fields save was causing array to string conversion warning. New function & helper added called `array_filter_walker` for backwards compatibility. Also fixes the 'editable' titles in Multiple File Upload. Fixes (#4112,#4313). (#4314). [@mgratch,@JoryHogeveen,@sc0ttkclark] +* Added: Pods Templates & Page Capabilities have been added to the Members Cap Filter and Pods Role Manager from Components, Roles & Capabilities. This corrects an issue where Pods Templates and Pods Pages were not available to Admins, only Network Admins. Admins will still need to have the pods_templates_ and pods_pages_ capabilities added to their role, but now they'll be able to do this without additional code. Fixes (#4311). (#4342). [@JoryHogeveen] +* Fixed: Corrected 2.x branch for GitHub Feed. Fixes (#4305). (#4306). [@sc0ttkclark] +* Fixed: Minor Spelling fixes related to i18n. (#4276) [@garrett-eclipse] +* Updated: Removed CodeClimate Integration (#4275) and updated glob 7.1 (#4242). [@Ramoonus] + += 2.6.9 - May 30th 2017 = +* Added: Pods Template Component is now automatically active on initial installation or reinstallation of Pods. Fixes (#3446). (#4060,#4180). [@pglewis,@sc0ttkclark] +* Added: Auto Template Fix: Add configurations setting to override and allow Auto Templates to run against the_content outside of the WordPress_Loop. By default now, it will only run inside the WP Loop. (#4088). [@jamesgol] +* Added: Allow raw value in PodsUI rows. New type "raw" that can output HTML form elements; used in i18n component. Fixes (#3959). (#3960). [@JoryHogeveen] +* Fixed: Template Reference in Template Editor now properly displays without running out of memory. Fixes (#3370,#3992). (#4088,#4000). [@jamesgol] +* Fixed: post_author querying now works through traversal of related post type. Fixes (#3931). (#3953,#4065). [@sc0ttkclark,@pglewis] +* Fixed: Search the proper SQL column with "search" and meta based CPT. Fixes (#3858). (#4007). [@jamesgol] +* Fixed: Ensure call to pods_view returns shortcode generated content, instead of echo'ing. Fixes (#3433). (#4010) [@dom111] +* Fixed: Additional CSS Classes were not saved (#4003) so new Duplicating Pod now gives preference to existing field options values on duplication (#4028). [@pglewis] +* Fixed: duplicate_pod_item now works for WP objects. Fixes (#3238,#4025). (#4070). [@pglewis] +* Fixed: Hidden field did not save Default Values on fields with both Visibility hidden and a Default Value set. Fixes (#3996). (#4061). [@pglewis] +* Fixed: Use register_taxonomy_for_object_type for post types that support post formats. Was not originally being registered for Pods CPT. Fixes (#2165). (#4076,#4084). [@sc0ttkclark] +* Fixed: Help Text for HTML fields wpautop reference. Fixes (#4090,#4091). (#4089). [@JoryHogeveen] +* Fixed: Corrected Pods overriding preview link for post updated messages. Fixes (#4092). (#4093). [@tuanmh] +* Fixed: When using shortcodes/magic tags with PDF attachments, ._src returns an image since WP 4.7. This will now output the URL of the file. You can still get PDF generated images using ._src.image_size or ._img. Fixes (#4040). (#4111). [@JoryHogeveen] +* Fixed: Audio attachments will now work properly with pods_attachment_import. (#4155) [@sc0ttkclark] +* Fixed: Handling of Single & Double Quotes in post_thumbnail interpolation. Fixes (#4166). (#4167). [@quasel] +* Fixed: Adding back_link to wp_die() usage which allows Modal Add/Edit to give you a way to go back in the edit screen. Fixes (#4168). (#4169). [@sc0ttkclark] +* Fixed: Conflict with The Event Calendar issue with Handlebars (as we're using an older implementation). Temporary hack until 2.7 with the correct fix. (#4173). [@sc0ttkclark] +* Fixed: Missing images in unit test (#4177). [@sc0ttkclark] +* Fixed: Invalid AJAX error with frontend forms and Settings Pods; $id will always return for AJAX requests. Fixes (#4181). (#4184). [@JoryHogeveen] +* Fixed: Allow float values for menu positions and the option to remove trailing decimals from number field. Fixes issue where Pods Converted menu positions with decimals to INT on save. Fixes (#2839). (#4192). [@JoryHogeveen] +* Fixed: Composer: composer installers v1.2 to v1.3. (#4239) [@Ramoonus] +* Fixed: Editable Titles in Multiple File Upload fields are 'editable' again (broke in 2.6.8) without breaking bidirectional relationship saving. Fixes (#4112) and resolves (#3477,#3720). (#4264). [@sc0ttkclark] +* Fixed: Spelling error in UI. Fixes (#4266). (#4267). [@danmaby] +* Updated: Brand assets for Pods (icons and banners) for WordPress Plugin Directory. Fixes (#3948). (#4268) [@jimtrue] + += 2.6.8 - January 17th 2017 = +* Added: WP Gallery display options for image fields. Fixes (#3905). (#3910). [@JoryHogeveen] +* Added: Add action after successful AJAX in admin_ajax. This allows other scripts to hook in the ajax handlers from Pods. Fixes (#3839). (#3840). [@JoryHogeveen] +* Added: Keep Plupload instances in `windows.pods_uploader[id]`. This makes it possible to bind event listeners to the file uploader. Fixes (#3763). (#3768). [@thirdender] +* Added: New singular capabilities for Taxonomies for Compatibility with WP 4.7. Fixes (#3896). (#3946). [@JoryHogeveen] +* Added: Enhance Currency Field storage. Fixes Adds new format as arrays for multiple values (label, name, sign) and decimal handling options. Fixes(#1915,#3453). (#3949). [@JoryHogeveen] +* Fixed: Number/Currency format validation error with French formatting. Fixes (#3842). (#3950). [@JoryHogeveen] +* Fixed: Additional save_user/save_post handling problems corrected and addition of Unit Tests. Fixes (#3918,#3801). (#3945). [sc0ttkclark] +* Fixed: Double qtip/tooltip when using single checkboxes (boolean type). Fixes (#3940). (#3943) [@JoryHogeveen] +* Fixed: Undefined Index Notice in (#3936). (#3941). [@sc0ttkclark] +* Fixed: Properly clear cache before running post-save actions in PodsAPI::save_pod_item. Prevents double saves being necessary to use the `pods_api_post_save_pod_item` filters to update WordPress Object fields. Fixes (#3917). (#3938). [@sc0ttkclark] +* Fixed: Revamp pods_error to handle multiple modes, PodsMeta now returns false instead of die/exception. Fixes (#3930). (#3937). [@sc0ttkclark] +* Fixed: Update save_post / save_user handling with better fallbacks when nonce not active. Fixes an issue where the $is_new_item was not set as expected on post saves and user saves. Fixes (#3801,#3918). (#3936). [@sc0ttkclark] +* Fixed: Add `pods_ui_get_find_params` filter for PodsUI to extend default `find()`. Fixes (#3925). (#3926). [@sc0ttkclark] +* Fixed: Compatibility additions for WP 4.7, Taxonomy Class (#3895,#3894) +* Fixed: Proper reset of the local var cache in Pods::$row when using add_to/remove_from/save. Fixes (#3784). (#3923). [@sc0ttkclark] +* Fixed: get_meta() $single usage to ensure it's always a boolean. Fixes (#3742). (#3921). [@sc0ttkclark,@JoryHogeveen] +* Fixed: Multiple Travis and Unit Test fixes and build functions. (#3942,#3913,#3911,#3907,#3903,#3888,#3887,#3886,#3885,#3883,#3882,#3881,#3880,#3869,#3868,#3819,#3770,#3750,#3745,#3743) [@Ramoonus,@sc0ttkclark] +* Fixed: Removing a Bad Init Call generated by a fix to correct plupload file field listings. Fixes (#3900,#3731). (#3901). [@pcfreak30] +* Fixed: Pass audio_args to the Audio Shortcode, src wasn't being passed when multiple audio files were on the same page using the same shortcode. Fixes (#3891). [@jamesgol] +* Fixed: Corrected non-printable character added after $api->cache_flush_pods() to settings-tools.php. Fixes (#3876). [@szepeviktor] +* Fixed: opcache names and add OPcache. Fixes (#3864). (#3875). [@szepeviktor] +* Fixed: Make sure self::$field_data is set in all cases. Corrects issue where relationship to predefined list was not working in AutoComplete/Select2 fields. Fixes (#3862). (#3863). [@jamesgol] +* Fixed: Unchecking Show in Menu in the Admin UI selection for Custom Taxonomies will now properly not show the Taxonomy. `show_in_menu` option for for Taxonomies. Fixes (#3848). (#3852). [@JoryHogeveen] +* Fixed: Make field type labels translatable. Fixes (#3849). (#3850). [@JoryHogeveen] +* Fixed: Store the old field name in meta. Pods already stored the old 'pod' name, but didn't do the same for fields after updating. Added for (#3841). (#3842). [@JoryHogeveen] +* Fixed: Fix error with PODS_LIGHT and components. Fixes (#2301,#3811,#2293). (#3837). [@JoryHogeveen] +* Fixed: Update the attachment parent if updating a post type. Only updates if the parent isn't set but allows file fields/upload fields to now properly show parent post. Fixes (#3808). (#3834). [@JoryHogeveen] +* Fixed: CSS fixes (remove old images + linter), fixing issues with gradient button not in WP Core. Fixes (#3812). (#3833). [@JoryHogeveen] +* Fixed: Improve CSS for Code Field (CodeMirror). Fixes (#3818). (#3832). [@JoryHogeveen] +* Fixed: Set Start of Week Day from General Settings; fixes issue where Calendar of datetime field in admin UI didn't follow the first day of week settings from Setting, General. Fixes (#3826). (#3831). [@JoryHogeveen] +* Fixed: PHP7 Compatibility issues, a few deprecated constructors and deprecated mysql_ with the use of $wpdb. Fixes (#3828). (#3830). [@JoryHogeveen] +* Fixed: Update postmeta cache before get_post_meta calls when bypassing cache, ensuring the meta is "fresh". (#3807). [@sc0ttkclark] +* Fixed: When preloading config after flushing cache, bypass cache. solves the issue when running multisite and youโ€™ve got an object cache drop-in that wonโ€™t flush cache for multisite when wp_cache_flush is called. (#3806). [@sc0ttkclark] +* Fixed: Fix error exporting taxonomy relationship over REST API. Fixes (#3606). (#3794). [@pcfreak30] +* Fixed: Use taxonomy capabilities in custom locations for taxonomy edit pages. Fixes an issue where Taxonomies assigned as Top Level Menu Items are not usable by Editors (only by Administrators). Fixes (#3569). (#3780). [@JoryHogeveen] +* Fixed: Correcting a bug in adding Taxonomy REST support. Fixes (#3777). (#3778). [@pcfreak30] +* Fixed: Clear `$related_item_cache` when saving a relationship. Fixes an issue where the $PodsAPI::save_relationships was not clearing the cache. Fixes (#3775). (#3776). [@pcfreak30] +* Fixed: jQuery fix to change from deprecated .live() to .on(). Fixes (#3771). (#3772). [@mikeschinkel] +* Fixed: Basic included post types from WP-API are no longer having their REST base overridden by Pods. Fixes (#3759). (#3760). [@sc0ttkclark] +* Fixed: Fix SQL for multilingual taxonomies for compatibility with PolyLang. Fixes (#3728). (#3754). [@JoryHogeveen] +* Fixed: Fix plupload file field listings, specifically fixing some issues in the CSS and jQuery. Fixes (#3731). (#3732). [@pcfreak30] +* Fixed: Removed max-length for default field value for Text & WYSIWYG fields. Fixes (#3729). (#3730). [@JoryHogeveen] +* Fixed: Updated URL for translation contributions. Fixes (#3725). (#3726). [@JoryHogeveen] +* Fixed: Validate field option dependencies based on location within tabs. Corrects and issue with compatibility between Pods SEO. Fixes (#3707). (#3723). [@JoryHogeveen] +* Fixed: Properly update bidirectional taggable relations. Corrects the issue where bidirectional relationships were creating new entries from the taggable choice in AutoComplete fields, but not saving the relationship. Fixes (#3477). (#3720). [@caleb] +* Fixed: Allow the entry of negative numbers in Currency fields. Fixes (#3708). (#3709). [@pcfreak30] + += 2.6.7 - August 15th 2016 = +* Fixed: Magic Tag {@permalink} fixes for taxonomy / user / comment detail URL Mapping. Fixes (#3339). [@sc0ttkclark] +* Fixed: Pods Wizard for Forms now properly uses the `[podsform]` shortcode. Fixes (#3251). [@sc0ttkclark] +* Fixed: Issue with pll_get_post returning false instead of null. Fixes (#3596). (#3599) [@JoryHogeveen] +* Fixed: WYSIWYG editor type option is used as dependency by the editor options. Fixes (#3549). (#3610) [@JoryHogeveen] +* Fixed: Do not display metagroup if all fields are set to hidden. Fixes (#1614). (#3615) [@JoryHogeveen] +* Fixed: Allow post_status filter to be set for related post_type objects in the edit field UI (#3626). Fixes (#3594). [@JoryHogeveen] +* Fixed: Refactor object type checking in PodsRESTHandlers::get_handler (#3630). Fixes (#3629). [@pcfreak30] +* Fixed: Added PODS_DIR to directories that are checked by field_loader() (#3644). Fixes (#3643). [@jamesgol] +* Fixed: Improved field alignment on setting pages (#3649). Fixes (#3648). [@JoryHogeveen] +* Fixed: Check for PodsInit in general.php (#3665). Fixes (#3473,#2803,#3353). [@JoryHogeveen] +* Fixed: Taxonomy capabilities + No more hardcoded tax settings (#3678). Fixes (#3676,#3677). [@JoryHogeveen] +* Fixed: Allow field options to be filtered (UI). Also allows for il8n module to improve translation handling. (#3683). Fixes (#3682). [@JoryHogeveen] +* Fixed: WPML Compatibility (#3691). Related to (#142). [@srdjan-jcc] +* Fixed: Pods field() now properly handles user and media when the output type is pod/pods. Original issue resulted in `$object` being empty as `user` and `media` do not have a `pick_val` (#3694). Fixes (#3693). [@pcfreak30] +* Fixed: travis-ci: test with PHP 7.1 (#3702). [@Ramoonus] + += 2.6.6 - June 23rd 2016 = +* Added: Polylang compatibility with latest versions along with fixes to longstanding issues with editing and displaying content, relationships, and taxonomy (#3574). Fixes (#3572, #3506) [@JoryHogeveen] +* Added: REST API v2 Compatibility (#3584). Switches `register_api_field` to `register_rest_field`. Fixes (#3581) [@sc0ttkclark] +* Added: Allow changing the Auto Templates Filter. This adds a new section in the Auto Templates tab that allows overriding the default `the_content` filter (#3542). Fixes (#3540) [@Shelob9] +* Added: Polylang support to pods_v post_id (#3562). Allows Pods templates that are translated to be properly selected. Fixes (#3561,#3537) [@jamesgol] +* Added: Create new 'post_id' method for pods_v (#3537). Provides a method to allow i18n plugins to return a different post id. Related to (#3542,#3526) [@jamesgol] +* Added: Add filter to PodsMeta->groups_get() allowing adjusting the groups via filter (#3548). Related to (#3547) [@jamesgol] +* Added: Use form_counter in field name to be unique and prevent conflicts. (#3535) Fixes (#3533) [@pcfreak30] +* Added: Add user, media and comment support to REST API (#3516). Related to (#3418,#3419) [@pcfreak30] +* Added: Filter the Pods Metas to Display (#3544). Fixes (#3520). [@coding-panda] +* Fixed: REST API cleanup for pick field handling. (#3560) Fixes (#3559) [@sc0ttkclark] +* Fixed: Exclude Unique Post fields from duplication during `$pods->save`. (#3564). Includes `ID`, `post_name`, `post_date`, `post_date_gmt`, `post_modified`, `post_modified_gmt` and `guid`. Fixes (#3563) [@pcfreak30] +* Fixed: Allow midnight (00:00) as valid time (#3555). If "Allow empty value" is unchecked and a value is not passed it will default to the current time, but it will still accept 00:00:00 as a valid value. Related to (#3488) [@jamesgol] +* Fixed: Pass $strict = false to load_pod (#3554). This will keep the "Pod not found" message from being displayed during register of other post types. Related to (#3416) [@jamesgol] +* Fixed: Don't add space to currency names that use HTML encoding (#3553). Fixes British pound currency symbols and others. Resolves (#3498) [@jamesgol] +* Fixed: Removed extra setting showing up in Auto Templates settings for Taxonomies (#3543). Fixes (#3541) [@Shelob9] +* Fixed: Use html_entity_decode to convert separator as it is an html entity. (#3536) Fixes (#3527) [@pcfreak30] +* Fixed: PodsRESTHandlers::write_handler needs to be static (#3511). Fixes (#3510) [@pcfreak30] + += 2.6.5.2 - May 4th 2016 = +* Fixed: Typo in PLL Compatibility check corrected. (#3504) Fixes (#3503). Thank you @JoryHogeveen and @fmommeja for tracking down, fixing and validating this fix. [@JoryHogeveen] + += 2.6.5.1 - May 4th, 2016 = +* Fixed: Additional Field Options tab disappears from field admin view. Fixes (#3501). [@sc0ttkclark] + += 2.6.5 - May 3rd, 2016 = +* Fixed: Renaming of Pods with underscores to hyphenated names that was introduced in 2.6.3. Hyphenated Pods names will remain hyphenated and Underscored Pods names will remain underscored. Fixes (#3499). [@sc0ttkclark] +* Fixed: Support for new Polylang Versions with much kudos to @JoryHogeveen for tackling this (#3491). Fixes (#3490,#3223) [@JoryHogeveen] + += 2.6.4 - April 25th, 2016 = +* Fixed: Modified Run activation/install priority to fire before plugins loaded. Fix for the Clearing Pods Cache automatically after Pods Upgrade (#3487). Fixes (#2558,#3348) [@sc0ttkclark] + += 2.6.3.1 - April 21st, 2016 = +* Fixed: An Git / SVN deploy bug caused some files to not be properly pushed to WordPress.org SVN, this release is just to ensure everyone who may have updated to 2.6.3 during the period which we were fixing it will be able to still get the proper file updates + += 2.6.3 - April 21st, 2016 = +* Fixed: Fix forcing underscores when loading Edit Pod Form (#3483). Fixes (#3095) [@sc0ttkclark] Kudos to @lkraav for helping us pin this particular issue down and bring it to resolution. +* Fixed: Clearing Pods Cache automatically after Pods Upgrade "Salt n'Pepa"'ing the cache keys (#3401). Fixes (#2558,#3348) [@sc0ttkclark] + += 2.6.2 - March 24th, 2016 = +* Added: Support for object fields when using Pods::field() with a specific $field and $option. This was also used to correct a problem with "fetching" Custom Taxonomy's Term List when using Pods Feeds in Pods Gravity Forms Plugin. (#3437) [@sc0ttkclark] +* Fixed: Correcting CSS used for Dashicon to remove conflict with icon usage in Divi. (#3404,#3406) [@jimtrue] +* Fixed: Currency/Number Validation used to correct issue with Currency Usage in the Pods Gravity Forms plugin (#3436) [@sc0ttkclark] + += 2.6.1 - February 15th, 2016 = +* Added: Additional Label support for Post Type / Taxonomy register functions (#3275) [@pcfreak30] +* Added: Add use_current option for Widget Single (#3393,#3394) [@sc0ttkclark] +* Added: Add option to website fields to open links in new window (#3388,#3387) [@sc0ttkclark] +* Fixed: 'type' not 'object_type' (#3378,#3351) [@pglewis] +* Fixed: Update Select2 to v3.2.0, should resolve #3344 (#3377,#344) [@pglewis] +* Fixed: Change Markup to Support CSS in WP 4.4 (Thanks to @nicdford we missed mentioning in 2.6 Change log) (#3277,#3270,#3279) +* Fixed: Non-Zero Array Keys here in PHP7 cause odd behaviour so just strip the keys (#3294,#3299) [@pglewis] +* Fixed: Corrected Dashicons Link in the Menu Options panel of Edit Pods (#3287,#3271) [@benbrandt] +* Fixed: Update Version number on 2.x (#3282,#3281) [@pglewis] +* Fixed: Typo's Rest into REST (#3303) [@Ramoonus] +* Fixed: Disable xdebug on Travis (#3284,#3283) [@pglewis] +* Fixed: Remove dockunit leftovers (#3307) [@Ramoonus] +* Fixed: Do not use Hashtag as name (#3316) [@Ramoonus] +* Fixed: Over-escaping strikes again (file upload, restrict file types with more than one mime type) (#3083,#3328) [@pglewis] +* Fixed: Refresh #3388 with 2.x (#3388,#3389) [@sc0ttkclark] +* Fixed: Replace usage of get_currentuserinfo with wp_get_current_user (preparation for WP 4.5) (#3399,#3398) [@sc0ttkclark] +* Fixed: Taxonomy custom meta fields returning false from REST API (#3365,#3369) [@anandamd] + += 2.6 - December 9th, 2015 = +* Added: Support for Term Meta in WP 4.4 - Now create meta-based taxonomies and Pods just magically works! (#3169,#3163) [@sc0ttkclark] +* Added: Add REST API Support to Post Types, Taxonomies, Users. Read the update in https://github.com/pods-framework/pods/pull/3184 for step by step details. (#3184,#3182) [@Shelob9] +* Added: Added compatibility with the latest Polylang version, using $polylang-model to get the current language and version. (#3223) [@JoryHogeveen] +* Added: Inline hook docs in PodsAdmin class (#3180,#3179) [@Shelob9] +* Added: Fixes to REST API Admin Tab (thanks @nicdford) to display always but also explain why it won't work if not able to work. (#3246,#3259) [@Shelob9,@nicdford] +* Added: PHPunit support for clover-coverage FN (#3176) [@Ramoonus] +* Added: Travis do not allow PHP7 to fail (#3235) [@Ramoonus] +* Added: Tests for Mariadb and mysql 5.6+7 with PHP 5.6 Travis (#3212,#3208) [@Ramoonus] +* Added: Nonce and text translation to delete link in pod edit sidebar. Fixes issue where attempted to delete pod from edit page results in fatal error. (#3203,#3194) [@cpruitt] +* Added: Use phpcs standard wordpress in scrutinizer (#3166) [@Ramoonus] +* Added: phpunit support for clover-coverage (#3161) [@Ramoonus] +* Added: Travis allow PHP7 to fail (#3153) [@Ramoonus] +* Added: Travis include WordPress 4.3 in test matrix (#3152) [@Ramoonus] +* Added: Travis cache composer (#3151) [@Ramoonus] +* Added: Grunt ignore dockunit.json (#3150) [@Ramoonus] +* Updated: Dockunit - replace PHP 7 rc1 with rc4 (#3201) [@Ramoonus] +* Updated: Improve Contributing guidelines correcting wrong pull location and fixing correct release branch. (#3149,#3147) [@quasel] +* Fixed: Scheduled post preview message/URL. When a post was scheduled, the status message displayed at the top of the edit post page was malformed where the string placeholders were numbered. (#3234) [@sparkdevelopment] +* Fixed: Merged #3205 to fix install-wp-tests.sh (#3211,#3205) [@Ramoonus] +* Fixed: Add pods_auto_template_name filter, by context to change auto template (#3199,#3200,#3198) [@Shelob9] +* Fixed: Revert scrutinizer less is more (#3172,#3170) [@sc0ttkclark,@Ramoonus] +* Fixed: Remove limit of 5 in get_template_titles Auto Template (#3157,#3160) [@jimtrue] +* Fixed: Related_act.permalink calls to fix permalink/slug traversal in ACTs and related taxonomies (#3156,#3155,#2779) [@sc0ttkclark] +* Fixed: Added option to deselect Auto Template for Archive views. There needed an 'empty' selection to correct issue where Template error wouldn't go away. (#3148,#3146,#3142,#3247) [@Sgillessen] +* Fixed: Added Dockunit Badge (#3145) [@tlovett1] +* Removed: Double exclude path in scrutinizer (#3228) [@Ramoonus] +* Removed: Readme removed code coverage badge (#3220) [@Ramoonus] +* Removed: Dump composer in Scrutinizer (#3204,#3167) [@Ramoonus] +* Removed: Composer remove coveralls. Was not being used and needs phpunit support. Could also be replaced by php codesniffer or scrutinizer. (#3174) [@Ramoonus] + += 2.5.5 - September 16th, 2015 = +* Added: Unit testing for PHPUnit 4.8 support. (#3090, #3069) Kudos to @Ramoonus +* Fixed: Drop External code coverage - timeout in Scrutinizer. (#3091) Kudos to @Ramoonus +* Fixed: Changed Content property to fix spacing issues with AutoComplete Field where the formatted selection fields have awkward spacing between the selection box and the selection list. (#3098, #3097, #3099) Kudos to @nicdford +* Fixed: Issue where [each] tag traversal did not work with Taxonomy in Pods Templates. Related notes regarding pod->object_fields for taxonomy added for 3.0 notes. (#3106, #3018, #3107, #3111) Major thanks to @pglewis +* Fixed: `permalink` field traversal has only been working for post types, not for related taxonomies. (#2779, #3114, #3115) Kudos to @pglewis +* Added: Support for CPT UI 1.0.x in CPT UI migration component by adding support for multiple possible option names for post types and taxonomies. (#3112, #3109, #3113, #3116, #3117) Kudos to @pglewis +* Added: Merged Auto Template into Pods Template Component. (#3125, #3105) Major thanks to @Shelob9 both for the original plugin and for incorporating this into Pods Templates. +* Added: License.txt changes to sync with GPL v2 (#3130, #3133) Kudos to @Ramoonus + += 2.5.4 - August 10th, 2015 = +* Added: Support for Compare ALL with meta_query syntax. Kudos to @pcfreak30. (#3037, #3038) +* Added: Query_field tests (meta_query syntax for where) (#3033, #3032, #1662, #2689) +* Added: Support for autoCAST()ing meta_value orderby for dates and numbers (#3043, #3041, #3058) +* Added: Feature/pods page export support. Added 'pods_page_exists' filter to allow Pods Page content to be supplied from another source (eg exported files) (#3049, #3054) +* Added: Copy of EDDs scrutinizer (#2917, #3072) +* Removed: PHP4-style constructor removed in Pods Widgets (#3055, #3056, #3057) +* Fixed: PHP Doc Improvement (#3039, #3040) +* Fixed: Style escaping which created a quote encoding bug in PodsMeta.php. (#3053, #3032) + += 2.5.3 - June 11th, 2015 = +* Added: Support for Term Splitting in WP 4.2 (#2856, #2660) +* Added: Support for Pod and Field names with dashes and prefixes with underscores (#3012, #3021, #3022) +* Added: Add git workflow and a link to it from contributing.md (#2490, #2496) +* Added: Unit tests for PodsField_Boolean (#2473, #2474) +* Added: Unit test to create pod factory object and moves fixture set up from traversal tests to test case. (#2445) +* Added: Additional Pods_Field_Text tests added to incorrect text dependencies. (#2388) +* Fixed: Fixes for Drag and Drop Reorder Action not working in ACT's (#3015, #3016) +* Fixed: Fix for pagination handling in shortcodes. Shortcodes currently use 'pagination' for two contexts (display and data) but if page or offset is supplied, it's only meant for one context (display). (#2807, #3004) +* Fixed: Update post field in pod instance before saving, related to MetaData (post field) not flushing after saving (#3000, #3002, #3003) +* Fixed: Corrects Delete not working for Edit Items (#2752, #2991) +* Fixed: Corrects ACT - Admin Order DESC not working && SQL error if order by an relationship field (#2843, #2989) +* Fixed: Composer: updated for phpunit 4.7 (#2987, #2988, #2783) +* Fixed: ui/js/jquery.pods.js fixes (#2971, #2972) +* Fixed: Remove `@internal` phpDoc for pods_query() (#2970, #2969, #2975) +* Fixed: Fix for ACT editor not staying on current item after saving (#2968, #2942, #2974) +* Fixed: Fix for over escaping icon URL in file fields previewer (#2957, #2956, #2955, #2978) +* Fixed: Fix for symlinked pods in local deve environment (#2946, #2945, #2949) +* Fixed: Removed Vestiges of Old Updater (#2940, #2983) +* Fixed: Clarify help text as to what does and doesn't get deleted on reset (#2792, #2778) +* Fixed: Missing $ in PodsInit line 494 (#2475, #2476) +* Fixed: Trim off whitespace when saving custom fields; code in classes/fields/pick.php already does this. (#2386, #2343) +* Fixed: Updated Taxonomy to get called after cache is flushed (#2264, #2375, #2382) +* Fixed: Cleared old unit tests from EDD (#2380) +* Fixed: Allow fields to be sorted by orderby; Two separate but connected issues. First if orderby is passed then the $data array is never populated. Then looping through $ids will always give it results sorted by priority in the relationships field (data returned by lookup_related_items) (#2350, #2277) + += 2.5.2 - May 14th, 2015 = +* Fixed: Issues with default values for number and other types of fields. +* Fixed: Issue where Pods update was causing WP-API endpoints to 404. Rewirte rules now flush on wp_loaded. +* Fixed: Issue preventing proper display of fields in a related CPT via Pods::field() +* Fixed: Issue preventing codemirror from being enqueued in Pods templates and therefore breaking Pods tempaltes editor in certain configurations. +* Added: Added caching info to debug info. +* Fixed: Bug that was causing Pods to overwrite admin menus. +* Fixed: Issue preventing ongoing compatibility with Admin Columns. +* Improved: Style of components filter bar. +* Improved: Proper sanitization/ escaping of URLs. +* Fixed: Shortcode button was outputted in post editor when shortcodes were disabled. This will no longer happen. +* Improved: Translation strings in ui/admin/help +* Improved: Gradients in Pods wizard. +* Fixed: Issue preventing associated taxonomies to be fetched via Pods::field() and therefore magic tags. +* Improved: Icon font used for Pods admin icon. +* Improved: Elaborated on what data is and isn't deleted when Pods data is reset. +* Added: Compatibility with Github updater plugin. +* Updated: New youtube video in readme. +* Added: Support for term splitting in WordPress 4.2. +* Removed: Extra meta data with _pods_ prefix +* Fixed: Issue where multiple post type Pods objects called in same session were treated as the same in cache. +* Fixed: Double slashing in PodsView class. +* Improved: URL escaping in PodsUI + += 2.5.1.2 - March 16th, 2015 = +* Security Update: We recommend all Pods 2.x installations be updated to the latest version of Pods +* or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/ +* Fixed: Pods UI orderby now strictly enforces Database column format + += 2.5.1.1 - January 22nd, 2015 = +* Fixed missing files for font icon. + += 2.5.1 - January 22nd, 2015 = +* Fixed: Issue preventing fields from being sorted by weight or by orderby, that was affecting image multi-select image field ordering. +* Fixed: Missing gradients in UI. +* Fixed: Use of anonymous function in PodsMeta.php causing issues with old versions of PHP. +* Fixed: Issue where hidden fields were being shown for admin users, when they should have been hidden. +* Fixed: Issue where PodsAPI::delete_field() was unable to delete fields in certain situations. +* Fixed: Issue with pods_version_check() usage that was causing a deprecated core function to run, when it was supposed to prevent it from running. +* Fixed: Issue with pods_error() that was causing it to display AJAX errors improperly. +* Fixed: Issue preventing public, publicly queryable & rewrite with front from saving choices in advanced options. +* Fixed: Magic tag for custom taxonomy, which was showing no content in Pods Templates in 2.5. +* Fixed: If block in Frontier. +* Fixed: Issue with custom taxonomy joins preventing "custom_tax.d.custom_field" type where clauses from working. + += 2.5 - December 30th, 2014 = +* Major performance enhancements can now make things run up to 400% faster (props to @jamesgol!) +* More unit tests -- now 1,858 tests with a total of 13,420 assertions covering all content type, storage type, and field variations (props to @sc0ttkclark, @clubduece, and @mordauk! it was a group effort) +* Added Travis-CI / Scrutinizer-CI for all pushes and pull requests to unit test and check for other issues +* Upgraded Code Mirror library +* Upgraded qTip library +* Updated translations -- Add your translations at http://wp-translate.org/projects/pods +* Fixed: Added nonces for multiple actions in the admin area to avoid accidental / unwanted results +* Fixed: Issue causing issues in admin with CodePress admin columns. +* Fixed: Issue preventing Pods Template editor from working with certain xcache configurations. +* Added: 'join' to the accepted tags for Pods Shortcode. +* Added: 'pods_data_pre_select_params' filter. +* Improve: PodsAPI::export_pod_item_lvl(), adding item ID to all steps. +* Simplify logic when creating new PodsAPI singleton internally. +* Switch from Pods::do_hook() to apply_filters() or do_action() for 'pods_pods_fields', 'pods_pods_field_related_output_type', 'pods_pods_field_', 'pods_pods_field', 'pods_pods_fetch', 'pods_pods_reset', 'pods_pods_total_found', 'pods_pods_filters' +* Fixed: YARRP support. +* Ensure that pods_v_sanitized() passes the $strict argument to pods_v(). +* Prevent use of date_i18n() in PodsData when not needed. +* Fixed: Issue where updating relationship to users in pods editor threw an erroneous error. +* Fixed: Hiding of text in title-prompt-text +* Updated design of new Pod wizard to match MP6 (props to @nikv!) +* Fixed: Inline docs for pods_api_get_table_info_default_post_status filter +* Fixed: Issue where Pods::field() showed cached data after saving via Pods::save(), without re-building the Pods Object. +* Allowed PodsField_Pick to save names +* Switched pods_v() to use switch/case instead of if/else where possible. +* Prevented Pods::id() from calling the field method unless it has to. +* In PodsData::select(), allow proper use of cache expiration time. +* Fixed: Issue in currency fields to ensure proper handling of decimals. +* Added a "pre_select" hook in PodsData. +* Improved traversal regex in Pods::find() to have better handling for variation of backticks. +* Removed usages of the deprecated WordPress function like_escape(). +* Remove redundant file/class checks for Pods Templates. +* Implement glotpress-grunt for manging translations. +* Fixed: Issue where get_current_screen(), in some contexts was used as an object, when it was null. +* Improved: Styling of shortcode insert button. +* Prevented string replace and trim from running on a form field default when default value is not a string +* Fixed: Issue preventing color pickers from working in front-end form. +* Switched from using $wpdb->prefix to $wpdb->base_prefix in pick field class. +* Fixed: Default avatars on the Discussion settings page replaced by user's custom avatar. +* When saving custom fields, whitespace is now trimmed. +* Better validation of custom fields when saving custom post types. +* Improved: Handling of required fields. +* Changed the default of $display_errors in Pods class to true. +* Allowed save_post_meta to delete single meta elements instead of update. +* Fixed: An issue preventing fields from being sorted by orderby. +* Fixed: Issue where fields, storing one value, returned arrays, instead of strings. +* Allowed extending the link category taxonomy, if in use. +* Added join as an acceptable tag for Pods shortcodes. +* Fixed pods_error(): reversed logic that was emitting an error instead of throwing an exception when $display_errors is false +* Fixed issue where user_url was created as a required field when extending users. +* Add ability to use pods_group_add() in the ACT editor. +* Security Update Reminder: As of Pods 2.4.2, we recommend all Pods 2.x installations be updated to the latest version, or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/ +* If you need assistance in upgrading your Pods 2.x site to the latest version of Pods, please don't hesitate to contact us at https://pods.io/help/ + += 2.4.3 - June 23rd, 2014 = +* Fixed: Pods Templates component now has better handling of the new shortcodes +* Fixed: PodsUI data issue with Custom DB Table support +* Fixed: Readonly fields and noncing now works properly, Pods 2.4.2 caused all forms with readonly fields to fail submission +* Hardened: Further security hardening of the `[pods]` shortcode, added PODS_DISABLE_SHORTCODE constant to allow sites to disable the Pods shortcode altogether + += 2.4.2 - June 22nd, 2014 = +* Security Update: We recommend all Pods 2.x installations be updated to the latest version of Pods to fix a noncing issue with form saving, or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/ + += 2.4.1 - June 19th, 2014 = +* Fixed: Display of of hidden fields in Pods Forms +* Fixed: Reordering fields in PodsUI +* Fixed: PodsUI Admin Icon Display +* Add new filter: โ€˜pods_pod_form_success_messageโ€™ for changing the message when Pods Forms are successfully submitted. +* Fixed: Issues in Packages component when importing existing fields. +* Added new filter: โ€˜pods_view_alt_viewโ€™ for overriding normal Pods Views to be loaded in via AJAX inline from Pods AJAX Views plugin. +* Fixed: PHP error in Pods Template reference. +* New Constant: PODS_PRELOAD_CONFIG_AFTER_FLUSH check to allow for preloading $api->load_pods() after a Pods Cache flush. +* Fixed: Issue with tabled-based SQL delete actions. +* Fixed: PodsUI SQL table-based lookups +* Added: New Hooks In ui/admin/form, which generates ACT editor, for adding additional forms or other content to editor. +* Added: Inline docs for 'pods_meta_default_box_title' filter and normalized args across each usage. +* Added: Item ID to pods_api::export() item array. +* Fixed: Update from GitHub functionality. +* Fixed: Issue where extended custom post types had diffrent names then original post type due to use of dashes in names. +* Improved UX for select2 field adding new items. +* Fixed: $params with unslashed data in Pods_Admin::admin_ajax() +* Fixed: Unwarranted base_dir warnings. +* Fixed: Pagination/search boolean checks. +* Fixed: Issue when mbstring module is not active. +* Fixed: Issue with markdown module header causing activation errors. +* New Filter: 'pods_admin_components_menu' to add/edit components submenu items. +* Added: Ability to use pods() without any parameters. Will pull the pod object based off of the current WP_Query queried object / object id + += 2.4 - April 16th, 2014 = +* After a long road, we've got a new minor release out that fixes a large number of outstanding bugs and adds a few improvements that were within reach right away. +* In Pods 3.0 we're focusing on finishing some overarching performance improvements that are necessary to support large installs with the new Loop and Repeatable fields features. +* Added: Tagging feature for Relationship fields with Autocomplete (Select2) which lets you add new items on-demand when saving +* Added: PodsAPI::get_changed_fields() that can be used when in a pre-save hook to return array of changed values or used in PodsAPI::save_pods_item() to track changes to fields +* Added: _pods_location to $params for PodsAPI::save_pod_item which will contain the URL of the form it was submitted from +* Added: New Pods Template editor revamp to include auto-complete for magic tags and field reference, which can be further extended by installing Pods Frontier +* Added: An optional download link to File Upload field type +* Added: Additional Currency formats to Currency field type +* Added: created/modified functionality (see Advanced Content Types) to other Pod types, as long as they are date/datetime fields +* Added: Support for JetPack Publicize and Markdown modules +* Added: Max character length option for paragraph fields +* Added: Actions before and after Pods Form all and individual form fields are outputted +* Added: New constant PODS_ALLOW_FULL_META for for enabling/disabling get_post_meta( $id ) interaction with Pods (on by default) +* Added: New constant PODS_DISABLE_SHORTCODE_SQL to disable SQL-related parameters in shortcode +* Added: 'pods_admin_media_button' filter to disable the Pods shortcode button in post editor +* Added: 'pods_api_save_pod_item_track_changed_fields_{POD_NAME}' filter for tracking changes to fields +* Added: 'pods_pick_ignore_internal' filter to enable/disable Relationships with core Pods types (_pods_pod, etc) +* Added: 'pods_image_default' filter to allow for placekitten.com or other image placeholder scripts for testing +* Added: Improved Pods Template code sanitization +* Added: Better names for many fields in Pods Editor +* Added: New and improved help bubbles in Pods Editor +* Added: Instructions about using Pods Templates in Pods Widgets +* Added: New descriptions for Pods Pages and Pods Advanced Content Types component descriptions +* Added: Support links in Pods Admin -> Help +* Added: Currently active theme to Pods Debug info list +* Added: Inline docs for 'pods_api_get_table_info_default_post_status' filter +* Added: Inline docs for 'pods_admin_menu' filter +* Added: Inline docs for 'pods_admin_setup_edit_options' (and related) filters +* Added: Inline docs for 'pods_admin_setup_edit_tabs' (and related) filters +* Fixed: Issues with user tables in multisite +* Fixed: Issue with PodsForm::default_value +* Fixed: With Pods UI. Keep view when generating pagination links +* Fixed: Bug with custom extensions for allowed file types in upload fields +* Fixed: Compatibility problem with changes to plupload in WordPress 3.9 that prevented upload pop-up from loading +* Fixed: Array to string conversion error for CSS fields in Pods UI +* Fixed: Magic tags for taxonomies in Pods Templates +* Fixed: Fixed jQuery scope in Pods Form inline JavaScript +* Fixed: Added 'output' to reserved content types names and reserved query vars +* Fixed: Issue where required currency and number fields could be saved at default value +* Fixed: Undefined method error in WP 3.4 due to use of WP_User::to_array() which was added in WP 3.5 +* Fixed: Issue with ability to use filters on reorder page with Pods UI +* Fixed: Pre-save enforcing of max length for meta-based values +* Fixed: Extra spaces in custom defined list labels +* Fixed: Pagination default value for Pods shortcode +* Fixed: PodsForm::submit_button() method that had been lost from previous versions +* Fixed: Usage of pods_v in currency.php for optimzation purposes +* Fixed: Correct parent_file to highlight the correct top level menu +* Fixed: Improper wording for text at top of settings page field diff --git a/classes/Pods.php b/classes/Pods.php index 383805191c..1da50ac24d 100644 --- a/classes/Pods.php +++ b/classes/Pods.php @@ -1,9 +1,28 @@ api = pods_api( $pod ); - $this->api->display_errors =& $this->display_errors; - - $this->data = pods_data( $this->api, $id, false ); - PodsData::$display_errors =& $this->display_errors; - - // Set up page variable. - if ( pods_strict( false ) ) { - $this->page = 1; - $this->pagination = false; - $this->search = false; - } else { - // Get the page variable. - $this->page = pods_v( $this->page_var, 'get', 1, true ); + $maybe_id = null; - if ( ! empty( $this->page ) ) { - $this->page = max( 1, pods_absint( $this->page ) ); - } + if ( ! is_array( $id ) && ! is_object( $id ) ) { + $maybe_id = $id; } - // Set default pagination handling to on/off. - if ( defined( 'PODS_GLOBAL_POD_PAGINATION' ) ) { - if ( ! PODS_GLOBAL_POD_PAGINATION ) { - $this->page = 1; - $this->pagination = false; - } else { - $this->pagination = true; - } - } + $this->data = pods_data( $pod, $maybe_id, false ); - // Set default search to on/off. - if ( defined( 'PODS_GLOBAL_POD_SEARCH' ) ) { - if ( PODS_GLOBAL_POD_SEARCH ) { - $this->search = true; - } else { - $this->search = false; - } + PodsData::$display_errors =& $this->display_errors; + + if ( ! $pod ) { + return; } - // Set default search mode. - $allowed_search_modes = array( 'int', 'text', 'text_like' ); - - if ( defined( 'PODS_GLOBAL_POD_SEARCH_MODE' ) && in_array( PODS_GLOBAL_POD_SEARCH_MODE, $allowed_search_modes, true ) ) { - $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE; - } - - // Sync Settings. - $this->data->page =& $this->page; - $this->data->limit =& $this->limit; - $this->data->pagination =& $this->pagination; - $this->data->search =& $this->search; - $this->data->search_mode =& $this->search_mode; - - // Sync Pod Data. - $this->api->pod_data =& $this->data->pod_data; - $this->pod_data =& $this->api->pod_data; - $this->api->pod_id =& $this->data->pod_id; - $this->pod_id =& $this->api->pod_id; - $this->datatype_id =& $this->pod_id; - $this->api->pod =& $this->data->pod; - $this->pod =& $this->api->pod; - $this->datatype =& $this->pod; - $this->api->fields =& $this->data->fields; - $this->fields =& $this->api->fields; - $this->detail_page =& $this->data->detail_page; - $this->id =& $this->data->id; - $this->row =& $this->data->row; - $this->rows =& $this->data->data; - $this->row_number =& $this->data->row_number; - $this->sql =& $this->data->sql; + $this->pod_data =& $this->data->pod_data; if ( is_array( $id ) || is_object( $id ) ) { $this->find( $id ); @@ -398,13 +189,12 @@ public function __construct( $pod = null, $id = null ) { * @since 2.0.0 */ public function valid() { - - if ( empty( $this->pod_id ) ) { + if ( empty( $this->pod_data ) ) { return false; } if ( $this->iterator ) { - return isset( $this->rows[ $this->row_number ] ); + return isset( $this->data->rows[ $this->data->row_number ] ); } return true; @@ -420,7 +210,6 @@ public function valid() { * @link http://www.php.net/manual/en/class.iterator.php */ public function is_iterator() { - return $this->iterator; } @@ -451,7 +240,7 @@ public function rewind() { if ( ! $this->iterator ) { $this->iterator = true; - $this->row_number = 0; + $this->data->row_number = 0; } } @@ -484,7 +273,7 @@ public function current() { */ public function key() { - return $this->row_number; + return $this->data->row_number; } /** @@ -498,7 +287,7 @@ public function key() { */ public function next() { - $this->row_number ++; + $this->data->row_number ++; } /** @@ -510,7 +299,7 @@ public function next() { */ public function exists() { - if ( empty( $this->row ) ) { + if ( empty( $this->data->row ) ) { return false; } @@ -526,17 +315,17 @@ public function exists() { * @return array|bool An array of all rows returned from a find() call, or false if no items returned * * @since 2.0.0 - * @link https://pods.io/docs/data/ + * @link https://docs.pods.io/code/pods/data/ */ public function data() { do_action( 'pods_pods_data', $this ); - if ( empty( $this->rows ) ) { + if ( empty( $this->data->rows ) ) { return false; } - return (array) $this->rows; + return (array) $this->data->rows; } /** @@ -551,8 +340,9 @@ public function data() { * @since 2.3.10 */ public function input( $field, $input_name = null, $value = '__null' ) { + $is_field_object = $field instanceof Field; - if ( is_array( $field ) ) { + if ( is_array( $field ) || $is_field_object ) { // Field data override. $field_data = $field; @@ -589,47 +379,35 @@ public function input( $field, $input_name = null, $value = '__null' ) { * @param null $field Field name. * @param null $option Option name. * - * @return bool|mixed + * @return array|\Pods\Whatsit\Field|mixed|null * * @since 2.0.0 */ - public function fields( $field = null, $option = null ) { + public function fields( $field_name = null, $option = null ) { $field_data = null; - if ( empty( $this->fields ) ) { - // No fields found. - $field_data = array(); - } elseif ( empty( $field ) ) { + if ( empty( $this->pod_data ) ) { + return null; + } + + if ( empty( $field_name ) ) { // Return all fields. - $field_data = (array) $this->fields; - } elseif ( ! isset( $this->fields[ $field ] ) && ! isset( $this->pod_data['object_fields'][ $field ] ) ) { - // Field not found. - $field_data = array(); - } elseif ( empty( $option ) ) { - // Return all field data. - if ( isset( $this->fields[ $field ] ) ) { - $field_data = $this->fields[ $field ]; - } elseif ( isset( $this->pod_data['object_fields'] ) ) { - $field_data = $this->pod_data['object_fields'][ $field ]; - } + $field_data = pods_config_get_all_fields( $this->pod_data ); } else { - $options = array(); + $tableless_field_types = PodsForm::tableless_field_types(); - // Merge options. - if ( isset( $this->fields[ $field ] ) ) { - $options = array_merge( $this->fields[ $field ], $this->fields[ $field ]['options'] ); - } elseif ( isset( $this->pod_data['object_fields'] ) ) { - $options = array_merge( $this->pod_data['object_fields'][ $field ], $this->pod_data['object_fields'][ $field ]['options'] ); - } + $field = pods_config_get_field_from_all_fields( $field_name, $this->pod_data ); - if ( 'data' === $option && in_array( pods_v( 'type', $options ), PodsForm::tableless_field_types(), true ) ) { + if ( empty( $field ) || empty( $option ) ) { + $field_data = $field; + } elseif ( 'data' === $option && in_array( $field['type'], $tableless_field_types, true ) ) { // Get a list of available items from a relationship field. - $field_data = PodsForm::field_method( 'pick', 'get_field_data', $options ); - } elseif ( isset( $options[ $option ] ) ) { + $field_data = PodsForm::field_method( 'pick', 'get_field_data', $field ); + } elseif ( isset( $field[ $option ] ) ) { // Return option. - $field_data = $options[ $option ]; - } + $field_data = $field[ $option ]; + }//end if }//end if /** @@ -637,12 +415,13 @@ public function fields( $field = null, $option = null ) { * * @since unknown * - * @param array $field_data The data for the field. - * @param string|null $field The specific field that data is being return for, if set when method is called or null. - * @param string|null $option Value of option param when method was called. Can be used to get a list of available items from a relationship field. - * @param Pods|object $this The current Pods class instance. + * @param array|\Pods\Whatsit\Field|mixed $field_data The data to be returned for the field / option. + * @param array|\Pods\Whatsit\Field $field The field information. + * @param string|null $field_name The specific field that data is being return for, if set when method is called or null. + * @param string|null $option Value of option param when method was called. Can be used to get a list of available items from a relationship field. + * @param Pods|object $this The current Pods class instance. */ - return apply_filters( 'pods_pods_fields', $field_data, $field, $option, $this ); + return apply_filters( 'pods_pods_fields', $field_data, $field_name, $option, $this ); } @@ -657,11 +436,11 @@ public function row() { do_action( 'pods_pods_row', $this ); - if ( ! is_array( $this->row ) ) { + if ( ! is_array( $this->data->row ) ) { return false; } - return (array) $this->row; + return (array) $this->data->row; } /** @@ -675,7 +454,7 @@ public function row() { * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned * for tableless fields * @since 2.0.0 - * @link https://pods.io/docs/display/ + * @link https://docs.pods.io/code/pods/display/ */ public function display( $name, $single = null ) { @@ -703,11 +482,7 @@ public function display( $name, $single = null ) { $value = $this->field( $params ); if ( is_array( $value ) ) { - $fields = $this->fields; - - if ( isset( $this->pod_data['object_fields'] ) ) { - $fields = array_merge( $fields, $this->pod_data['object_fields'] ); - } + $fields = pods_config_get_all_fields( $this->pod_data ); $serial_params = array( 'field' => $params->name, @@ -735,7 +510,7 @@ public function display( $name, $single = null ) { * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned * for tableless fields * @since 2.0.0 - * @link https://pods.io/docs/display/ + * @link https://docs.pods.io/code/pods/display/ */ public function raw( $name, $single = null ) { @@ -776,26 +551,26 @@ public function raw( $name, $single = null ) { * @return mixed|null Value returned depends on the field type, null if the field doesn't exist, false if no value * returned for tableless fields. * @since 2.0.0 - * @link https://pods.io/docs/field/ + * @link https://docs.pods.io/code/pods/field/ */ public function field( $name, $single = null, $raw = false ) { - - $defaults = array( - 'name' => $name, - 'orderby' => null, - 'single' => $single, - 'params' => null, - 'in_form' => false, - 'raw' => $raw, - 'raw_display' => false, - 'display' => false, - 'get_meta' => false, - 'output' => null, - 'deprecated' => false, - 'keyed' => false, + $defaults = [ + 'name' => $name, + 'orderby' => null, + 'single' => $single, + 'params' => null, + 'in_form' => false, + 'raw' => $raw, + 'raw_display' => false, + 'display' => false, + 'display_process_individually' => false, + 'get_meta' => false, + 'output' => null, + 'deprecated' => false, + 'keyed' => false, // extra data to send to field handlers. - 'args' => array(), - ); + 'args' => [], + ]; if ( is_object( $name ) ) { $name = get_object_vars( $name ); @@ -836,7 +611,7 @@ public function field( $name, $single = null, $raw = false ) { * @param array $params Params array passed to field(). * @param Pods $this Current Pods object. */ - $params->output = apply_filters( 'pods_pods_field_related_output_type', 'arrays', $this->row, $params, $this ); + $params->output = apply_filters( 'pods_pods_field_related_output_type', 'arrays', $this->data->row, $params, $this ); } if ( in_array( $params->output, array( 'id', 'name', 'object', 'array', 'pod' ), true ) ) { @@ -845,7 +620,7 @@ public function field( $name, $single = null, $raw = false ) { // Support old $orderby variable. if ( null !== $params->single && is_string( $params->single ) && empty( $params->orderby ) ) { - if ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) { + if ( ! class_exists( 'Deprecated_Pod' ) || Deprecated_Pod::$deprecated_notice ) { pods_deprecated( 'Pods::field', '2.0', 'Use $params[ \'orderby\' ] instead' ); } @@ -879,8 +654,8 @@ public function field( $name, $single = null, $raw = false ) { } if ( $this->data->field_id === $params->name ) { - if ( isset( $this->row[ $params->name ] ) ) { - return $this->row[ $params->name ]; + if ( isset( $this->data->row[ $params->name ] ) ) { + return $this->data->row[ $params->name ]; // @codingStandardsIgnoreLine. } elseif ( null !== $value ) { return $value; @@ -912,7 +687,17 @@ public function field( $name, $single = null, $raw = false ) { /** @var string $pod_type The pod object type. */ $pod_type = pods_v( 'type', $this->pod_data, '' ); - $is_wp_object = in_array( $pod_type, $wp_object_types, true ); + $use_meta_fallback = in_array( $pod_type, $wp_object_types, true ); + + /** + * Allow hooking in to support getting meta using the meta fallback. + * + * @since 2.8.0 + * + * @param bool $use_meta_fallback Whether to support getting meta using the meta fallback. + * @param string $object_type The object type. + */ + $use_meta_fallback = apply_filters( 'pods_field_wp_object_use_meta_fallback', $use_meta_fallback, $pod_type ); if ( in_array( $params->name, $permalink_fields, true ) ) { if ( 0 < strlen( $this->detail_page ) && false === strpos( $params->name, 'permalink' ) ) { @@ -961,46 +746,34 @@ public function field( $name, $single = null, $raw = false ) { $first_field = $traverse_fields[0]; $last_field_data = null; - if ( isset( $this->fields[ $params->name ] ) ) { + // Get the first field name data. + $field_data = $this->fields( $first_field ); + + // Ensure the field name is using the correct name and not the alias. + if ( $field_data ) { + $first_field = $field_data['name']; + + if ( ! $is_traversal ) { + $params->name = $first_field; + } + } + + if ( ! $field_data && ! $is_traversal ) { // Get the full field name data. - $field_data = $this->fields[ $params->name ]; - $field_source = 'field'; + $field_data = $this->fields( $params->name ); + } + + if ( $field_data instanceof \Pods\Whatsit\Object_Field ) { + $field_source = 'object_field'; $is_field_set = true; - } elseif ( isset( $this->fields[ $first_field ] ) ) { - // Get the first field name data. - $field_data = $this->fields[ $first_field ]; + } elseif ( $field_data instanceof \Pods\Whatsit\Field ) { $field_source = 'field'; $is_field_set = true; - } elseif ( ! empty( $this->pod_data['object_fields'] ) ) { - // Get the object field data. - if ( isset( $this->pod_data['object_fields'][ $first_field ] ) ) { - $field_data = $this->pod_data['object_fields'][ $first_field ]; - $field_source = 'object_field'; - $is_field_set = true; - } else { - $object_fields = (array) $this->pod_data['object_fields']; - - // Search through field aliases. - foreach ( $object_fields as $object_field => $object_field_opt ) { - if ( in_array( $first_field, $object_field_opt['alias'], true ) ) { - if ( $first_field === $params->name ) { - $params->name = $object_field; - } - - $first_field = $object_field; - $field_data = $object_field_opt; - $field_source = 'object_field'; - $is_field_set = true; - - break; - } - } - } - }//end if + } // Store field info. $field_type = pods_v( 'type', $field_data, '' ); - $field_options = pods_v( 'options', $field_data, array() ); + $field_options = $field_data; $is_tableless_field = in_array( $field_type, $tableless_field_types, true ); // Simple fields have no other output options. @@ -1016,10 +789,10 @@ public function field( $name, $single = null, $raw = false ) { $row_key = '_' . $params->output . '_' . $params->name; - if ( 'arrays' !== $params->output && isset( $this->row[ $row_key ] ) ) { - $value = $this->row[ $row_key ]; - } elseif ( 'arrays' === $params->output && isset( $this->row[ $params->name ] ) ) { - $value = $this->row[ $params->name ]; + if ( 'arrays' !== $params->output && isset( $this->data->row[ $row_key ] ) ) { + $value = $this->data->row[ $row_key ]; + } elseif ( 'arrays' === $params->output && isset( $this->data->row[ $params->name ] ) ) { + $value = $this->data->row[ $params->name ]; } if ( @@ -1034,10 +807,14 @@ public function field( $name, $single = null, $raw = false ) { if ( empty( $value ) && - isset( $this->row[ $params->name ] ) && + isset( $this->data->row[ $params->name ] ) && ( ! $is_tableless_field || 'arrays' === $params->output ) ) { - if ( empty( $field_data ) || in_array( $field_type, array( 'boolean', 'number', 'currency' ), true ) ) { + if ( empty( $field_data ) || in_array( $field_type, [ + 'boolean', + 'number', + 'currency', + ], true ) ) { $params->raw = true; } @@ -1049,147 +826,27 @@ public function field( $name, $single = null, $raw = false ) { } } - $value = $this->row[ $params->name ]; + $value = $this->data->row[ $params->name ]; } elseif ( empty( $value ) ) { $object_field_found = false; if ( 'object_field' === $field_source ) { $object_field_found = true; - if ( isset( $this->row[ $first_field ] ) ) { - $value = $this->row[ $first_field ]; + if ( isset( $this->data->row[ $first_field ] ) ) { + $value = $this->data->row[ $first_field ]; } elseif ( $is_tableless_field ) { - // Overwrite existing field data. - $this->fields[ $first_field ] = $field_data; - $object_field_found = false; } else { return null; } + } else { + // Handle custom/supported value mappings. + $map_field_values = tribe( Map_Field_Values::class ); - } elseif ( 'avatar' === $first_field && 'user' === $pod_type ) { - // User avatar. - $size = null; - $get_avatar = true; - - if ( $is_traversal ) { - if ( $is_field_set ) { - // This is a registered field. - if ( isset( $traverse_fields[1] ) && is_numeric( $traverse_fields[1] ) ) { - $size = (int) $traverse_fields[1]; - } else { - // Traverse through attachment post. - $get_avatar = false; - } - } else { - if ( isset( $traverse_fields[1] ) ) { - $size = (int) $traverse_fields[1]; - } - } - } - - if ( $get_avatar ) { - $object_field_found = true; - if ( 0 < $size ) { - $value = get_avatar( $this->id(), $size ); - } else { - $value = get_avatar( $this->id() ); - } - } - - } elseif ( ! $is_field_set ) { - - $image_fields = array( - 'image_attachment', - 'image_attachment_url', - ); - - if ( 'post_type' === $pod_type ) { - $image_fields[] = 'post_thumbnail'; - $image_fields[] = 'post_thumbnail_url'; - } - - // Handle special field tags. - if ( in_array( $first_field, $image_fields, true ) ) { - // Default image field handlers. - $object_field_found = true; - - $image_field = $first_field; - // Is it a URL request? - $url = '_url' === substr( $image_field, - 4 ); - if ( $url ) { - $image_field = substr( $image_field, 0, - 4 ); - } - - // Copy traversal parameters. - $traverse_params = $traverse_fields; - // Results in an empty array if no traversal params are passed. - array_shift( $traverse_params ); - - $attachment_id = 0; - switch ( $image_field ) { - case 'post_thumbnail': - $attachment_id = get_post_thumbnail_id( $this->id() ); - break; - case 'image_attachment': - if ( isset( $traverse_params[0] ) ) { - $attachment_id = $traverse_params[0]; - array_shift( $traverse_params ); - } - break; - } - - if ( $attachment_id ) { - $is_image = wp_attachment_is_image( $attachment_id ); - - $size = 'thumbnail'; - if ( isset( $traverse_params[0] ) ) { - $size = $traverse_params[0]; - - if ( pods_is_image_size( $size ) ) { - // Force image request since a valid size parameter is passed. - $is_image = true; - } else { - // No valid image size found. - $size = false; - } - } - - if ( $url ) { - if ( $is_image ) { - $value = pods_image_url( $attachment_id, $size, 0, true ); - } else { - $value = wp_get_attachment_url( $attachment_id ); - } - } elseif ( $size ) { - // Pods will auto-get the thumbnail ID if this isn't an attachment. - $value = pods_image( $attachment_id, $size, 0, null, true ); - } else { - // Fallback to attachment Post object to look for other image properties. - $media = pods( 'media', $attachment_id ); - - if ( $media && $media->valid() && $media->exists() ) { - $value = $media->field( implode( '.', $traverse_params ) ); - } else { - // Fallback to default attachment object. - $attachment = get_post( $attachment_id ); - $value = pods_v( implode( '.', $traverse_params ), $attachment, null ); - - if ( null === $value ) { - // Start traversal though object property or metadata. - $name_key = array_shift( $traverse_params ); - $value = pods_v( $name_key, $attachment, null ); - - if ( null === $value ) { - $value = get_post_meta( $attachment_id, $name_key, true ); - } + $value = $map_field_values->map_value( $first_field, $traverse_fields, $is_field_set ? $field_data : null, $this ); - $value = pods_traverse( $traverse_params, $value ); - } - } - } - } - } + $object_field_found = null !== $value; } // Continue regular field parsing. @@ -1202,8 +859,9 @@ public function field( $name, $single = null, $raw = false ) { $params->name = $params->traverse[0]; } - if ( $field_type ) { + $simple = false; + if ( $field_data ) { /** * Modify value returned by field() after its retrieved, but before its validated or formatted * @@ -1211,21 +869,17 @@ public function field( $name, $single = null, $raw = false ) { * * @since unknown * - * @param array|string|null $value Value retrieved. - * @param array|object $row Current row being outputted. - * @param array $params Params array passed to field(). - * @param object|Pods $this Current Pods object. + * @param array|string|null $value Value retrieved. + * @param array $field_data Current field object. + * @param array|object $row Current row being outputted. + * @param array $params Params array passed to field(). + * @param object|Pods $this Current Pods object. */ - $v = apply_filters( "pods_pods_field_{$field_type}", null, $this->fields[ $params->name ], $this->row, $params, $this ); + $v = apply_filters( "pods_pods_field_{$field_type}", null, $field_data, $this->row(), $params, $this ); if ( null !== $v ) { return $v; } - } - - $simple = false; - - if ( $is_field_set ) { if ( 'meta' === $this->pod_data['storage'] && ! $is_tableless_field ) { $simple = true; @@ -1238,7 +892,11 @@ public function field( $name, $single = null, $raw = false ) { $simple = true; $params->single = true; } - } elseif ( in_array( $field_type, array( 'boolean', 'number', 'currency' ), true ) ) { + } elseif ( in_array( $field_type, [ + 'boolean', + 'number', + 'currency', + ], true ) ) { $params->raw = true; } } @@ -1259,32 +917,34 @@ public function field( $name, $single = null, $raw = false ) { pods_no_conflict_on( $pod_type ); } - if ( $is_wp_object ) { - $id = $this->id(); - + if ( $use_meta_fallback ) { $metadata_type = $pod_type; if ( in_array( $metadata_type, array( 'post_type', 'media' ), true ) ) { $metadata_type = 'post'; - - // Support for WPML 'duplicated' translation handling. - if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_is_translated_post_type', false, $this->pod_data['name'] ) ) { - $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $id ); - - if ( $master_post_id ) { - $id = $master_post_id; - } - } } elseif ( 'taxonomy' === $metadata_type ) { $metadata_type = 'term'; } + /** + * Modify the object ID for getting metadata. + * Added for i18n integration classes. + * + * @since 2.8.0 + * + * @param int $id The object ID. + * @param string $metadata_type The object metadata type. + * @param array $params Field params + * @param \Pods $pod Pods object. + */ + $id = apply_filters( 'pods_pods_field_get_metadata_object_id', $this->id(), $metadata_type, $params, $this ); + $value = get_metadata( $metadata_type, $id, $params->name, $params->single ); $single_multi = 'single'; - if ( $is_field_set && $field_type ) { - $single_multi = pods_v( $field_type . '_format_type', $field_options, $single_multi ); + if ( $is_field_set ) { + $single_multi = pods_v( $field_type . '_format_type', $field_data, $single_multi ); } if ( $simple && ! is_array( $value ) && 'single' !== $single_multi ) { @@ -1300,7 +960,7 @@ public function field( $name, $single = null, $raw = false ) { $params->single = false; } - $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $this->fields[ $params->name ], $this->pod_data, $this->id(), true ); + $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $field_data, $this->pod_data, $this->id(), true ); } if ( ! $no_conflict ) { @@ -1309,7 +969,7 @@ public function field( $name, $single = null, $raw = false ) { } } else { // Dot-traversal. - $pod = $this->pod; + $pod = $this->pod_data['name']; $ids = array( $this->id() ); $all_fields = array(); @@ -1317,12 +977,17 @@ public function field( $name, $single = null, $raw = false ) { // Get fields matching traversal names. if ( ! empty( $lookup ) ) { - $fields = $this->api->load_fields( array( - 'name' => $lookup, - 'type' => $tableless_field_types, - 'object_fields' => true, - // @todo support object fields too. - ) ); + if ( 1 === count( $params->traverse ) && $params->name === $params->traverse[0] && $field_data && $field_data['name'] === $params->traverse[0] ) { + $fields = array( + $field_data, + ); + } else { + $fields = $this->data->api->traverse_fields( array( + 'pod' => $pod, + 'expand' => $lookup, + 'type' => $tableless_field_types, + ) ); + } if ( ! empty( $fields ) ) { foreach ( $fields as $field ) { @@ -1335,26 +1000,17 @@ public function field( $name, $single = null, $raw = false ) { } } } - - if ( ! empty( $this->pod_data['object_fields'] ) ) { - $object_fields = (array) $this->pod_data['object_fields']; - - foreach ( $object_fields as $object_field => $object_field_opt ) { - if ( in_array( $object_field_opt['type'], $tableless_field_types, true ) ) { - $all_fields[ $this->pod ][ $object_field ] = $object_field_opt; - } - } - } }//end if $last_type = ''; $last_object = ''; $last_pick_val = ''; + $last_options = array(); - $single_multi = pods_v( $field_type . '_format_type', $field_options, 'single' ); + $single_multi = pods_v( $field_type . '_format_type', $field_data, 'single' ); if ( 'multi' === $single_multi ) { - $limit = (int) pods_v( $field_type . '_limit', $field_options, 0 ); + $limit = (int) pods_v( $field_type . '_limit', $field_data, 0 ); } else { $limit = 1; } @@ -1369,41 +1025,39 @@ public function field( $name, $single = null, $raw = false ) { $field_exists = isset( $all_fields[ $pod ][ $field ] ); - $simple = false; - $last_options = array(); + $current_field = null; + $simple = false; + + if ( $field_exists ) { + /** @var \Pods\Whatsit\Field $current_field */ + $current_field = $all_fields[ $pod ][ $field ]; - if ( - $field_exists && - 'pick' === $all_fields[ $pod ][ $field ]['type'] && - in_array( $all_fields[ $pod ][ $field ]['pick_object'], $simple_tableless_objects, true ) - ) { - $simple = true; - $last_options = $all_fields[ $pod ][ $field ]; + if ( in_array( $current_field['type'], $tableless_field_types, true ) ) { + $last_options = $current_field; + + if ( 'pick' === $current_field['type'] && in_array( $current_field->get_related_object_type(), $simple_tableless_objects, true ) ) { + $simple = true; + } + } } // Tableless handler. - if ( $field_exists && ( ! $simple || ! in_array( $all_fields[ $pod ][ $field ]['type'], array( + if ( $field_exists && ( ! $simple || ! in_array( $current_field['type'], array( 'pick', 'taxonomy', 'comment', ), true ) ) ) { - $type = $all_fields[ $pod ][ $field ]['type']; - $pick_object = $all_fields[ $pod ][ $field ]['pick_object']; - $pick_val = $all_fields[ $pod ][ $field ]['pick_val']; - - if ( 'table' === $pick_object ) { - $pick_val = pods_v( 'pick_table', $all_fields[ $pod ][ $field ]['options'], $pick_val, true ); - } elseif ( '__current__' === $pick_val ) { - $pick_val = $pod; - } + $type = $current_field['type']; + $pick_object = $current_field->get_related_object_type(); + $pick_val = $current_field->get_related_object_name(); $last_limit = 0; if ( in_array( $type, $tableless_field_types, true ) ) { - $single_multi = pods_v( "{$type}_format_type", $all_fields[ $pod ][ $field ]['options'], 'single' ); + $single_multi = $current_field->get_arg( "{$type}_format_type", 'single' ); if ( 'multi' === $single_multi ) { - $last_limit = (int) pods_v( "{$type}_limit", $all_fields[ $pod ][ $field ]['options'], 0 ); + $last_limit = (int) $current_field->get_arg( "{$type}_limit", 0 ); } else { $last_limit = 1; } @@ -1412,24 +1066,26 @@ public function field( $name, $single = null, $raw = false ) { $last_type = $type; $last_object = $pick_object; $last_pick_val = $pick_val; - $last_options = $all_fields[ $pod ][ $field ]; + $last_options = $current_field; // Temporary hack until there's some better handling here. $last_limit *= count( $ids ); // Get related IDs. - if ( ! isset( $all_fields[ $pod ][ $field ]['pod_id'] ) ) { - $all_fields[ $pod ][ $field ]['pod_id'] = 0; - } - - if ( isset( $all_fields[ $pod ][ $field ]['id'] ) ) { - $ids = $this->api->lookup_related_items( $all_fields[ $pod ][ $field ]['id'], $all_fields[ $pod ][ $field ]['pod_id'], $ids, $all_fields[ $pod ][ $field ] ); + if ( isset( $current_field['id'] ) ) { + $ids = $this->data->api->lookup_related_items( $current_field['id'], $current_field->get_parent_id(), $ids, $current_field ); } // No items found. if ( empty( $ids ) ) { + // pods_debug( 'No related IDs found! ' . var_export( array( 'id' => $current_field['id'], 'pod_id' => $current_field->get_parent_id(), 'ids' => $ids, 'current_field' => empty( $current_field['id'] ) ? $current_field : 'has field id tho' ), true ) ); + return false; - } elseif ( 0 < $last_limit ) { + } + + // pods_debug( 'Related IDs found! ' . var_export( array( 'id' => $current_field['id'], 'pod_id' => $current_field->get_parent_id(), 'ids' => $ids ), true ) ); + + if ( 0 < $last_limit ) { // @todo This should return array() if not $params->single. $ids = array_slice( $ids, 0, $last_limit ); } @@ -1443,9 +1099,9 @@ public function field( $name, $single = null, $raw = false ) { if ( 'pod' === $pick_object ) { $pod = $pick_val; } else { - $check = $this->api->get_table_info( $pick_object, $pick_val ); + $check = $current_field->get_table_info(); - if ( ! empty( $check ) && ! empty( $check['pod'] ) ) { + if ( $check && ! empty( $check['pod'] ) ) { $pod = $check['pod']['name']; } } @@ -1467,12 +1123,15 @@ public function field( $name, $single = null, $raw = false ) { if ( in_array( $last_type, PodsForm::file_field_types(), true ) ) { $object_type = 'media'; - $object = 'attachment'; + $object = 'media'; } - $data = array(); + $data = array(); + $table = array(); - $table = $this->api->get_table_info( $object_type, $object, null, null, $last_options ); + if ( $last_options ) { + $table = $last_options->get_table_info(); + } $join = array(); $where = array(); @@ -1481,7 +1140,9 @@ public function field( $name, $single = null, $raw = false ) { $join = (array) $table['join']; } - if ( ! empty( $ids ) || ! empty( $table['where'] ) ) { + // pods_debug( 'IDs found: ' . var_export( $ids, true ) ); + + if ( $table && ( ! empty( $ids ) || ! empty( $table['where'] ) ) ) { foreach ( $ids as $id ) { $where[ $id ] = '`t`.`' . $table['field_id'] . '` = ' . (int) $id; } @@ -1516,7 +1177,7 @@ public function field( $name, $single = null, $raw = false ) { $related_obj = pods( $table['pod']['name'], null, false ); } - if ( $related_obj || ! empty( $table['table'] ) ) { + if ( $table && ( $related_obj || ! empty( $table['table'] ) ) ) { $sql = array( 'select' => '*, `t`.`' . $table['field_id'] . '` AS `pod_item_id`', 'table' => $table['table'], @@ -1557,7 +1218,7 @@ public function field( $name, $single = null, $raw = false ) { if ( ! $related_obj || ! $related_obj->valid() ) { if ( ! is_object( $this->alt_data ) ) { - $this->alt_data = pods_data( null, 0, true, true ); + $this->alt_data = pods_data(); } $item_data = $this->alt_data->select( $sql ); @@ -1711,12 +1372,12 @@ public function field( $name, $single = null, $raw = false ) { // Return an array of single column values. $value = array(); - foreach ( $data as $item_id => $item ) { - // $field is 123x123, needs to be _src.123x123 - $traverse_fields = array_splice( $params->traverse, $key ); - $full_field = implode( '.', $traverse_fields ); - array_shift( $traverse_fields ); + // $field is 123x123, needs to be _src.123x123 + $traverse_fields = array_splice( $params->traverse, $key ); + $full_field = implode( '.', $traverse_fields ); + array_shift( $traverse_fields ); + foreach ( $data as $item_id => $item ) { if ( is_array( $item ) && isset( $item[ $field ] ) ) { if ( $table['field_id'] === $field ) { $value[] = (int) $item[ $field ]; @@ -1736,7 +1397,7 @@ public function field( $name, $single = null, $raw = false ) { ( ( false !== strpos( $full_field, '_src' ) || 'guid' === $field ) && ( - in_array( $table['type'], array( 'attachment', 'media' ), true ) + in_array( $table['type'], [ 'attachment', 'media' ], true ) || in_array( $last_type, PodsForm::file_field_types(), true ) ) ) @@ -1830,24 +1491,20 @@ public function field( $name, $single = null, $raw = false ) { $metadata_type = $object_type; - if ( 'post' === $object_type ) { - // Support for WPML 'duplicated' translation handling. - if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_is_translated_post_type', false, $object ) ) { - $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $metadata_object_id ); - - if ( 0 < $master_post_id ) { - $metadata_object_id = $master_post_id; - } - } - } elseif ( 'taxonomy' === $object_type ) { + if ( 'taxonomy' === $object_type ) { $metadata_type = 'term'; } + /** This filter is documented earlier in this method */ + $metadata_object_id = apply_filters( 'pods_pods_field_get_metadata_object_id', $metadata_object_id, $metadata_type, $params, $this ); + $meta_value = get_metadata( $metadata_type, $metadata_object_id, $field, true ); - $value[] = pods_traverse( $traverse_fields, $meta_value ); + + $value[] = pods_traverse( $traverse_fields, $meta_value ); } elseif ( 'settings' === $object_type ) { $option_value = get_option( $object . '_' . $field ); - $value[] = pods_traverse( $traverse_fields, $option_value ); + + $value[] = pods_traverse( $traverse_fields, $option_value ); }//end if }//end foreach }//end if @@ -1874,6 +1531,9 @@ public function field( $name, $single = null, $raw = false ) { } }//end if + // pods_debug( 'value' ); + // pods_debug( compact( 'value', 'data' ) ); + if ( $last_options ) { $last_field_data = $last_options; } elseif ( isset( $related_obj, $related_obj->fields, $related_obj->fields[ $field ] ) ) { @@ -1891,11 +1551,11 @@ public function field( $name, $single = null, $raw = false ) { if ( ! empty( $params->traverse ) && 1 < count( $params->traverse ) ) { $field_names = implode( '.', $params->traverse ); - $this->row[ $field_names ] = $value; - } elseif ( 'arrays' !== $params->output && in_array( $field_data['type'], $tableless_field_types, true ) ) { - $this->row[ '_' . $params->output . '_' . $params->full_name ] = $value; - } elseif ( 'arrays' === $params->output || ! in_array( $field_data['type'], $tableless_field_types, true ) ) { - $this->row[ $params->full_name ] = $value; + $this->data->row[ $field_names ] = $value; + } elseif ( 'arrays' !== $params->output && $field_data && in_array( $field_data['type'], $tableless_field_types, true ) ) { + $this->data->row[ '_' . $params->output . '_' . $params->full_name ] = $value; + } elseif ( 'arrays' === $params->output || ! $field_data || ! in_array( $field_data['type'], $tableless_field_types, true ) ) { + $this->data->row[ $params->full_name ] = $value; } if ( true === $params->single && is_array( $value ) && 1 === count( $value ) ) { @@ -1908,8 +1568,6 @@ public function field( $name, $single = null, $raw = false ) { if ( ! empty( $field_data ) && ( $params->display || ! $params->raw ) && ! $params->in_form && ! $params->raw_display ) { if ( $params->display || ( ( $params->get_meta || $params->deprecated ) && ! in_array( $field_data['type'], $tableless_field_types, true ) ) ) { - $field_data['options'] = pods_v( 'options', $field_data, array(), true ); - $post_temp = false; $old_post = null; $old_post_id = null; @@ -1929,22 +1587,20 @@ public function field( $name, $single = null, $raw = false ) { $post_ID = $this->id(); } - $filter = pods_v( 'display_filter', $field_data['options'] ); + $filter = pods_v( 'display_filter', $field_data ); if ( 0 < strlen( $filter ) ) { - if ( $params->single ) { $value = array( $value ); } foreach ( $value as $key => $val ) { - $args = array( $filter, $val, ); - $filter_args = pods_v( 'display_filter_args', $field_data['options'] ); + $filter_args = pods_v( 'display_filter_args', $field_data ); if ( ! empty( $filter_args ) ) { $args = array_merge( $args, compact( $filter_args ) ); @@ -1959,9 +1615,16 @@ public function field( $name, $single = null, $raw = false ) { if ( $params->single ) { $value = reset( $value ); } - - } elseif ( 1 === (int) pods_v( 'display_process', $field_data['options'], 1 ) ) { - $value = PodsForm::display( $field_data['type'], $value, $params->name, array_merge( $field_data, $field_data['options'] ), $this->pod_data, $this->id() ); + } elseif ( 1 === (int) pods_v( 'display_process', $field_data, 1 ) ) { + if ( ! is_array( $value ) || ! $params->display_process_individually ) { + // Do the normal display handling. + $value = PodsForm::display( $field_data['type'], $value, $params->name, $field_data, $this->pod_data, $this->id() ); + } else { + // Attempt to process each value independently. + foreach ( $value as $k => $val ) { + $value[ $k ] = PodsForm::display( $field_data['type'], $val, $params->name, $field_data, $this->pod_data, $this->id() ); + } + } } if ( $post_temp ) { @@ -1971,7 +1634,7 @@ public function field( $name, $single = null, $raw = false ) { $post_ID = $old_post_id; } } else { - $value = PodsForm::value( $field_data['type'], $value, $params->name, array_merge( $field_data, $field_data['options'] ), $this->pod_data, $this->id() ); + $value = PodsForm::value( $field_data['type'], $value, $params->name, $field_data, $this->pod_data, $this->id() ); }//end if }//end if @@ -1987,7 +1650,7 @@ public function field( $name, $single = null, $raw = false ) { * @param array $params Params array passed to field(). * @param object|Pods $this Current Pods object. */ - $value = apply_filters( 'pods_pods_field', $value, $this->row, $params, $this ); + $value = apply_filters( 'pods_pods_field', $value, $this->row(), $params, $this ); return $value; } @@ -2040,7 +1703,7 @@ public function has( $field, $value, $id = null ) { } } } else { - $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); + $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); foreach ( $value as $k => $v ) { if ( ! preg_match( '/[^\D]/', $v ) ) { @@ -2122,7 +1785,7 @@ public function is( $field, $value, $id = null ) { } } } else { - $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); + $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); foreach ( $value as $k => $v ) { if ( ! preg_match( '/[^\D]/', $v ) ) { @@ -2203,7 +1866,7 @@ public function is( $field, $value, $id = null ) { */ public function id() { - if ( isset( $this->data->row, $this->data->row['id'] ) ) { + if ( isset( $this->data->row['id'] ) ) { // If we already have data loaded return that ID. return $this->data->row['id']; } @@ -2255,8 +1918,8 @@ public function prev_id( $id = null, $params_override = null ) { } } elseif ( isset( $params['offset'] ) && 0 < $params['offset'] ) { $params['offset'] --; - } elseif ( 0 < $this->row_number && ! isset( $params['offset'] ) && ! empty( $this->params ) ) { - $params['offset'] = $this->row_number - 1; + } elseif ( 0 < $this->data->row_number && ! isset( $params['offset'] ) && ! empty( $this->params ) ) { + $params['offset'] = $this->data->row_number - 1; } else { return 0; } @@ -2343,8 +2006,8 @@ public function next_id( $id = null, $params_override = null ) { $params['where'] = "{$id} < `t`.`{$this->data->field_id}`"; } } elseif ( ! isset( $params['offset'] ) ) { - if ( ! empty( $this->params ) && - 1 < $this->row_number ) { - $params['offset'] = $this->row_number + 1; + if ( ! empty( $this->params ) && - 1 < $this->data->row_number ) { + $params['offset'] = $this->data->row_number + 1; } else { $params['offset'] = 1; } @@ -2507,7 +2170,7 @@ public function index() { * * @return \Pods The pod object * @since 2.0.0 - * @link https://pods.io/docs/find/ + * @link https://docs.pods.io/code/pods/find/ */ public function find( $params = null, $limit = 15, $where = null, $sql = null ) { @@ -2518,6 +2181,10 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) $select = '`t`.*'; + if ( ! $this->pod_data instanceof Pods\Whatsit\Pod ) { + return $this; + } + if ( 'table' === $this->pod_data['storage'] && ! in_array( $this->pod_data['type'], array( 'pod', 'table', @@ -2525,13 +2192,15 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) $select .= ', `d`.*'; } - if ( empty( $this->data->table ) ) { + $table = $this->pod_data['table']; + + if ( empty( $table ) ) { return $this; } $defaults = array( // Optimization parameters. - 'table' => $this->data->table, + 'table' => $table, 'select' => $select, 'join' => null, // Main query parameters. @@ -2609,8 +2278,13 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) $order = 'DESC'; } - if ( isset( $this->fields[ $k ] ) && in_array( $this->fields[ $k ]['type'], $tableless_field_types, true ) ) { - if ( in_array( $this->fields[ $k ]['pick_object'], $simple_tableless_objects, true ) ) { + $order_field = $this->fields( $k ); + + if ( $order_field && in_array( $order_field['type'], $tableless_field_types, true ) ) { + $order_object_type = $order_field->get_related_object_type(); + $order_object_name = $order_field->get_related_object_name(); + + if ( in_array( $order_object_type, $simple_tableless_objects, true ) ) { if ( 'table' === $this->pod_data['storage'] ) { if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) { $key = "`d`.`{$k}`"; @@ -2621,13 +2295,7 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) $key = "`{$k}`.`meta_value`"; } } else { - $pick_val = $this->fields[ $k ]['pick_val']; - - if ( '__current__' === $pick_val ) { - $pick_val = $this->pod; - } - - $table = $this->api->get_table_info( $this->fields[ $k ]['pick_object'], $pick_val ); + $table = $order_field->get_table_info(); if ( ! empty( $table ) ) { $key = "`{$k}`.`" . $table['field_index'] . '`'; @@ -2639,7 +2307,7 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) { if ( isset( $this->pod_data['object_fields'][ $k ] ) ) { $key = "`t`.`{$k}`"; - } elseif ( isset( $this->fields[ $k ] ) ) { + } elseif ( $order_field ) { if ( 'table' === $this->pod_data['storage'] ) { $key = "`d`.`{$k}`"; } else { @@ -2654,7 +2322,7 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) } } } - } elseif ( isset( $this->fields[ $k ] ) ) { + } elseif ( $order_field ) { if ( 'table' === $this->pod_data['storage'] ) { $key = "`t`.`{$k}`"; } else { @@ -2700,10 +2368,12 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) $key = $k; + $order_field = $this->fields( $k ); + if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) { if ( isset( $this->pod_data['object_fields'][ $k ] ) ) { $key = "`t`.`{$k}`"; - } elseif ( isset( $this->fields[ $k ] ) ) { + } elseif ( $order_field ) { if ( 'table' === $this->pod_data['storage'] ) { $key = "`d`.`{$k}`"; } else { @@ -2718,7 +2388,7 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) } } } - } elseif ( isset( $this->fields[ $k ] ) ) { + } elseif ( $order_field ) { if ( 'table' === $this->pod_data['storage'] ) { $key = "`t`.`{$k}`"; } else { @@ -2753,7 +2423,7 @@ public function find( $params = null, $limit = 15, $where = null, $sql = null ) * @return array An array of fields from the row * * @since 2.0.0 - * @link https://pods.io/docs/fetch/ + * @link https://docs.pods.io/code/pods/fetch/ */ public function fetch( $id = null, $explicit_set = true ) { @@ -2773,7 +2443,7 @@ public function fetch( $id = null, $explicit_set = true ) { $this->data->fetch( $id, $explicit_set ); - return $this->row; + return $this->row(); } /** @@ -2786,7 +2456,7 @@ public function fetch( $id = null, $explicit_set = true ) { * @return \Pods The pod object * * @since 2.0.0 - * @link https://pods.io/docs/reset/ + * @link https://docs.pods.io/code/pods/reset/ */ public function reset( $row = null ) { @@ -2814,7 +2484,7 @@ public function reset( $row = null ) { * * @return int Number of rows returned by find(), based on the 'limit' parameter set * @since 2.0.0 - * @link https://pods.io/docs/total/ + * @link https://docs.pods.io/code/pods/total/ */ public function total() { @@ -2822,9 +2492,7 @@ public function total() { $this->data->total(); - $this->total =& $this->data->total; - - return $this->total; + return $this->data->total; } /** @@ -2836,7 +2504,7 @@ public function total() { * * @return int Number of rows returned by find(), regardless of the 'limit' parameter * @since 2.0.0 - * @link https://pods.io/docs/total-found/ + * @link https://docs.pods.io/code/pods/total-found/ */ public function total_found() { @@ -2851,9 +2519,7 @@ public function total_found() { $this->data->total_found(); - $this->total_found =& $this->data->total_found; - - return $this->total_found; + return $this->data->total_found; } /** @@ -2947,7 +2613,7 @@ public function position() { * @return int The item ID * * @since 2.0.0 - * @link https://pods.io/docs/add/ + * @link https://docs.pods.io/code/pods/add/ */ public function add( $data = null, $value = null ) { @@ -2967,7 +2633,7 @@ public function add( $data = null, $value = null ) { 'allow_custom_fields' => true, ); - return $this->api->save_pod_item( $params ); + return $this->data->api->save_pod_item( $params ); } /** @@ -3022,7 +2688,7 @@ public function add_to( $field, $value, $id = null ) { $value = array_merge( $current_value, $value ); } else { - $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); + $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); foreach ( $value as $k => $v ) { if ( ! preg_match( '/[^\D]/', $v ) ) { @@ -3074,7 +2740,7 @@ public function add_to( $field, $value, $id = null ) { ), ); - $id = $this->api->save_pod_item( $params ); + $id = $this->data->api->save_pod_item( $params ); if ( 0 < $id && $fetch ) { // Clear local var cache of field values. @@ -3148,7 +2814,7 @@ public function remove_from( $field, $value = null, $id = null ) { $value = $current_value; } else { - $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); + $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data ); foreach ( $value as $k => $v ) { if ( ! preg_match( '/[^\D]/', $v ) ) { @@ -3211,7 +2877,7 @@ public function remove_from( $field, $value = null, $id = null ) { ), ); - $id = $this->api->save_pod_item( $params ); + $id = $this->data->api->save_pod_item( $params ); if ( 0 < $id && $fetch ) { // Clear local var cache of field values. @@ -3240,7 +2906,7 @@ public function remove_from( $field, $value = null, $id = null ) { * @return int The item ID * * @since 2.0.0 - * @link https://pods.io/docs/save/ + * @link https://docs.pods.io/code/pods/save/ */ public function save( $data = null, $value = null, $id = null, $params = null ) { @@ -3251,7 +2917,7 @@ public function save( $data = null, $value = null, $id = null, $params = null ) $fetch = false; // @codingStandardsIgnoreLine - if ( null === $id || ( $this->row && $id == $this->id() ) ) { + if ( null === $id || ( $this->row() && $id == $this->id() ) ) { $fetch = true; if ( null === $id ) { @@ -3261,7 +2927,7 @@ public function save( $data = null, $value = null, $id = null, $params = null ) $data = (array) $this->do_hook( 'save', $data, $id ); - if ( empty( $data ) && empty( $params['is_new_item'] ) ) { + if ( empty( $data ) && empty( $params['is_new_item'] ) && empty( $params['podsmeta'] ) ) { return $id; } @@ -3271,6 +2937,13 @@ public function save( $data = null, $value = null, $id = null, $params = null ) $default = $params; } + // If ID is sent as part of data, use it and then unset it from the data. + if ( isset( $data[ $this->pod_data['field_id'] ] ) ) { + $id = $data[ $this->pod_data['field_id'] ]; + + unset( $data[ $this->pod_data['field_id'] ] ); + } + $params = array( 'pod' => $this->pod, 'id' => $id, @@ -3283,7 +2956,7 @@ public function save( $data = null, $value = null, $id = null, $params = null ) $params = array_merge( $params, $default ); } - $id = $this->api->save_pod_item( $params ); + $id = $this->data->api->save_pod_item( $params ); if ( 0 < $id && $fetch ) { // Clear local var cache of field values. @@ -3317,7 +2990,7 @@ public function save( $data = null, $value = null, $id = null, $params = null ) * @return bool Whether the item was successfully deleted * * @since 2.0.0 - * @link https://pods.io/docs/delete/ + * @link https://docs.pods.io/code/pods/delete/ */ public function delete( $id = null ) { @@ -3336,7 +3009,7 @@ public function delete( $id = null ) { 'id' => $id, ); - return $this->api->delete_pod_item( $params ); + return $this->data->api->delete_pod_item( $params ); } /** @@ -3349,17 +3022,19 @@ public function delete( $id = null ) { * @since 2.1.1 */ public function reset_pod() { - - $params = array( 'id' => $this->pod_id ); + $params = [ + 'id' => $this->pod_id, + 'name' => $this->pod, + ]; $this->data->id = null; - $this->data->row = array(); - $this->data->data = array(); + $this->data->row = []; + $this->data->data = []; $this->data->total = 0; $this->data->total_found = 0; - return $this->api->reset_pod( $params ); + return $this->data->api->reset_pod( $params ); } /** @@ -3372,7 +3047,7 @@ public function reset_pod() { * @return int|bool ID of the new pod item * * @since 2.0.0 - * @link https://pods.io/docs/duplicate/ + * @link https://docs.pods.io/code/pods/duplicate/ */ public function duplicate( $id = null ) { @@ -3391,7 +3066,7 @@ public function duplicate( $id = null ) { 'id' => $id, ); - return $this->api->duplicate_pod_item( $params ); + return $this->data->api->duplicate_pod_item( $params ); } /** @@ -3409,7 +3084,7 @@ public function duplicate( $id = null ) { */ public function import( $import_data, $numeric_mode = false, $format = null ) { - return $this->api->import( $import_data, $numeric_mode, $format ); + return $this->data->api->import( $import_data, $numeric_mode, $format ); } /** @@ -3424,7 +3099,7 @@ public function import( $import_data, $numeric_mode = false, $format = null ) { * @return array|bool Data array of the exported pod item * * @since 2.0.0 - * @link https://pods.io/docs/export/ + * @link https://docs.pods.io/code/pods/export/ */ public function export( $fields = null, $id = null, $format = null ) { @@ -3458,7 +3133,7 @@ public function export( $fields = null, $id = null, $format = null ) { return false; } - $data = $this->api->export_pod_item( $params ); + $data = $this->data->api->export_pod_item( $params ); if ( ! empty( $params['format'] ) && 'json' === $params['format'] ) { $data = wp_json_encode( (array) $data ); @@ -3492,7 +3167,7 @@ public function export_data( $params = null ) { $params = array_merge( $defaults, (array) $params ); } - return $this->api->export( $this, $params ); + return $this->data->api->export( $this, $params ); } /** @@ -3504,7 +3179,7 @@ public function export_data( $params = null ) { * * @return string Pagination HTML * @since 2.0.0 - * @link https://pods.io/docs/pagination/ + * @link https://docs.pods.io/code/pods/pagination/ */ public function pagination( $params = null ) { @@ -3583,7 +3258,7 @@ public function pagination( $params = null ) { * @return string Filters HTML * * @since 2.0.0 - * @link https://pods.io/docs/filters/ + * @link https://docs.pods.io/code/pods/filters/ */ public function filters( $params = null ) { @@ -3634,7 +3309,9 @@ public function filters( $params = null ) { 'name' => $name, ); - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $name = $field; $field = array( @@ -3643,7 +3320,7 @@ public function filters( $params = null ) { } // @codingStandardsIgnoreLine. - $field = array_merge( $defaults, $field ); + $field = pods_config_merge_data( $defaults, $field ); $field['name'] = trim( $field['name'] ); @@ -3653,14 +3330,14 @@ public function filters( $params = null ) { if ( isset( $object_fields[ $field['name'] ] ) ) { // @codingStandardsIgnoreLine. - $fields[ $field['name'] ] = array_merge( $object_fields[ $field['name'] ], $field ); + $fields[ $field['name'] ] = pods_config_merge_data( $object_fields[ $field['name'] ], $field ); } elseif ( isset( $this->fields[ $field['name'] ] ) ) { // @codingStandardsIgnoreLine. - $fields[ $field['name'] ] = array_merge( $this->fields[ $field['name'] ], $field ); + $fields[ $field['name'] ] = pods_config_merge_data( $this->fields[ $field['name'] ], $field ); } }//end foreach - // Cleanup. + // Cleanup before get_defined_vars(). unset( $filter_fields ); }//end if @@ -3699,9 +3376,7 @@ public function filters( $params = null ) { } /** - * Run a helper within a Pod Page or WP Template - * - * @see Pods_Helpers::helper + * Run a helper within a Pod Page or WP Template. * * @param string|array $helper Helper name. * @param string $value Value to run the helper on. @@ -3727,65 +3402,82 @@ public function helper( $helper, $value = null, $name = null ) { $params = array_merge( $params, $helper ); } - if ( class_exists( 'Pods_Helpers' ) ) { - $value = Pods_Helpers::helper( $params, $this ); - } elseif ( is_callable( $params['helper'] ) ) { - $disallowed = array( - 'system', - 'exec', - 'popen', - 'eval', - 'preg_replace', - 'create_function', - 'include', - 'include_once', - 'require', - 'require_once', - ); + /** + * Allows changing whether callbacks are allowed to run. + * + * @param bool $allowed Whether callbacks are allowed to run. + * @param array $params Parameters used by Pods::helper() method. + * + * @since 2.8.0 + */ + $allow_callbacks = (boolean) apply_filters( 'pods_helper_allow_callbacks', true, $params ); - $allowed = array(); + if ( ! $allow_callbacks ) { + return $value; + } - /** - * Allows adjusting the disallowed callbacks as needed. - * - * @param array $disallowed List of callbacks not allowed. - * @param array $params Parameters used by Pods::helper() method. - * - * @since 2.7.0 - */ - $disallowed = apply_filters( 'pods_helper_disallowed_callbacks', $disallowed, $params ); + if ( ! is_callable( $params['helper'] ) ) { + return apply_filters( $params['helper'], $value ); + } - /** - * Allows adjusting the allowed allowed callbacks as needed. - * - * @param array $allowed List of callbacks explicitly allowed. - * @param array $params Parameters used by Pods::helper() method. - * - * @since 2.7.0 - */ - $allowed = apply_filters( 'pods_helper_allowed_callbacks', $allowed, $params ); + $disallowed = array( + 'system', + 'exec', + 'popen', + 'eval', + 'preg_replace', + 'preg_replace_array', + 'preg_replace_callback', + 'preg_replace_callback_array', + 'preg_match', + 'preg_match_all', + 'create_function', + 'include', + 'include_once', + 'require', + 'require_once', + ); - // Clean up helper callback (if string). - if ( is_string( $params['helper'] ) ) { - $params['helper'] = strip_tags( str_replace( array( '`', chr( 96 ) ), "'", $params['helper'] ) ); - } + $allowed = array(); - $is_allowed = false; + /** + * Allows adjusting the disallowed callbacks as needed. + * + * @param array $disallowed List of callbacks not allowed. + * @param array $params Parameters used by Pods::helper() method. + * + * @since 2.7.0 + */ + $disallowed = apply_filters( 'pods_helper_disallowed_callbacks', $disallowed, $params ); - if ( ! empty( $allowed ) ) { - if ( in_array( $params['helper'], $allowed, true ) ) { - $is_allowed = true; - } - } elseif ( ! in_array( $params['helper'], $disallowed, true ) ) { + /** + * Allows adjusting the allowed callbacks as needed. + * + * @param array $allowed List of callbacks explicitly allowed. + * @param array $params Parameters used by Pods::helper() method. + * + * @since 2.7.0 + */ + $allowed = apply_filters( 'pods_helper_allowed_callbacks', $allowed, $params ); + + // Clean up helper callback (if string). + if ( is_string( $params['helper'] ) ) { + $params['helper'] = strip_tags( str_replace( array( '`', chr( 96 ) ), "'", $params['helper'] ) ); + } + + $is_allowed = false; + + if ( ! empty( $allowed ) ) { + if ( in_array( $params['helper'], $allowed, true ) ) { $is_allowed = true; } + } elseif ( ! in_array( $params['helper'], $disallowed, true ) ) { + $is_allowed = true; + } - if ( $is_allowed ) { - $value = call_user_func( $params['helper'], $value ); - } - } else { - $value = apply_filters( $params['helper'], $value ); - }//end if + if ( $is_allowed ) { + $value = call_user_func( $params['helper'], $value ); + } return $value; } @@ -3802,7 +3494,7 @@ public function helper( $helper, $value = null, $name = null ) { * @return mixed Template output * * @since 2.0.0 - * @link https://pods.io/docs/template/ + * @link https://docs.pods.io/code/pods/template/ */ public function template( $template_name, $code = null, $deprecated = false ) { @@ -3810,7 +3502,9 @@ public function template( $template_name, $code = null, $deprecated = false ) { $obj =& $this; - if ( ! empty( $code ) ) { + if ( class_exists( 'Pods_Templates' ) ) { + $out = Pods_Templates::template( $template_name, $code, $this, $deprecated ); + } elseif ( ! empty( $code ) ) { // backwards compatibility. $code = str_replace( '$this->', '$obj->', $code ); @@ -3868,8 +3562,15 @@ public function template( $template_name, $code = null, $deprecated = false ) { * @param Pods $pod Pods object. */ $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this ); - } elseif ( class_exists( 'Pods_Templates' ) ) { - $out = Pods_Templates::template( $template_name, $code, $this, $deprecated ); + + /** + * Filter the final template output. + * + * @param string $out Template output. + * @param string $code Template code. + * @param Pods $pod Pods object. + */ + $out = apply_filters( 'pods_templates_do_template', $out, $code, $this ); } elseif ( trim( preg_replace( '/[^a-zA-Z0-9_\-\/]/', '', $template_name ), ' /-' ) === $template_name ) { ob_start(); @@ -3918,7 +3619,16 @@ public function template( $template_name, $code = null, $deprecated = false ) { $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this ); }//end if - return $out; + /** + * Filter the final content. + * + * @since 2.8.0 + * + * @param string $out The template content. + * @param string $code The original template code. + * @param Pods $pod The current Pods object. + */ + return apply_filters( 'pods_template_content', $out, $code, $this ); } /** @@ -3932,15 +3642,52 @@ public function template( $template_name, $code = null, $deprecated = false ) { * * @return bool|mixed * @since 2.0.0 - * @link https://pods.io/docs/form/ + * @link https://docs.pods.io/code/pods/form/ */ public function form( $params = null, $label = null, $thank_you = null ) { + // Check for anonymous submissions. + if ( ! is_user_logged_in() ) { + $session_auto_start = pods_session_auto_start(); + + // Check if Pods sessions are disabled. + if ( false === $session_auto_start ) { + return sprintf( + '%1$s %2$s, %4$s %5$s.', + esc_html__( 'Error', 'pods' ), + esc_html__( 'Anonymous form submissions are not enabled for this site', 'pods' ), + esc_url( wp_login_url( pods_current_url() ) ), + esc_html__( 'try logging in first', 'pods' ), + esc_html__( 'contacting your site administrator', 'pods' ) + ); + } + + // Check if we need to turn on sessions and have visitor refresh page. + if ( 'auto' === $session_auto_start ) { + pods_update_setting( 'pods_session_auto_start', '1' ); + + return sprintf( + '%1$s %2$s', + esc_html__( 'Error', 'pods' ), + esc_html__( 'Please refresh the page to access this form.', 'pods' ) + ); + } + + // Check if the session started properly. + if ( '' === pods_session_id() ) { + return sprintf( + '%1$s %2$s', + esc_html__( 'Error', 'pods' ), + esc_html__( 'Anonymous form submissions are not compatible with sessions on this site.', 'pods' ) + ); + } + } $defaults = array( 'fields' => $params, 'label' => $label, 'thank_you' => $thank_you, 'fields_only' => false, + 'output_type' => 'div', ); if ( is_array( $params ) ) { @@ -3953,41 +3700,41 @@ public function form( $params = null, $label = null, $thank_you = null ) { $params = $this->do_hook( 'form_params', $params ); - $fields = $params['fields']; + $form_fields = $params['fields']; - if ( null !== $fields && ! is_array( $fields ) && 0 < strlen( $fields ) ) { - $fields = explode( ',', $fields ); + if ( null !== $form_fields && ! is_array( $form_fields ) && 0 < strlen( $form_fields ) ) { + $form_fields = explode( ',', $form_fields ); } - $object_fields = (array) pods_v( 'object_fields', $this->pod_data, array(), true ); + $all_fields = pods_config_get_all_fields( $this->pod_data ); - if ( empty( $fields ) ) { - // Add core object fields if $fields is empty. - $fields = array_merge( $object_fields, $this->fields ); - } + $default_form = false; - // Temporary. - $form_fields = $fields; + // Get all fields if form fields are empty. + if ( empty( $form_fields ) ) { + $form_fields = $all_fields; - $fields = array(); + $default_form = true; + } + + $fields = []; foreach ( $form_fields as $k => $field ) { $name = $k; - $defaults = array( + $defaults = [ 'name' => $name, - ); + ]; - if ( ! is_array( $field ) ) { + if ( is_string( $field ) ) { $name = $field; - $field = array( + $field = [ 'name' => $name, - ); + ]; } - // @codingStandardsIgnoreLine. - $field = array_merge( $defaults, $field ); + $field = pods_config_merge_data( $defaults, $field ); $field['name'] = trim( $field['name'] ); @@ -3998,12 +3745,20 @@ public function form( $params = null, $label = null, $thank_you = null ) { $field['name'] = trim( $name ); } - if ( isset( $object_fields[ $field['name'] ] ) ) { - // @codingStandardsIgnoreLine. - $field = array_merge( $object_fields[ $field['name'] ], $field ); - } elseif ( isset( $this->fields[ $field['name'] ] ) ) { - // @codingStandardsIgnoreLine. - $field = array_merge( $this->fields[ $field['name'] ], $field ); + $to_merge = pods_v( $field['name'], $all_fields ); + + if ( $to_merge ) { + $field = pods_config_merge_data( $to_merge, $field ); + } + + // Never show the ID field. + if ( $this->pod_data['field_id'] === $field['name'] ) { + continue; + } + + // Hide fields from default form. + if ( 1 === (int) pods_v( 'hide_in_default_form', $field ) ) { + continue; } if ( pods_v( 'hidden', $field, false, true ) ) { @@ -4015,11 +3770,11 @@ public function form( $params = null, $label = null, $thank_you = null ) { if ( empty( $this->id ) && null !== $default_value ) { $this->row_override[ $field['name'] ] = $default_value; } elseif ( ! empty( $this->id ) && null !== $value ) { - $this->row[ $field['name'] ] = $value; + $this->data->row[ $field['name'] ] = $value; } }//end foreach - // Cleanup. + // Cleanup before get_defined_vars(). unset( $form_fields ); $fields = $this->do_hook( 'form_fields', $fields, $params ); @@ -4032,6 +3787,7 @@ public function form( $params = null, $label = null, $thank_you = null ) { $thank_you = $params['thank_you']; $fields_only = $params['fields_only']; + $output_type = $params['output_type']; PodsForm::$form_counter ++; @@ -4079,47 +3835,45 @@ public function form( $params = null, $label = null, $thank_you = null ) { /** * Render a singular view for the Pod item content. * - * @param array|string|null $fields (optional) Fields to show in the view, defaults to all fields. + * @param array|string|null $view_fields (optional) Fields to show in the view, defaults to all fields. * * @return mixed * @since 2.3.10 */ - public function view( $fields = null ) { + public function view( $view_fields = null ) { $pod =& $this; // Convert comma separated list of fields to an array. - if ( null !== $fields && ! is_array( $fields ) && 0 < strlen( $fields ) ) { - $fields = explode( ',', $fields ); + if ( null !== $view_fields && ! is_array( $view_fields ) && 0 < strlen( $view_fields ) ) { + $view_fields = explode( ',', $view_fields ); } - $object_fields = (array) pods_v( 'object_fields', $this->pod_data, array(), true ); + $all_fields = pods_config_get_all_fields( $this->pod_data ); - if ( empty( $fields ) ) { - // Add core object fields if $fields is empty. - $fields = array_merge( $object_fields, $this->fields ); + // Get all fields if fields are empty. + if ( empty( $view_fields ) ) { + $view_fields = $all_fields; } - // Temporary. - $view_fields = $fields; - - $fields = array(); + $fields = []; foreach ( $view_fields as $name => $field ) { - $defaults = array( + $defaults = [ 'name' => $name, - ); + ]; - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $name = $field; - $field = array( + $field = [ 'name' => $name, - ); + ]; } - // @codingStandardsIgnoreLine. - $field = array_merge( $defaults, $field ); + $field = pods_config_merge_data( $defaults, $fields ); $field['name'] = trim( $field['name'] ); @@ -4127,24 +3881,22 @@ public function view( $fields = null ) { $field['name'] = trim( $name ); } - if ( isset( $object_fields[ $field['name'] ] ) ) { - // @codingStandardsIgnoreLine. - $field = array_merge( $field, $object_fields[ $field['name'] ] ); - } elseif ( isset( $this->fields[ $field['name'] ] ) ) { - // @codingStandardsIgnoreLine. - $field = array_merge( $this->fields[ $field['name'] ], $field ); + $to_merge = pods_v( $field['name'], $all_fields ); + + if ( $to_merge ) { + $field = pods_config_merge_data( $to_merge, $field ); } if ( pods_v( 'hidden', $field, false, true ) || 'hidden' === $field['type'] ) { continue; - } elseif ( ! PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $pod->id() ) ) { + } elseif ( ! pods_permission( $field ) ) { continue; } $fields[ $field['name'] ] = $field; }//end foreach - // Cleanup. + // Cleanup before get_defined_vars(). unset( $view_fields ); $output = pods_view( PODS_DIR . 'ui/front/view.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true ); @@ -4305,8 +4057,8 @@ public function ui( $options = null, $amend = false ) { $this->ui = $options; return pods_ui( $this ); - } elseif ( ! empty( $options ) || 'custom' !== pods_v( 'ui_style', $this->pod_data['options'], 'post_type', true ) ) { - $actions_enabled = pods_v( 'ui_actions_enabled', $this->pod_data['options'] ); + } elseif ( ! empty( $options ) || 'custom' !== pods_v( 'ui_style', $this->pod_data, 'post_type', true ) ) { + $actions_enabled = pods_v( 'ui_actions_enabled', $this->pod_data ); if ( ! empty( $actions_enabled ) ) { $actions_enabled = (array) $actions_enabled; @@ -4340,7 +4092,7 @@ public function ui( $options = null, $amend = false ) { 'export' => 'export', ); - if ( 1 === pods_v( 'ui_export', $this->pod_data['options'], 0 ) ) { + if ( 1 === pods_v( 'ui_export', $this->pod_data, 0 ) ) { unset( $actions_disabled['export'] ); } }//end if @@ -4397,7 +4149,7 @@ public function ui( $options = null, $amend = false ) { $manage['modified'] = $this->pod_data['fields']['modified']['label']; } - $manage_fields = (array) pods_v( 'ui_fields_manage', $this->pod_data['options'] ); + $manage_fields = (array) pods_v( 'ui_fields_manage', $this->pod_data ); if ( ! empty( $manage_fields ) ) { $manage_new = array(); @@ -4427,13 +4179,13 @@ public function ui( $options = null, $amend = false ) { $pod_name = $this->pod; $manage = apply_filters( "pods_admin_ui_fields_{$pod_name}", apply_filters( 'pods_admin_ui_fields', $manage, $this->pod, $this ), $this->pod, $this ); - $icon = pods_v( 'ui_icon', $this->pod_data['options'] ); + $icon = pods_v( 'ui_icon', $this->pod_data ); if ( ! empty( $icon ) ) { $icon = pods_image_url( $icon, '32x32' ); } - $filters = pods_v( 'ui_filters', $this->pod_data['options'] ); + $filters = pods_v( 'ui_filters', $this->pod_data ); if ( ! empty( $filters ) ) { $filters_new = array(); @@ -4469,7 +4221,7 @@ public function ui( $options = null, $amend = false ) { $ui['filters_enhanced'] = true; } - $reorder_field = pods_v( 'ui_reorder_field', $this->pod_data['options'] ); + $reorder_field = pods_v( 'ui_reorder_field', $this->pod_data ); if ( ! empty( $reorder_field ) && in_array( 'reorder', $actions_enabled, true ) && ! in_array( 'reorder', $actions_disabled, true ) && ( ( ! empty( $this->pod_data['object_fields'] ) && isset( $this->pod_data['object_fields'][ $reorder_field ] ) ) || isset( $this->pod_data['fields'][ $reorder_field ] ) ) ) { $ui['reorder'] = array( 'on' => $reorder_field ); @@ -4495,7 +4247,7 @@ public function ui( $options = null, $amend = false ) { ); } - $detail_url = pods_v( 'detail_url', $this->pod_data['options'] ); + $detail_url = pods_v( 'detail_url', $this->pod_data ); if ( 0 < strlen( $detail_url ) ) { $ui['actions_custom'] = array( @@ -4562,35 +4314,117 @@ private function do_hook( $name ) { * @since 2.0.0 */ public function __get( $name ) { - $name = (string) $name; - // PodsData vars. - if ( isset( $this->data->{$name} ) && 0 === strpos( $name, 'field_' ) ) { + // Handle PodsData properties. + $supported_pods_data = array( + 'rows', + 'row', + 'pagination', + 'page', + 'page_var', + 'search', + 'search_var', + 'search_mode', + 'api', + 'row_number', + 'params', + 'filters', + 'id', + 'limit', + 'offset', + 'total', + 'total_found', + 'sql', + ); + + if ( in_array( $name, $supported_pods_data, true ) ) { return $this->data->{$name}; } - if ( ! $this->deprecated ) { - require_once PODS_DIR . 'deprecated/classes/Pods.php'; + // Handle alias Pods\Whatsit\Pod properties. + $supported_pods_object = array( + 'pod' => 'name', + 'pod_id' => 'id', + 'fields' => 'fields', + 'detail_page' => 'detail_url', + 'detail_url' => 'detail_url', + ); - $this->deprecated = new Pods_Deprecated( $this ); + if ( isset( $supported_pods_object[ $name ] ) ) { + if ( ! is_object( $this->pod_data ) ) { + return null; + } + + return pods_v( $supported_pods_object[ $name ], $this->pod_data ); } - $var = null; + // Handle sending previously mapped PodsData properties directly to their correct place. + if ( 0 === strpos( $name, 'field_' ) ) { + if ( ! is_object( $this->pod_data ) ) { + return null; + } - $pod_class_exists = class_exists( 'Pod' ); + return pods_v( $name, $this->pod_data ); + } - if ( isset( $this->deprecated->{$name} ) ) { - if ( ! $pod_class_exists || Pod::$deprecated_notice ) { - pods_deprecated( "Pods->{$name}", '2.0' ); - } + return null; + } - $var = $this->deprecated->{$name}; - } elseif ( ! $pod_class_exists || Pod::$deprecated_notice ) { - pods_deprecated( "Pods->{$name}", '2.0' ); + /** + * Handle variables that have been deprecated and PodsData vars + * + * @param string $name Property name. + * @param mixed $value Property value. + * + * @since 2.8.0 + */ + public function __set( $name, $value ) { + $name = (string) $name; + + $supported_pods_data = array( + 'rows' => 'array', + 'row' => 'array', + 'pagination' => 'boolean', + 'page' => 'int', + 'page_var' => 'string', + 'search' => 'boolean', + 'search_var' => 'string', + 'search_mode' => 'string', + ); + + if ( isset( $supported_pods_data[ $name ] ) ) { + // Cast the value. + settype( $value, $supported_pods_data[ $name ] ); + + $this->data->{$name} = $value; } + } - return $var; + /** + * Handle variables that have been deprecated and PodsData vars + * + * @param string $name Property name. + * + * @return bool Whether the variable is set or not. + * + * @since 2.8.0 + */ + public function __isset( $name ) { + $value = $this->__get( $name ); + + return ( null !== $value ); + } + + /** + * Handle variables that have been deprecated and PodsData vars + * + * @param string $name Property name. + * + * @since 2.8.0 + */ + public function __unset( $name ) { + $this->__set( $name, null ); } /** @@ -4618,12 +4452,12 @@ public function __call( $name, $args ) { $this->deprecated = new Pods_Deprecated( $this ); } - $pod_class_exists = class_exists( 'Pod' ); + $pod_class_exists = class_exists( 'Deprecated_Pod' ); if ( method_exists( $this->deprecated, $name ) ) { return call_user_func_array( array( $this->deprecated, $name ), $args ); // @codingStandardsIgnoreLine - } elseif ( ! $pod_class_exists || Pod::$deprecated_notice ) { + } elseif ( ! $pod_class_exists || Deprecated_Pod::$deprecated_notice ) { pods_deprecated( "Pods::{$name}", '2.0' ); } diff --git a/classes/PodsAPI.php b/classes/PodsAPI.php index f93afbbe72..05eddf92dc 100644 --- a/classes/PodsAPI.php +++ b/classes/PodsAPI.php @@ -1,5 +1,12 @@ format = $format; - - pods_deprecated( 'pods_api( $pod, $format )', '2.0', 'pods_api( $pod )' ); - } - - $pod = pods_clean_name( $pod ); - - $pod = $this->load_pod( array( 'name' => $pod, 'table_info' => true ), false ); + $pod = pods_clean_name( $pod ); + $pod = $this->load_pod( [ 'name' => $pod ] ); - if ( ! empty( $pod ) ) { - $this->pod_data = $pod; - $this->pod = $pod['name']; - $this->pod_id = $pod['id']; - $this->fields = $pod['fields']; - } + if ( ! empty( $pod ) ) { + $this->pod_data = $pod; } } @@ -139,41 +103,77 @@ public function __construct( $pod = null, $format = null ) { * @param bool $strict (optional) Decides whether the previous saved meta should be deleted or not * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before * sending. - * @param array $fields (optional) The array of fields and their options, for further processing with + * @param array $fields (optional) The array of fields and their options, for further processing with. * - * @return bool|mixed + * @return int|string|false The object ID after saving, false if not saved. * * @since 2.0.0 */ - public function save_wp_object( $object_type, $data, $meta = array(), $strict = false, $sanitized = false, $fields = array() ) { - - if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) { + public function save_wp_object( $object_type, $data, $meta = [], $strict = false, $sanitized = false, $fields = [] ) { + if ( in_array( $object_type, [ 'post_type', 'media' ], true ) ) { $object_type = 'post'; - } - - if ( 'taxonomy' === $object_type ) { + } elseif ( 'taxonomy' === $object_type ) { $object_type = 'term'; } - $is_meta_object = in_array( $object_type, array( 'post', 'term', 'user', 'comment' ), true ); - if ( $sanitized ) { $data = pods_unsanitize( $data ); $meta = pods_unsanitize( $meta ); } - if ( $is_meta_object ) { - return call_user_func( array( $this, 'save_' . $object_type ), $data, $meta, $strict, false, $fields ); + if ( in_array( $object_type, [ 'post', 'term', 'user', 'comment' ], true ) ) { + return call_user_func( [ $this, 'save_' . $object_type ], $data, $meta, $strict, false, $fields ); } elseif ( 'settings' === $object_type ) { // Nothing to save if ( empty( $meta ) ) { return true; } - return $this->save_setting( pods_var( 'option_id', $data ), $meta, false ); + return $this->save_setting( pods_v( 'option_id', $data ), $meta, false ); } - return false; + /** + * Allow hooking in to support saving for custom object types. + * + * @since 2.8.0 + * + * @param int|string|false $object_id The object ID after saving, false if not saved. + * @param string $object_type The custom object type. + * @param array $data All object data to be saved + * @param array $meta Associative array of meta keys and values. + * @param bool $strict Decides whether the previous saved meta should be deleted or not. + * @param bool $sanitized Will unsanitize the data, should be passed if the data is sanitized before sending. + * @param array $fields The array of fields and their options, for further processing with. + */ + $object_id = apply_filters( 'pods_api_save_wp_object_for_custom_object_type', false, $object_type, $data, $meta, $strict, $sanitized, $fields ); + + if ( false === $object_id ) { + return $object_id; + } + + /** + * Allow hooking in to support saving meta using the meta fallback. + * + * @since 2.8.0 + * + * @param bool $use_meta_fallback Whether to support saving meta using the meta fallback. + * @param string $object_type The custom object type. + * @param array $data All object data to be saved + * @param array $meta Associative array of meta keys and values. + * @param bool $strict Decides whether the previous saved meta should be deleted or not. + * @param bool $sanitized Will unsanitize the data, should be passed if the data is sanitized before sending. + * @param array $fields The array of fields and their options, for further processing with. + */ + $use_meta_fallback = apply_filters( 'pods_api_save_wp_object_use_meta_fallback', false, $object_type, $data, $meta, $strict, $sanitized, $fields ); + + // Maybe use meta fallback for saving. + if ( $use_meta_fallback ) { + foreach ( $meta as $meta_key => $meta_value ) { + update_metadata( $object_type, $object_id, $meta_key, $meta_value ); + } + } + + return $object_id; } /** @@ -189,7 +189,7 @@ public function save_wp_object( $object_type, $data, $meta = array(), $strict = */ public function delete_wp_object( $object_type, $id, $force_delete = true ) { - if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) { + if ( in_array( $object_type, array( 'post_type', 'media' ), true ) ) { $object_type = 'post'; } @@ -201,7 +201,7 @@ public function delete_wp_object( $object_type, $id, $force_delete = true ) { return false; } - if ( in_array( $object_type, array( 'post' ) ) ) { + if ( in_array( $object_type, array( 'post' ), true ) ) { return wp_delete_post( $id, $force_delete ); } @@ -222,7 +222,7 @@ public function delete_wp_object( $object_type, $id, $force_delete = true ) { * sending. * @param array $fields (optional) The array of fields and their options, for further processing with * - * @return mixed|void + * @return mixed * * @since 2.0.0 */ @@ -235,7 +235,9 @@ public function save_post( $post_data, $post_meta = null, $strict = false, $sani } if ( ! is_array( $post_data ) || empty( $post_data ) ) { - $post_data = array( 'post_title' => '' ); + $post_data = [ + 'post_title' => '', + ]; } if ( ! is_array( $post_meta ) ) { @@ -306,7 +308,7 @@ public function save_post_meta( $id, $post_meta = null, $strict = false, $fields $meta = get_post_meta( $id ); foreach ( $meta as $k => $value ) { - if ( is_array( $value ) && 1 == count( $value ) ) { + if ( is_array( $value ) && 1 === count( $value ) ) { $meta[ $k ] = current( $value ); } } @@ -330,7 +332,7 @@ public function save_post_meta( $id, $post_meta = null, $strict = false, $fields if ( isset( $fields[ $meta_key ] ) ) { $field_data = $fields[ $meta_key ]; - $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) ); + $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects, true ) ); } if ( $simple ) { @@ -486,7 +488,7 @@ public function save_user_meta( $id, $user_meta = null, $strict = false, $fields if ( isset( $fields[ $meta_key ] ) ) { $field_data = $fields[ $meta_key ]; - $simple = ( 'pick' === $field_data['type'] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) ); + $simple = ( 'pick' === $field_data['type'] && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) ); } if ( $simple ) { @@ -690,7 +692,9 @@ public function save_term( $term_data, $term_meta, $strict = false, $sanitized = $conflicted = pods_no_conflict_check( 'taxonomy' ); if ( ! is_array( $term_data ) || empty( $term_data ) ) { - $term_data = array( 'name' => '' ); + $term_data = [ + 'name' => '', + ]; } if ( ! $conflicted ) { @@ -711,9 +715,13 @@ public function save_term( $term_data, $term_meta, $strict = false, $sanitized = unset( $term_data['taxonomy'] ); if ( empty( $term_data['term_id'] ) ) { - $term_name = $term_data['name']; + $term_name = ''; - unset( $term_data['name'] ); + if ( ! empty( $term_data['name'] ) ) { + $term_name = $term_data['name']; + + unset( $term_data['name'] ); + } $term_data['term_id'] = wp_insert_term( $term_name, $taxonomy, $term_data ); } elseif ( 1 < count( $term_data ) ) { @@ -803,7 +811,7 @@ public function save_term_meta( $id, $term_meta = null, $strict = false, $fields if ( isset( $fields[ $meta_key ] ) ) { $field_data = $fields[ $meta_key ]; - $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) ); + $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects, true ) ); } if ( $simple ) { @@ -942,7 +950,7 @@ public function rename_wp_object_type( $object_type, $old_name, $new_name ) { */ public function get_wp_object_fields( $object = 'post_type', $pod = null, $refresh = false ) { - $pod_name = pods_var_raw( 'name', $pod, $object, null, true ); + $pod_name = pods_v( 'name', $pod, $object, true ); if ( 'media' === $pod_name ) { $object = 'post_type'; @@ -959,483 +967,520 @@ public function get_wp_object_fields( $object = 'post_type', $pod = null, $refre return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod ); } - $fields = array(); + $fields = []; if ( 'post_type' === $object ) { - $fields = array( - 'ID' => array( - 'name' => 'ID', - 'label' => 'ID', - 'type' => 'number', - 'alias' => array( 'id' ), - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'post_title' => array( + $fields = [ + 'ID' => [ + 'name' => 'ID', + 'label' => 'ID', + 'type' => 'number', + 'alias' => [ 'id' ], + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + 'post_title' => [ 'name' => 'post_title', 'label' => 'Title', 'type' => 'text', - 'alias' => array( 'title', 'name' ), - 'options' => array( + 'alias' => [ 'title', 'name' ], + 'options' => [ 'display_filter' => 'the_title', - 'display_filter_args' => array( 'post_ID' ) - ) - ), - 'post_content' => array( + 'display_filter_args' => [ 'post_ID' ], + ], + ], + 'post_content' => [ 'name' => 'post_content', 'label' => 'Content', 'type' => 'wysiwyg', - 'alias' => array( 'content' ), - 'options' => array( + 'alias' => [ 'content' ], + 'options' => [ 'wysiwyg_allowed_html_tags' => '', 'display_filter' => 'the_content', - 'pre_save' => 0 - ) - ), - 'post_excerpt' => array( + 'pre_save' => 0, + ], + ], + 'post_excerpt' => [ 'name' => 'post_excerpt', 'label' => 'Excerpt', 'type' => 'paragraph', - 'alias' => array( 'excerpt' ), - 'options' => array( + 'alias' => [ 'excerpt' ], + 'options' => [ 'paragraph_allow_html' => 1, 'paragraph_allowed_html_tags' => '', 'display_filter' => 'the_excerpt', - 'pre_save' => 0 - ) - ), - 'post_author' => array( + 'pre_save' => 0, + ], + ], + 'post_author' => [ 'name' => 'post_author', 'label' => 'Author', 'type' => 'pick', - 'alias' => array( 'author' ), + 'alias' => [ 'author' ], 'pick_object' => 'user', - 'options' => array( + 'options' => [ 'pick_format_type' => 'single', 'pick_format_single' => 'autocomplete', - 'default_value' => '{@user.ID}' - ) - ), - 'post_date' => array( + 'default_value' => '{@user.ID}', + ], + ], + 'post_date' => [ 'name' => 'post_date', 'label' => 'Publish Date', 'type' => 'datetime', - 'alias' => array( 'created', 'date' ) - ), - 'post_date_gmt' => array( - 'name' => 'post_date_gmt', - 'label' => 'Publish Date (GMT)', - 'type' => 'datetime', - 'alias' => array(), - 'hidden' => true - ), - 'post_status' => array( + 'alias' => [ 'created', 'date' ], + ], + 'post_date_gmt' => [ + 'name' => 'post_date_gmt', + 'label' => 'Publish Date (GMT)', + 'type' => 'datetime', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'post_status' => [ 'name' => 'post_status', 'label' => 'Status', 'type' => 'pick', 'pick_object' => 'post-status', - 'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ), - 'alias' => array( 'status' ) - ), - 'comment_status' => array( + 'default' => $this->do_hook( 'default_status_' . $pod_name, pods_v( 'default_status', pods_v( 'options', $pod ), 'draft', true ), $pod ), + 'alias' => [ 'status' ], + ], + 'comment_status' => [ 'name' => 'comment_status', 'label' => 'Comment Status', 'type' => 'text', 'default' => get_option( 'default_comment_status', 'open' ), - 'alias' => array(), - 'data' => array( + 'alias' => [], + 'data' => [ 'open' => __( 'Open', 'pods' ), - 'closed' => __( 'Closed', 'pods' ) - ) - ), - 'ping_status' => array( - 'name' => 'ping_status', - 'label' => 'Ping Status', - 'default' => get_option( 'default_ping_status', 'open' ), - 'type' => 'text', - 'alias' => array(), - 'data' => array( + 'closed' => __( 'Closed', 'pods' ), + ], + ], + 'ping_status' => [ + 'name' => 'ping_status', + 'label' => 'Ping Status', + 'default' => get_option( 'default_ping_status', 'open' ), + 'type' => 'text', + 'alias' => [], + 'data' => [ 'open' => __( 'Open', 'pods' ), - 'closed' => __( 'Closed', 'pods' ) - ) - ), - 'post_password' => array( + 'closed' => __( 'Closed', 'pods' ), + ], + 'hide_in_default_form' => true, + ], + 'post_password' => [ 'name' => 'post_password', 'label' => 'Password', 'type' => 'password', - 'alias' => array() - ), - 'post_name' => array( + 'alias' => [], + ], + 'post_name' => [ 'name' => 'post_name', 'label' => 'Permalink', 'type' => 'slug', - 'alias' => array( 'slug', 'permalink' ) - ), - 'to_ping' => array( - 'name' => 'to_ping', - 'label' => 'To Ping', - 'type' => 'text', - 'alias' => array(), - 'hidden' => true - ), - 'pinged' => array( - 'name' => 'pinged', - 'label' => 'Pinged', - 'type' => 'text', - 'alias' => array(), - 'hidden' => true - ), - 'post_modified' => array( - 'name' => 'post_modified', - 'label' => 'Last Modified Date', - 'type' => 'datetime', - 'alias' => array( 'modified' ), - 'hidden' => true - ), - 'post_modified_gmt' => array( - 'name' => 'post_modified_gmt', - 'label' => 'Last Modified Date (GMT)', - 'type' => 'datetime', - 'alias' => array(), - 'hidden' => true - ), - 'post_content_filtered' => array( - 'name' => 'post_content_filtered', - 'label' => 'Content (filtered)', - 'type' => 'paragraph', - 'alias' => array(), - 'hidden' => true, - 'options' => array( + 'alias' => [ 'slug', 'permalink' ], + ], + 'to_ping' => [ + 'name' => 'to_ping', + 'label' => 'To Ping', + 'type' => 'text', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'pinged' => [ + 'name' => 'pinged', + 'label' => 'Pinged', + 'type' => 'text', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'post_modified' => [ + 'name' => 'post_modified', + 'label' => 'Last Modified Date', + 'type' => 'datetime', + 'alias' => [ 'modified' ], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'post_modified_gmt' => [ + 'name' => 'post_modified_gmt', + 'label' => 'Last Modified Date (GMT)', + 'type' => 'datetime', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'post_content_filtered' => [ + 'name' => 'post_content_filtered', + 'label' => 'Content (filtered)', + 'type' => 'paragraph', + 'alias' => [], + 'hidden' => true, + 'options' => [ 'paragraph_allow_html' => 1, 'paragraph_oembed' => 1, 'paragraph_wptexturize' => 1, 'paragraph_convert_chars' => 1, 'paragraph_wpautop' => 1, 'paragraph_allow_shortcode' => 1, - 'paragraph_allowed_html_tags' => '' - ) - ), - 'post_parent' => array( + 'paragraph_allowed_html_tags' => '', + ], + 'hide_in_default_form' => true, + ], + 'post_parent' => [ 'name' => 'post_parent', 'label' => 'Parent', 'type' => 'pick', 'pick_object' => 'post_type', 'pick_val' => '__current__', - 'alias' => array( 'parent' ), - 'data' => array(), - 'hidden' => true - ), - 'guid' => array( - 'name' => 'guid', - 'label' => 'GUID', - 'type' => 'text', - 'alias' => array(), - 'hidden' => true - ), - 'menu_order' => array( + 'alias' => [ 'parent' ], + 'data' => [], + 'hidden' => true, + ], + 'guid' => [ + 'name' => 'guid', + 'label' => 'GUID', + 'type' => 'text', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'menu_order' => [ 'name' => 'menu_order', 'label' => 'Menu Order', 'type' => 'number', - 'alias' => array(), - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'post_type' => array( - 'name' => 'post_type', - 'label' => 'Type', - 'type' => 'text', - 'alias' => array( 'type' ), - 'hidden' => true - ), - 'post_mime_type' => array( - 'name' => 'post_mime_type', - 'label' => 'Mime Type', - 'type' => 'text', - 'alias' => array(), - 'hidden' => true - ), - 'comment_count' => array( - 'name' => 'comment_count', - 'label' => 'Comment Count', - 'type' => 'number', - 'alias' => array(), - 'hidden' => true - ), - 'comments' => array( - 'name' => 'comments', - 'label' => 'Comments', - 'type' => 'comment', - 'pick_object' => 'comment', - 'pick_val' => 'comment', - 'alias' => array(), - 'hidden' => true, - 'options' => array( - 'comment_format_type' => 'multi' - ) - ) - ); + 'alias' => [], + 'options' => [ + 'number_format' => '9999.99', + ], + ], + 'post_type' => [ + 'name' => 'post_type', + 'label' => 'Type', + 'type' => 'text', + 'alias' => [ 'type' ], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'post_mime_type' => [ + 'name' => 'post_mime_type', + 'label' => 'Mime Type', + 'type' => 'text', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'comment_count' => [ + 'name' => 'comment_count', + 'label' => 'Comment Count', + 'type' => 'number', + 'alias' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'comments' => [ + 'name' => 'comments', + 'label' => 'Comments', + 'type' => 'comment', + 'pick_object' => 'comment', + 'pick_val' => 'comment', + 'alias' => [], + 'hidden' => true, + 'options' => [ + 'comment_format_type' => 'multi', + ], + 'hide_in_default_form' => true, + ], + ]; if ( ! empty( $pod ) ) { $taxonomies = get_object_taxonomies( $pod_name, 'objects' ); foreach ( $taxonomies as $taxonomy ) { - $fields[ $taxonomy->name ] = array( + $fields[ $taxonomy->name ] = [ 'name' => $taxonomy->name, 'label' => $taxonomy->labels->name, 'type' => 'taxonomy', 'pick_object' => 'taxonomy', 'pick_val' => $taxonomy->name, - 'alias' => array(), + 'alias' => [], 'hidden' => true, - 'options' => array( - 'taxonomy_format_type' => 'multi' - ) - ); + 'options' => [ + 'taxonomy_format_type' => 'multi', + ], + ]; } } } elseif ( 'user' === $object ) { - $fields = array( - 'ID' => array( - 'name' => 'ID', - 'label' => 'ID', - 'type' => 'number', - 'alias' => array( 'id' ), - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'user_login' => array( + $fields = [ + 'ID' => [ + 'name' => 'ID', + 'label' => 'ID', + 'type' => 'number', + 'alias' => [ 'id' ], + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + 'user_login' => [ 'name' => 'user_login', 'label' => 'Title', 'type' => 'text', - 'alias' => array( 'login' ), - 'options' => array( - 'required' => 1 - ) - ), - 'user_nicename' => array( + 'alias' => [ 'login' ], + 'options' => [ + 'required' => 1, + ], + ], + 'user_nicename' => [ 'name' => 'user_nicename', 'label' => 'Permalink', 'type' => 'slug', - 'alias' => array( 'nicename', 'slug', 'permalink' ) - ), - 'display_name' => array( + 'alias' => [ 'nicename', 'slug', 'permalink' ], + ], + 'display_name' => [ 'name' => 'display_name', 'label' => 'Display Name', 'type' => 'text', - 'alias' => array( 'title', 'name' ) - ), - 'user_pass' => array( + 'alias' => [ 'title', 'name' ], + ], + 'user_pass' => [ 'name' => 'user_pass', 'label' => 'Password', 'type' => 'text', - 'alias' => array( 'password', 'pass' ), - 'options' => array( + 'alias' => [ 'password', 'pass' ], + 'options' => [ 'required' => 1, - 'text_format_type' => 'password' - ) - ), - 'user_email' => array( + 'text_format_type' => 'password', + ], + ], + 'user_email' => [ 'name' => 'user_email', 'label' => 'E-mail', 'type' => 'text', - 'alias' => array( 'email' ), - 'options' => array( + 'alias' => [ 'email' ], + 'options' => [ 'required' => 1, - 'text_format_type' => 'email' - ) - ), - 'user_url' => array( + 'text_format_type' => 'email', + ], + ], + 'user_url' => [ 'name' => 'user_url', 'label' => 'URL', 'type' => 'text', - 'alias' => array( 'url', 'website' ), - 'options' => array( + 'alias' => [ 'url', 'website' ], + 'options' => [ 'required' => 0, 'text_format_type' => 'website', - 'text_format_website' => 'normal' - ) - ), - 'user_registered' => array( - 'name' => 'user_registered', - 'label' => 'Registration Date', - 'type' => 'date', - 'alias' => array( 'created', 'date', 'registered' ), - 'options' => array( - 'date_format_type' => 'datetime' - ) - ) - ); + 'text_format_website' => 'normal', + ], + ], + 'user_registered' => [ + 'name' => 'user_registered', + 'label' => 'Registration Date', + 'type' => 'date', + 'alias' => [ 'created', 'date', 'registered' ], + 'options' => [ + 'date_format_type' => 'datetime', + ], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + ]; } elseif ( 'comment' === $object ) { - $fields = array( - 'comment_ID' => array( - 'name' => 'comment_ID', - 'label' => 'ID', - 'type' => 'number', - 'alias' => array( 'id', 'ID', 'comment_id' ), - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'comment_content' => array( + $fields = [ + 'comment_ID' => [ + 'name' => 'comment_ID', + 'label' => 'ID', + 'type' => 'number', + 'alias' => [ 'id', 'ID', 'comment_id' ], + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + 'comment_content' => [ 'name' => 'comment_content', 'label' => 'Content', 'type' => 'wysiwyg', - 'alias' => array( 'content' ) - ), - 'comment_approved' => array( + 'alias' => [ 'content' ], + ], + 'comment_approved' => [ 'name' => 'comment_approved', 'label' => 'Approved', 'type' => 'number', - 'alias' => array( 'approved' ), - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'comment_post_ID' => array( + 'alias' => [ 'approved' ], + 'options' => [ + 'number_format' => '9999.99', + ], + ], + 'comment_post_ID' => [ 'name' => 'comment_post_ID', 'label' => 'Post', 'type' => 'pick', - 'alias' => array( 'post', 'post_id' ), - 'data' => array() - ), - 'user_id' => array( + 'alias' => [ 'post', 'post_id' ], + 'data' => [], + ], + 'user_id' => [ 'name' => 'user_id', 'label' => 'Author', 'type' => 'pick', - 'alias' => array( 'author' ), + 'alias' => [ 'author' ], 'pick_object' => 'user', - 'data' => array() - ), - 'comment_date' => array( + 'data' => [], + ], + 'comment_date' => [ 'name' => 'comment_date', 'label' => 'Date', 'type' => 'date', - 'alias' => array( 'created', 'date' ), - 'options' => array( - 'date_format_type' => 'datetime' - ) - ), - 'comment_author' => array( + 'alias' => [ 'created', 'date' ], + 'options' => [ + 'date_format_type' => 'datetime', + ], + ], + 'comment_author' => [ 'name' => 'comment_author', 'label' => 'Author', 'type' => 'text', - 'alias' => array( 'author' ) - ), - 'comment_author_email' => array( + 'alias' => [ 'author' ], + ], + 'comment_author_email' => [ 'name' => 'comment_author_email', 'label' => 'Author E-mail', 'type' => 'email', - 'alias' => array( 'author_email' ) - ), - 'comment_author_url' => array( + 'alias' => [ 'author_email' ], + ], + 'comment_author_url' => [ 'name' => 'comment_author_url', 'label' => 'Author URL', 'type' => 'text', - 'alias' => array( 'author_url' ) - ), - 'comment_author_IP' => array( - 'name' => 'comment_author_IP', - 'label' => 'Author IP', - 'type' => 'text', - 'alias' => array( 'author_IP' ) - ), - 'comment_type' => array( - 'name' => 'comment_type', - 'label' => 'Type', - 'type' => 'text', - 'alias' => array( 'type' ), - 'hidden' => true - ), - 'comment_parent' => array( - 'name' => 'comment_parent', - 'label' => 'Parent', - 'type' => 'pick', - 'pick_object' => 'comment', - 'pick_val' => '__current__', - 'alias' => array( 'parent' ), - 'data' => array(), - 'hidden' => true - ) - ); + 'alias' => [ 'author_url' ], + ], + 'comment_author_IP' => [ + 'name' => 'comment_author_IP', + 'label' => 'Author IP', + 'type' => 'text', + 'alias' => [ 'author_IP' ], + 'hide_in_default_form' => true, + ], + 'comment_type' => [ + 'name' => 'comment_type', + 'label' => 'Type', + 'type' => 'text', + 'alias' => [ 'type' ], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + 'comment_parent' => [ + 'name' => 'comment_parent', + 'label' => 'Parent', + 'type' => 'pick', + 'pick_object' => 'comment', + 'pick_val' => '__current__', + 'alias' => [ 'parent' ], + 'data' => [], + 'hidden' => true, + 'hide_in_default_form' => true, + ], + ]; } elseif ( 'taxonomy' === $object ) { - $fields = array( - 'term_id' => array( - 'name' => 'term_id', - 'label' => 'ID', - 'type' => 'number', - 'alias' => array( 'id', 'ID' ), - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'name' => array( + $fields = [ + 'term_id' => [ + 'name' => 'term_id', + 'label' => 'ID', + 'type' => 'number', + 'alias' => [ 'id', 'ID' ], + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + 'name' => [ 'name' => 'name', 'label' => 'Title', 'type' => 'text', - 'alias' => array( 'title' ) - ), - 'slug' => array( + 'alias' => [ 'title' ], + ], + 'slug' => [ 'name' => 'slug', 'label' => 'Permalink', 'type' => 'slug', - 'alias' => array( 'permalink' ) - ), - 'description' => array( + 'alias' => [ 'permalink' ], + ], + 'description' => [ 'name' => 'description', 'label' => 'Description', 'type' => 'wysiwyg', - 'alias' => array( 'content' ) - ), - 'taxonomy' => array( + 'alias' => [ 'content' ], + ], + 'taxonomy' => [ 'name' => 'taxonomy', 'label' => 'Taxonomy', 'type' => 'text', - 'alias' => array() - ), - 'parent' => array( + 'alias' => [], + ], + 'parent' => [ 'name' => 'parent', 'label' => 'Parent', 'type' => 'pick', 'pick_object' => 'taxonomy', 'pick_val' => '__current__', - 'alias' => array( 'parent' ), - 'data' => array(), - 'hidden' => true - ), - 'term_taxonomy_id' => array( - 'name' => 'term_taxonomy_id', - 'label' => 'Term Taxonomy ID', - 'type' => 'number', - 'alias' => array(), - 'hidden' => true, - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'term_group' => array( - 'name' => 'term_group', - 'label' => 'Term Group', - 'type' => 'number', - 'alias' => array( 'group' ), - 'hidden' => true, - 'options' => array( - 'number_format' => '9999.99' - ) - ), - 'count' => array( - 'name' => 'count', - 'label' => 'Count', - 'type' => 'number', - 'alias' => array(), - 'hidden' => true, - 'options' => array( - 'number_format' => '9999.99' - ) - ) - ); + 'alias' => [ 'parent' ], + 'data' => [], + 'hidden' => true, + ], + 'term_taxonomy_id' => [ + 'name' => 'term_taxonomy_id', + 'label' => 'Term Taxonomy ID', + 'type' => 'number', + 'alias' => [], + 'hidden' => true, + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + 'term_group' => [ + 'name' => 'term_group', + 'label' => 'Term Group', + 'type' => 'number', + 'alias' => [ 'group' ], + 'hidden' => true, + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + 'count' => [ + 'name' => 'count', + 'label' => 'Count', + 'type' => 'number', + 'alias' => [], + 'hidden' => true, + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + ]; + } elseif ( 'pod' === $object ) { + $fields = [ + 'id' => [ + 'name' => 'id', + 'label' => 'ID', + 'type' => 'number', + 'alias' => [ 'ID' ], + 'options' => [ + 'number_format' => '9999.99', + ], + 'hide_in_default_form' => true, + ], + ]; } $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod ); @@ -1457,7 +1502,7 @@ public function get_wp_object_fields( $object = 'post_type', $pod = null, $refre $fields = PodsForm::fields_setup( $fields ); if ( did_action( 'init' ) && pods_api_cache() ) { - pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields ); + pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields, WEEK_IN_SECONDS ); } return $fields; @@ -1476,6 +1521,7 @@ public function get_wp_object_fields( $object = 'post_type', $pod = null, $refre * $params['create_label_singular'] string Singular Label (for Creating) * $params['create_storage'] string Storage Type (for Creating Post Types) * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies) + * $params['create_rest_api'] int Whether REST API will be enabled (for Creating Post Types and Taxonomies) * $params['extend_pod_type'] string Pod Type (for Extending) * $params['extend_post_type'] string Post Type (for Extending Post Types) * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies) @@ -1497,6 +1543,7 @@ public function add_pod( $params ) { 'create_label_plural' => '', 'create_storage' => 'meta', 'create_storage_taxonomy' => '', + 'create_rest_api' => 1, 'create_setting_name' => '', 'create_label_title' => '', @@ -1511,7 +1558,7 @@ public function add_pod( $params ) { 'extend_storage_taxonomy' => '', ); - if( !function_exists( 'get_term_meta' ) ) { + if( ! function_exists( 'get_term_meta' ) ) { $defaults['create_storage_taxonomy'] = 'none'; $defaults['extend_storage_taxonomy' ] = 'table' ; } @@ -1539,18 +1586,16 @@ public function add_pod( $params ) { $label = $params->create_label_singular; } - $pod_params['name'] = $params->create_name; - $pod_params['label'] = ( ! empty( $params->create_label_plural ) ? $params->create_label_plural : $label ); - $pod_params['type'] = $params->create_pod_type; - $pod_params['options'] = array( - 'label_singular' => ( ! empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params['label'] ), - 'public' => 1, - 'show_ui' => 1 - ); + $pod_params['name'] = $params->create_name; + $pod_params['label'] = ( ! empty( $params->create_label_plural ) ? $params->create_label_plural : $label ); + $pod_params['type'] = $params->create_pod_type; + $pod_params['label_singular'] = ( ! empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params['label'] ); + $pod_params['public'] = 1; + $pod_params['show_ui'] = 1; // Auto-generate name if not provided - if ( empty( $pod_params['name'] ) && ! empty( $pod_params['options']['label_singular'] ) ) { - $pod_params['name'] = pods_clean_name( $pod_params['options']['label_singular'] ); + if ( empty( $pod_params['name'] ) && ! empty( $pod_params['label_singular'] ) ) { + $pod_params['name'] = pods_clean_name( $pod_params['label_singular'] ); } if ( 'post_type' === $pod_params['type'] ) { @@ -1563,6 +1608,8 @@ public function add_pod( $params ) { if ( pods_tableless() ) { $pod_params['storage'] = 'meta'; } + + $pod_params['rest_enable'] = 1 === (int) $params->create_rest_api ? 1 : 0; } elseif ( 'taxonomy' === $pod_params['type'] ) { if ( empty( $pod_params['name'] ) ) { return pods_error( __( 'Please enter a Name for this Pod', 'pods' ), $this ); @@ -1578,7 +1625,9 @@ public function add_pod( $params ) { $pod_params['storage'] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ); } - $pod_params['options']['hierarchical'] = 1; + $pod_params['hierarchical'] = 1; + + $pod_params['rest_enable'] = 1 === (int) $params->create_rest_api ? 1 : 0; } elseif ( 'pod' === $pod_params['type'] ) { if ( empty( $pod_params['name'] ) ) { return pods_error( __( 'Please enter a Name for this Pod', 'pod' ), $this ); @@ -1589,13 +1638,11 @@ public function add_pod( $params ) { $pod_params['storage'] = 'meta'; } } elseif ( 'settings' === $pod_params['type'] ) { - $pod_params['name'] = $params->create_setting_name; - $pod_params['label'] = ( ! empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) ); - $pod_params['options'] = array( - 'menu_name' => ( ! empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params['label'] ), - 'menu_location' => $params->create_menu_location - ); - $pod_params['storage'] = 'none'; + $pod_params['name'] = $params->create_setting_name; + $pod_params['label'] = ( ! empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) ); + $pod_params['menu_name'] = ( ! empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params['label'] ); + $pod_params['menu_location'] = $params->create_menu_location; + $pod_params['storage'] = 'none'; // Auto-generate name if not provided if ( empty( $pod_params['name'] ) && ! empty( $pod_params['label'] ) ) { @@ -1654,8 +1701,8 @@ public function add_pod( $params ) { return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params['name'] ), $this ); } - $pod_params['options']['supports_title'] = 1; - $pod_params['options']['supports_editor'] = 1; + $pod_params['supports_title'] = 1; + $pod_params['supports_editor'] = 1; } elseif ( 'taxonomy' === $pod_params['type'] ) { $check = get_taxonomy( $pod_params['name'] ); @@ -1681,56 +1728,101 @@ public function add_pod( $params ) { * $params['type'] string The Pod type * $params['object'] string The object being extended (if any) * $params['storage'] string The Pod storage - * $params['options'] array Options * $params['create_extend'] string Create or Extend a Content Type + * $params['order'] array List of group and field IDs to reorder * - * @param array $params An associative array of parameters - * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will - * sanitize them if false. - * @param bool|int $db (optional) Whether to save into the DB or just return Pod array. + * @param array|Pod $params An associative array of parameters + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will + * sanitize them if false. + * @param bool|int $db (optional) Whether to save into the DB or just return Pod array. + * + * @throws Exception * * @return int Pod ID * @since 1.7.9 */ public function save_pod( $params, $sanitized = false, $db = true ) { + if ( $params instanceof Pod ) { + $params = [ + 'id' => $params->get_id(), + 'pod' => $params, + ]; + } - $tableless_field_types = PodsForm::tableless_field_types(); - $simple_tableless_objects = PodsForm::simple_tableless_objects(); + $params = (object) $params; - $extend = ( is_array( $params ) && ! empty( $params['create_extend'] ) && 'extend' === $params['create_extend'] ); - unset( $params['create_extend'] ); + $extend = false; - $load_params = (object) $params; + if ( isset( $params->create_extend ) ) { + $extend = 'extend' === $params->create_extend; - if ( isset( $load_params->id ) && isset( $load_params->name ) ) { - unset( $load_params->name ); + unset( $params->create_extend ); } - if ( isset( $load_params->old_name ) ) { - $load_params->name = $load_params->old_name; + if ( isset( $params->pod ) && $params->pod instanceof Pod ) { + $pod = $params->pod; + + unset( $params->pod ); + } else { + $load_params = []; + + if ( ! empty( $params->id ) ) { + $load_params['id'] = $params->id; + } elseif ( ! empty( $params->old_name ) ) { + $load_params['name'] = $params->old_name; + } elseif ( ! empty( $params->name ) ) { + $load_params['name'] = $params->name; + } + + $pod = $this->load_pod( $load_params, false ); } - $load_params->table_info = true; + if ( $pod instanceof Pod ) { + $groups = $pod->get_groups(); - $pod = $this->load_pod( $load_params, false ); + $pod = $pod->get_args(); - $params = (object) $params; + $pod['groups'] = []; + + foreach ( $groups as $group ) { + $fields = $group->get_fields(); + + $pod['groups'][ $group->name ] = $group->get_args(); + + $pod['groups'][ $group->name ]['fields'] = []; + + foreach ( $fields as $field ) { + $pod['groups'][ $group->name ]['fields'][ $field->name ] = $field->get_args(); + } + } + } if ( false === $sanitized ) { $params = pods_sanitize( $params ); + + $sanitized = true; } $old_id = null; $old_name = null; $old_storage = null; - + $old_groups = array(); $old_fields = array(); - $old_options = array(); if ( isset( $params->name ) && ! isset( $params->object ) ) { $params->name = pods_clean_name( $params->name ); } + $params->overwrite = ! empty( $params->overwrite ) ? (boolean) $params->overwrite : false; + + $order_group_fields = null; + + if ( isset( $params->order ) ) { + $order_group_fields = $params->order; + + unset( $params->order ); + } + if ( ! empty( $pod ) ) { // Existing pod (update). @@ -1741,9 +1833,18 @@ public function save_pod( $params, $sanitized = false, $db = true ) { $params->id = $pod['id']; $old_name = $pod['name']; - $old_storage = $pod['storage']; - $old_fields = $pod['fields']; - $old_options = $pod['options']; + $old_storage = isset( $pod['storage'] ) ? $pod['storage'] : 'meta'; + $old_groups = isset( $pod['groups'] ) ? $pod['groups'] : []; + $old_fields = isset( $pod['fields'] ) ? $pod['fields'] : []; + + // Get group fields if we have groups. + if ( ! empty( $old_groups ) ) { + $old_fields = wp_list_pluck( array_values( $old_groups ), 'fields' ); + + if ( ! empty( $old_fields ) ) { + $old_fields = array_merge( ...$old_fields ); + } + } // Check if name is intentionally not set, set it as current name. if ( ! isset( $params->name ) ) { @@ -1763,16 +1864,16 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } if ( - in_array( $pod['type'], array( 'post_type', 'taxonomy' ), true ) - && ! empty( $pod['object'] ) - && $pod['object'] == $old_name + ! empty( $pod['object'] ) + && $pod['object'] === $old_name + && in_array( $pod['type'], array( 'post_type', 'taxonomy' ), true ) ) { return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this ); } } - if ( $old_id != $params->id ) { - if ( $params->type == $pod['type'] && isset( $params->object ) && $params->object == $pod['object'] ) { + if ( (int) $old_id !== (int) $params->id ) { + if ( $params->type === $pod['type'] && isset( $params->object ) && $params->object === $pod['object'] ) { return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this ); } else { return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this ); @@ -1781,6 +1882,10 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } else { // New pod (create). + if ( empty( $params->name ) ) { + return pods_error( __( 'Pod name is required', 'pods' ), $this ); + } + if ( in_array( $params->name, pods_reserved_keywords(), true ) && in_array( pods_v( 'type', $params ), array( 'post_type', 'taxonomy' ), true ) @@ -1811,15 +1916,13 @@ public function save_pod( $params, $sanitized = false, $db = true ) { 'storage' => 'table', 'object' => '', 'alias' => '', - 'options' => array(), - 'fields' => array(), + 'groups' => array(), ); } // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite) - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { - $pod['fields'] = array(); - $pod['options'] = array(); + if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || $params->overwrite ) { + $pod['groups'] = array(); } // Setup options @@ -1829,6 +1932,18 @@ public function save_pod( $params, $sanitized = false, $db = true ) { unset( $options['method'] ); } + if ( isset( $options['overwrite'] ) ) { + unset( $options['overwrite'] ); + } + + $pod = pods_config_merge_data( $pod, $options ); + + if ( is_array( $pod ) && isset( $pod['options'] ) ) { + $pod = array_merge( $pod, $pod['options'] ); + + unset( $pod['options'] ); + } + $options_ignore = array( 'object_type', 'object_name', @@ -1846,7 +1961,9 @@ public function save_pod( $params, $sanitized = false, $db = true ) { 'meta_field_value', 'pod_field_id', 'pod_field_index', + 'fields', 'object_fields', + 'groups', 'join', 'where', 'where_default', @@ -1860,7 +1977,12 @@ public function save_pod( $params, $sanitized = false, $db = true ) { 'developer_mode', 'dependency', 'depends-on', - 'excludes-on' + 'excludes-on', + 'is_new', + '_locale', + 'old_name', + 'parent', + 'group_id', ); foreach ( $options_ignore as $ignore ) { @@ -1878,8 +2000,17 @@ public function save_pod( $params, $sanitized = false, $db = true ) { 'storage', 'object', 'alias', - 'options', - 'fields' + 'fields', + 'weight', + 'parent', + 'group', + 'groups', + 'is_new', + '_locale', + 'old_name', + 'parent', + 'group_id', + 'post_status', ); foreach ( $exclude as $k => $exclude_field ) { @@ -1899,7 +2030,8 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } } - if ( pods_tableless() && ! in_array( $pod['type'], array( 'settings', 'table' ) ) ) { + // Enforce pod types and storage types. + if ( pods_tableless() && ! in_array( $pod['type'], array( 'settings', 'table' ), true ) ) { if ( 'pod' === $pod['type'] ) { $pod['type'] = 'post_type'; } @@ -1913,13 +2045,6 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } } - $pod['options']['type'] = $pod['type']; - $pod['options']['storage'] = $pod['storage']; - $pod['options']['object'] = $pod['object']; - $pod['options']['alias'] = $pod['alias']; - - $pod['options'] = array_merge( $pod['options'], $options ); - /** * @var WP_Query */ @@ -1935,19 +2060,15 @@ public function save_pod( $params, $sanitized = false, $db = true ) { $reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) ); } - if ( isset( $pod['options']['query_var_string'] ) ) { - if ( in_array( $pod['options']['query_var_string'], $reserved_query_vars ) ) { - $pod['options']['query_var_string'] = $pod['options']['type'] . '_' . $pod['options']['query_var_string']; - } + if ( isset( $pod['query_var_string'] ) && in_array( $pod['query_var_string'], $reserved_query_vars, true ) ) { + $pod['query_var_string'] = $pod['type'] . '_' . $pod['query_var_string']; } - if ( isset( $pod['options']['query_var'] ) ) { - if ( in_array( $pod['options']['query_var'], $reserved_query_vars ) ) { - $pod['options']['query_var'] = $pod['options']['type'] . '_' . $pod['options']['query_var']; - } + if ( isset( $pod['query_var'] ) && in_array( $pod['query_var'], $reserved_query_vars, true ) ) { + $pod['query_var'] = $pod['type'] . '_' . $pod['query_var']; } - if ( strlen( $pod['label'] ) < 1 ) { + if ( '' === $pod['label'] ) { $pod['label'] = $pod['name']; } @@ -1982,7 +2103,7 @@ public function save_pod( $params, $sanitized = false, $db = true ) { // Add new pod if ( empty( $params->id ) ) { - if ( strlen( $params->name ) < 1 ) { + if ( '' === $params->name ) { return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this ); } @@ -1991,65 +2112,82 @@ public function save_pod( $params, $sanitized = false, $db = true ) { 'post_title' => $pod['label'], 'post_content' => $pod['description'], 'post_type' => '_pods_pod', - 'post_status' => 'publish' + 'post_status' => 'publish', ); - if ( 'pod' === $pod['type'] && ( ! is_array( $pod['fields'] ) || empty( $pod['fields'] ) ) ) { - $pod['fields'] = array(); - - $pod['fields']['name'] = array( - 'name' => 'name', - 'label' => 'Name', - 'type' => 'text', - 'options' => array( - 'required' => '1' - ) - ); - - $pod['fields']['created'] = array( - 'name' => 'created', - 'label' => 'Date Created', - 'type' => 'datetime', - 'options' => array( - 'datetime_format' => 'ymd_slash', - 'datetime_time_type' => '12', - 'datetime_time_format' => 'h_mm_ss_A' - ) - ); - - $pod['fields']['modified'] = array( - 'name' => 'modified', - 'label' => 'Date Modified', - 'type' => 'datetime', - 'options' => array( - 'datetime_format' => 'ymd_slash', - 'datetime_time_type' => '12', - 'datetime_time_format' => 'h_mm_ss_A' - ) - ); - - $pod['fields']['author'] = array( - 'name' => 'author', - 'label' => 'Author', - 'type' => 'pick', - 'pick_object' => 'user', - 'options' => array( - 'pick_format_type' => 'single', - 'pick_format_single' => 'autocomplete', - 'default_value' => '{@user.ID}' - ) - ); + if ( ! is_array( $pod['groups'] ) || empty( $pod['groups'] ) ) { + $default_group_label = __( 'More Fields', 'pods' ); + $default_group_fields = []; + + // Advanced Content Types have default fields. + if ( 'pod' === $pod['type'] ) { + $default_group_label = __( 'Details', 'pods' ); + $default_group_fields = [ + 'name' => [ + 'name' => 'name', + 'label' => 'Name', + 'type' => 'text', + 'required' => '1', + ], + 'created' => [ + 'name' => 'created', + 'label' => 'Date Created', + 'type' => 'datetime', + 'datetime_format' => 'ymd_slash', + 'datetime_time_type' => '12', + 'datetime_time_format' => 'h_mm_ss_A', + ], + 'modified' => [ + 'name' => 'modified', + 'label' => 'Date Modified', + 'type' => 'datetime', + 'datetime_format' => 'ymd_slash', + 'datetime_time_type' => '12', + 'datetime_time_format' => 'h_mm_ss_A', + ], + 'author' => [ + 'name' => 'author', + 'label' => 'Author', + 'type' => 'pick', + 'pick_object' => 'user', + 'pick_format_type' => 'single', + 'pick_format_single' => 'autocomplete', + 'default_value' => '{@user.ID}', + ], + 'permalink' => [ + 'name' => 'permalink', + 'label' => 'Permalink', + 'type' => 'slug', + 'description' => 'Leave blank to auto-generate from Name', + ], + ]; + + if ( ! isset( $pod['pod_index'] ) ) { + $pod['pod_index'] = 'name'; + } + } - $pod['fields']['permalink'] = array( - 'name' => 'permalink', - 'label' => 'Permalink', - 'type' => 'slug', - 'description' => 'Leave blank to auto-generate from Name' - ); + /** + * Filter the title of the Pods Metabox used in the post editor. + * + * @since unknown + * + * @param string $title The title to use, default is 'More Fields'. + * @param array $pod The Pods config data. + * @param array $fields Array of fields that will go in the metabox. + * @param string $type The type of Pod. + * @param string $name Name of the Pod. + */ + $default_group_label = apply_filters( 'pods_meta_default_box_title', $default_group_label, $pod, $default_group_fields, $pod['type'], $pod['name'] ); + $default_group_name = sanitize_key( pods_js_name( sanitize_title( $default_group_label ) ) ); - if ( ! isset( $pod['options']['pod_index'] ) ) { - $pod['options']['pod_index'] = 'name'; - } + $pod['groups'] = [ + $default_group_name => [ + 'name' => $default_group_name, + 'label' => $default_group_label, + 'fields' => $default_group_fields, + ], + ]; } $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db ); @@ -2065,11 +2203,73 @@ public function save_pod( $params, $sanitized = false, $db = true ) { ); } - if ( true === $db ) { - if ( ! has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) ) { - add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 ); - } - + /** + * Allow filtering the Pod config data before saving the options. + * + * @since 2.8.0 + * + * @param array $pod The Pod config data to be used for saving groups/fields. + * @param object $params The list of parameters used to save this pod. + * @param bool $sanitized Whether the data was sanitized already. + * @param bool $db Whether to save the data to the database. + */ + $pod = apply_filters( 'pods_api_save_pod_config_data', $pod, $params, $sanitized, $db ); + + $meta = $pod; + + $excluded_meta = array( + 'id', + 'name', + 'label', + 'description', + 'weight', + 'options', + 'fields', + 'group', + 'groups', + 'object_fields', + 'object_type', + 'storage_type', + 'old_name', + ); + + foreach ( $excluded_meta as $meta_key ) { + if ( isset( $meta[ $meta_key ] ) ) { + unset( $meta[ $meta_key ] ); + } + } + + /** + * Allow filtering the Pod object data before saving. + * + * @since 2.8.0 + * + * @param array $post_data The Pod object data to be saved. + * @param array $pod The Pod config data. + * @param object $params The list of parameters used to save this pod. + * @param bool $sanitized Whether the data was sanitized already. + * @param bool $db Whether to save the data to the database. + */ + $post_data = apply_filters( 'pods_api_save_pod_post_data', $post_data, $pod, $params, $sanitized, $db ); + + /** + * Allow filtering the Pod config data before saving the options. + * + * @since 2.8.0 + * + * @param array $meta The Pod meta data to be saved. + * @param array $pod The Pod config data. + * @param object $params The list of parameters used to save this pod. + * @param bool $sanitized Whether the data was sanitized already. + * @param bool $db Whether to save the data to the database. + */ + $meta = apply_filters( 'pods_api_save_pod_meta_data', $meta, $pod, $params, $sanitized, $db ); + + if ( true === $db ) { + if ( ! has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) ) { + add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 ); + } + $conflicted = false; // Headway compatibility fix @@ -2079,7 +2279,7 @@ public function save_pod( $params, $sanitized = false, $db = true ) { $conflicted = true; } - $params->id = $this->save_wp_object( 'post', $post_data, $pod['options'], true, true ); + $params->id = $this->save_wp_object( 'post', $post_data, $meta, true, true ); if ( $conflicted ) { add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); @@ -2094,237 +2294,189 @@ public function save_pod( $params, $sanitized = false, $db = true ) { $pod['id'] = $params->id; - // Setup / update tables - if ( 'table' !== $pod['type'] && 'table' === $pod['storage'] && $old_storage !== $pod['storage'] && $db ) { - $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" ); + $all_fields = []; - $defined_fields = array(); + if ( ! empty( $pod['fields'] ) ) { + $all_fields = (array) $pod['fields']; + } elseif ( ! empty( $pod['groups'] ) ) { + $all_fields = wp_list_pluck( array_values( $pod['groups'] ), 'fields' ); - foreach ( $pod['fields'] as $field ) { - if ( ! is_array( $field ) || ! isset( $field['name'] ) || in_array( $field['name'], $defined_fields ) ) { - continue; - } + if ( ! empty( $all_fields ) ) { + $all_fields = array_merge( ...$all_fields ); + } else { + $all_fields = []; + } + } - $defined_fields[] = $field['name']; + // Maybe save the pod table schema. + if ( $db ) { + $old_info = compact( + 'old_storage', + 'old_name' + ); - if ( ! in_array( $field['type'], $tableless_field_types ) || ( 'pick' === $field['type'] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) { - $definition = $this->get_field_definition( $field['type'], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) ); + $this->save_pod_table_schema( $pod, $all_fields, $old_info ); + } - if ( 0 < strlen( $definition ) ) { - $definitions[] = "`{$field['name']}` " . $definition; - } - } - } + // Maybe handle renaming. + if ( $db && $pod['name'] !== $old_name ) { + $this->save_pod_handle_rename( $pod, $old_name ); + } - pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" ); + // Maybe sync built-in options for post type and taxonomies. + if ( $db && empty( $pod['object'] ) ) { + $this->save_pod_handle_sync_built_in( $pod ); + } - /** - * @todo Central function to fetch charset. - * @see PodsUpgrade::install() L64-L76 - */ - $charset_collate = 'DEFAULT CHARSET utf8'; + $saved = array(); + $errors = array(); - global $wpdb; - if ( ! empty( $wpdb->charset ) ) { - $charset_collate = "DEFAULT CHARSET {$wpdb->charset}"; - } + $id_required = false; - if ( ! empty( $wpdb->collate ) ) { - $charset_collate .= " COLLATE {$wpdb->collate}"; - } + // Save the object to the collection. + $object_collection = Pods\Whatsit\Store::get_instance(); - $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") {$charset_collate}", $this ); + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); - if ( empty( $result ) ) { - return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this ); - } + $object = $post_type_storage->to_object( $pod['id'], true ); - } elseif ( 'table' !== $pod['type'] && 'table' === $pod['storage'] && $pod['storage'] == $old_storage && null !== $old_name && $old_name !== $params->name && $db ) { - $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this ); + if ( ! $object ) { + $errors[] = __( 'Cannot save pod to collection', 'pods' ); + } - if ( empty( $result ) ) { - return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this ); - } + if ( ! empty( $errors ) ) { + return pods_error( $errors, $this ); } - /** - * @var $wpdb wpdb - */ - global $wpdb; - - if ( null !== $old_name && $old_name !== $params->name && $db ) { - // Rename items in the DB pointed at the old WP Object names - if ( 'post_type' === $pod['type'] && empty( $pod['object'] ) ) { - $this->rename_wp_object_type( 'post', $old_name, $params->name ); - } elseif ( 'taxonomy' === $pod['type'] && empty( $pod['object'] ) ) { - $this->rename_wp_object_type( 'taxonomy', $old_name, $params->name ); - } elseif ( 'comment' === $pod['type'] && empty( $pod['object'] ) ) { - $this->rename_wp_object_type( 'comment', $old_name, $params->name ); - } elseif ( 'settings' === $pod['type'] ) { - $this->rename_wp_object_type( 'settings', $old_name, $params->name ); - } + $field_index = pods_v( 'pod_index', $pod, 'id', true ); + $field_index_id = 0; + $field_index_change = false; - // Sync any related fields if the name has changed - $fields = pods_query( " - SELECT `p`.`ID` - FROM `{$wpdb->posts}` AS `p` - LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` - LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID` - WHERE - `p`.`post_type` = '_pods_field' - AND `pm`.`meta_key` = 'pick_object' - AND ( - `pm`.`meta_value` = 'pod' - OR `pm`.`meta_value` = '" . $pod['type'] . "' - ) - AND `pm2`.`meta_key` = 'pick_val' - AND `pm2`.`meta_value` = '{$old_name}' - " ); + if ( 'pod' === $pod['type'] && isset( $all_fields[ $field_index ] ) ) { + $field_index_id = $all_fields[ $field_index ]; - if ( ! empty( $fields ) ) { - foreach ( $fields as $field ) { - update_post_meta( $field->ID, 'pick_object', $pod['type'] ); - update_post_meta( $field->ID, 'pick_val', $params->name ); - } + if ( is_array( $field_index_id ) && ! empty( $field_index_id['id'] ) ) { + $field_index_id = $field_index_id['id']; } + } - $fields = pods_query( " - SELECT `p`.`ID` - FROM `{$wpdb->posts}` AS `p` - LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` - WHERE - `p`.`post_type` = '_pods_field' - AND `pm`.`meta_key` = 'pick_object' - AND ( - `pm`.`meta_value` = 'pod-{$old_name}' - OR `pm`.`meta_value` = '" . $pod['type'] . "-{$old_name}' - ) - " ); + $fields_to_save = []; - if ( ! empty( $fields ) ) { - foreach ( $fields as $field ) { - update_post_meta( $field->ID, 'pick_object', $pod['type'] ); - update_post_meta( $field->ID, 'pick_val', $params->name ); - } - } - } + if ( ! empty( $params->fields ) ) { + $params->fields = (array) $params->fields; - // Sync built-in options for post types and taxonomies - if ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) && empty( $pod['object'] ) && $db ) { - // Build list of 'built_in' for later - $built_in = array(); + $weight = 0; - foreach ( $pod['options'] as $key => $val ) { - if ( false === strpos( $key, 'built_in_' ) ) { - continue; - } elseif ( false !== strpos( $key, 'built_in_post_types_' ) ) { - $built_in_type = 'post_type'; - } elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) ) { - $built_in_type = 'taxonomy'; - } else { - continue; - } + // Handle weight of fields. + foreach ( $params->fields as $field ) { + $is_field_object = $field instanceof Field; - if ( $built_in_type == $pod['type'] ) { + if ( ! $is_field_object && ! is_array( $field ) && empty( $field['name'] ) ) { continue; } - if ( ! isset( $built_in[ $built_in_type ] ) ) { - $built_in[ $built_in_type ] = array(); - } + if ( ! isset( $field['weight'] ) ) { + $field['weight'] = $weight; - $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key ); + $weight ++; + } - $built_in[ $built_in_type ][ $built_in_object ] = (int) $val; + $fields_to_save[ $field['name'] ] = $field; } + } elseif ( ! empty( $params->groups ) ) { + $params->groups = (array) $params->groups; - $lookup_option = false; - $lookup_built_in = false; + $group_weight = 0; - $lookup_name = $pod['name']; - - if ( 'post_type' === $pod['type'] ) { - $lookup_option = 'built_in_post_types_' . $lookup_name; - $lookup_built_in = 'taxonomy'; - } elseif ( 'taxonomy' === $pod['type'] ) { - $lookup_option = 'built_in_taxonomies_' . $lookup_name; - $lookup_built_in = 'post_type'; - } + // Handle saving of groups. + foreach ( $params->groups as $group ) { + if ( ! ( is_array( $group ) || $group instanceof Pods\Whatsit ) || ! isset( $group['name'] ) ) { + continue; + } - if ( ! empty( $lookup_option ) && ! empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) { - foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) { - $search_val = 1; + $group_to_save = $group; - if ( 1 == $val ) { - $search_val = 0; - } + // Normalize as an array if an object. + if ( $group instanceof Pods\Whatsit ) { + $group_to_save = $group->get_args(); + } - $query = "SELECT p.ID FROM {$wpdb->posts} AS p - LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}' - LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}' - LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = '' - WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}' - AND pm2.meta_id IS NOT NULL - AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )"; + if ( ! isset( $group_to_save['weight'] ) ) { + $group_to_save['weight'] = $group_weight; - $results = pods_query( $query ); + $group_weight ++; + } - if ( ! empty( $results ) ) { - foreach ( $results as $the_pod ) { - delete_post_meta( $the_pod->ID, $lookup_option ); + $group_to_save['pod'] = $object; + $group_to_save['overwrite'] = $params->overwrite; - add_post_meta( $the_pod->ID, $lookup_option, $val ); - } - } - } - } - } + $group_fields = []; - $saved = array(); - $errors = array(); + if ( isset( $group_to_save['fields'] ) ) { + $group_fields = $group_to_save['fields']; - $field_index_change = false; - $field_index_id = 0; + unset( $group_to_save['fields'] ); + } - $id_required = false; + $group['id'] = $this->save_group( $group_to_save, $sanitized, $db ); - $field_index = pods_var( 'pod_index', $pod['options'], 'id', null, true ); + if ( ! empty( $group_fields ) ) { + $weight = 0; - if ( 'pod' === $pod['type'] && ! empty( $pod['fields'] ) && isset( $pod['fields'][ $field_index ] ) ) { - $field_index_id = $pod['fields'][ $field_index ]; - } + // Handle weight of fields. + foreach ( $group_fields as $field ) { + $is_field_object = $field instanceof Field; - if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { - $fields = array(); + if ( ! $is_field_object && ! is_array( $field ) && empty( $field['name'] ) ) { + continue; + } - if ( isset( $params->fields ) ) { - $params->fields = (array) $params->fields; + // Set the parent. + $field['pod'] = $object; - $weight = 0; + if ( $group instanceof Pods\Whatsit ) { + $field['group'] = $group; + } else { + $field['group_id'] = $group['id']; + } - foreach ( $params->fields as $field ) { - if ( ! is_array( $field ) || ! isset( $field['name'] ) ) { - continue; - } + if ( ! isset( $field['weight'] ) ) { + $field['weight'] = $weight; - if ( ! isset( $field['weight'] ) ) { - $field['weight'] = $weight; + $weight ++; + } - $weight ++; + $fields_to_save[ $field['name'] ] = $field; } - - $fields[ $field['name'] ] = $field; } } + } + + if ( $fields_to_save || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ! empty( $params->overwrite ) ) { + $saved_field_ids = array(); + + $fields_to_save = $fields_to_save; $weight = 0; - $saved_field_ids = array(); + foreach ( $fields_to_save as $k => $field ) { + $is_field_object = $field instanceof Field; + + $is_field_ok = ( + is_array( $field ) + || $is_field_object + ); - foreach ( $pod['fields'] as $k => $field ) { - if ( ! empty( $old_id ) && ( ! is_array( $field ) || ! isset( $field['name'] ) || ! isset( $fields[ $field['name'] ] ) ) ) { + if ( + ! empty( $old_id ) + && ( + ! $is_field_ok + || ! isset( $field['name'], $fields_to_save[ $field['name'] ] ) + ) + ) { // Iterative change handling for setup-edit.php - if ( ! is_array( $field ) && isset( $old_fields[ $k ] ) ) { + if ( ! $is_field_ok && isset( $old_fields[ $k ] ) ) { $saved[ $old_fields[ $k ]['name'] ] = true; } @@ -2332,10 +2484,13 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } if ( ! empty( $old_id ) ) { - $field = array_merge( $field, $fields[ $field['name'] ] ); + $field_data = $fields_to_save[ $field['name'] ]; + + /** @noinspection SlowArrayOperationsInLoopInspection */ + $field = pods_config_merge_data( $field, $field_data ); } - $field['pod'] = $pod; + $field['pod_data'] = $object; if ( ! isset( $field['weight'] ) ) { $field['weight'] = $weight; @@ -2343,11 +2498,11 @@ public function save_pod( $params, $sanitized = false, $db = true ) { $weight ++; } - if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id ) { + if ( 0 < $field_index_id && (int) pods_v( 'id', $field ) === $field_index_id ) { $field_index_change = $field['name']; } - if ( 0 < pods_var( 'id', $field ) ) { + if ( 0 < pods_v( 'id', $field ) ) { $id_required = true; } @@ -2357,30 +2512,28 @@ public function save_pod( $params, $sanitized = false, $db = true ) { $field_data = $field; - $field = $this->save_field( $field_data, $field_table_operation, true, $db ); + $field = $this->save_field( $field_data, $field_table_operation, $sanitized, $db ); if ( true !== $db ) { - $pod['fields'][ $k ] = $field; + $fields_to_save[ $k ] = $field; $saved_field_ids[] = $field['id']; + } elseif ( ! empty( $field ) && 0 < $field ) { + $saved[ $field_data['name'] ] = true; + $saved_field_ids[] = $field; } else { - if ( ! empty( $field ) && 0 < $field ) { - $saved[ $field_data['name'] ] = true; - $saved_field_ids[] = $field; - } else { - $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data['name'] ); - } + $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data['name'] ); } } if ( true === $db ) { foreach ( $old_fields as $field ) { - if ( isset( $pod['fields'][ $field['name'] ] ) || isset( $saved[ $field['name'] ] ) || in_array( $field['id'], $saved_field_ids ) ) { + if ( isset( $fields_to_save[ $field['name'] ] ) || isset( $saved[ $field['name'] ] ) || in_array( $field['id'], $saved_field_ids ) ) { continue; } - if ( $field['id'] == $field_index_id ) { + if ( $field['id'] === (int) $field_index_id ) { $field_index_change = 'id'; - } elseif ( $field['name'] == $field_index ) { + } elseif ( $field['name'] === $field_index ) { $field_index_change = 'id'; } @@ -2398,6 +2551,10 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } } + if ( is_array( $order_group_fields ) && ! empty( $order_group_fields['groups'] ) ) { + $this->save_pod_group_field_order( $order_group_fields['groups'], $object, $db ); + } + $this->cache_flush_pods( $pod ); if ( ! empty( $errors ) ) { @@ -2432,7 +2589,7 @@ public function save_pod( $params, $sanitized = false, $db = true ) { && in_array( $pod['type'], array( 'post_type', 'taxonomy' - ) ) + ), true ) && empty( $pod['object'] ) ) { pods_init()->setup_content_types( true ); @@ -2446,175 +2603,1622 @@ public function save_pod( $params, $sanitized = false, $db = true ) { } /** - * Add or edit a field within a Pod + * Handle saving the pod table schema. * - * $params['id'] int Field ID (id OR pod_id+pod+name required) - * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required) - * $params['pod'] string Pod name (id OR pod_id+pod+name required) - * $params['name'] string Field name (id OR pod_id+pod+name required) - * $params['label'] string (optional) Field label - * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email, - * file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg) - * $params['pick_object'] string (optional) Related Object (for relationships) - * $params['pick_val'] string (optional) Related Object name (for relationships) - * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships) - * $params['weight'] int (optional) Order in which the field appears - * $params['options'] array (optional) Options + * @since 2.8.0 * - * @param array $params An associative array of parameters - * @param bool $table_operation (optional) Whether or not to handle table operations - * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, - * will sanitize them if false. - * @param bool|int $db (optional) Whether to save into the DB or just return field array. + * @param array $pod The pod configuration. + * @param array $fields The list of fields on the pod. + * @param array $old_info The old information to reference. * - * @return int|array The field ID or field array (if !$db) - * @since 1.7.9 + * @return bool|WP_Error True if the schema changes were handled, false or an error if it failed to create/update. + * + * @throws Exception */ - public function save_field( $params, $table_operation = true, $sanitized = false, $db = true ) { - - /** - * @var $wpdb wpdb - */ + public function save_pod_table_schema( $pod, array $fields, array $old_info ) { global $wpdb; - if ( true !== $db ) { - $table_operation = false; - } - $tableless_field_types = PodsForm::tableless_field_types(); $simple_tableless_objects = PodsForm::simple_tableless_objects(); - $params = (object) $params; - - if ( false === $sanitized ) { - $params = pods_sanitize( $params ); - } + $old_storage = $old_info['old_storage']; + $old_name = $old_info['old_name']; - if ( isset( $params->pod_id ) ) { - $params->pod_id = pods_absint( $params->pod_id ); + // Skip custom mapped table pods. + if ( 'table' === $pod['type'] || ! empty( $pod['table'] ) ) { + return; } - if ( true !== $db ) { - $params->pod_id = (int) $db; + // Skip if not using table storage. + if ( isset( $pod['storage'] ) && 'table' !== $pod['storage'] ) { + return; } - $pod = null; - $save_pod = false; - $id_required = false; + $table_name = "@wp_pods_{$pod['name']}"; + $old_table_name = "@wp_pods_{$old_name}"; - if ( isset( $params->id_required ) ) { - unset( $params->id_required ); + if ( $old_storage !== $pod['storage'] ) { + // Create the table if it wasn't there before. + $definitions = [ + '`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY', + ]; - $id_required = true; - } + $defined_fields = []; - if ( ( ! isset( $params->pod ) || empty( $params->pod ) ) && ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) ) { - return pods_error( __( 'Pod ID or name is required', 'pods' ), $this ); - } + foreach ( $fields as $field ) { + $is_field_object = $field instanceof Field; - if ( isset( $params->pod ) && is_array( $params->pod ) ) { - $pod = $params->pod; + // Skip if not a field, if an invalid field, or if already defined. + if ( + ! ( + is_array( $field ) + || $is_field_object + ) + || ! isset( $field['name'] ) + || in_array( $field['name'], $defined_fields, true ) + ) { + continue; + } - $save_pod = true; - } elseif ( ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) ) { - $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) ); - } elseif ( ! isset( $params->pod ) && ( true === $db || 0 < $db ) ) { - $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) ); - } elseif ( true === $db || 0 < $db ) { - $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) ); - } + $defined_fields[] = $field['name']; - if ( empty( $pod ) && true === $db ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } + $define_tableless_fields = false; - $params->pod_id = $pod['id']; - $params->pod = $pod['name']; - $params->pod_data = $pod; + // Skip if we are not defining tableless fields and it is a tableless field or not a simple tableless object. + if ( + ! $define_tableless_fields + && in_array( $field['type'], $tableless_field_types, true ) + && ( + 'pick' !== $field['type'] + || in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) + ) + ) { + continue; + } - $params->name = pods_clean_name( $params->name, true, ( 'meta' === $pod['storage'] ? false : true ) ); + $definition = $this->get_field_definition( $field['type'], $field ); - if ( ! isset( $params->id ) ) { - $params->id = 0; - } + if ( 0 < strlen( $definition ) ) { + $definitions[] = "`{$field['name']}` " . $definition; + } + } - if ( empty( $params->name ) ) { - return pods_error( __( 'Pod field name is required', 'pods' ), $this ); - } + // Drop the table if it already exists. + pods_query( "DROP TABLE IF EXISTS `{$table_name}`" ); - $field = $this->load_field( $params ); + /** + * @see PodsUpgrade::install() L64-L76 + * @todo Central function to fetch charset. + */ + $charset_collate = 'DEFAULT CHARSET utf8'; - unset( $params->pod_data ); + if ( ! empty( $wpdb->charset ) ) { + $charset_collate = "DEFAULT CHARSET {$wpdb->charset}"; + } - $old_id = null; - $old_name = null; - $old_type = null; - $old_definition = null; - $old_simple = null; - $old_options = null; - $old_sister_id = null; + if ( ! empty( $wpdb->collate ) ) { + $charset_collate .= " COLLATE {$wpdb->collate}"; + } - // @todo pods_reserved_keywords(); - $reserved_keywords = array( 'id', 'ID' ); + if ( empty( $definitions ) ) { + return pods_error( __( 'Cannot add Database Table for Pod, no table column definitions provided', 'pods' ), $this ); + } - if ( ! empty( $field ) ) { - $old_id = pods_var( 'id', $field ); - $old_name = pods_clean_name( $field['name'], true, ( 'meta' === $pod['storage'] ? false : true ) ); - $old_type = $field['type']; - $old_options = $field['options']; - $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 ); + $all_definitions = implode( ', ', $definitions ); - $old_simple = ( 'pick' === $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ); + $result = pods_query( "CREATE TABLE `{$table_name}` ({$all_definitions}) {$charset_collate}", $this ); - if ( isset( $params->name ) && ! empty( $params->name ) ) { - $field['name'] = $params->name; + if ( empty( $result ) ) { + return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this ); } + } elseif ( null !== $old_name && $old_name !== $pod['name'] ) { + // Rename the table. + $result = pods_query( "ALTER TABLE `{$old_table_name}` RENAME `{$table_name}`", $this ); - if ( $old_name !== $field['name'] ) { - if ( in_array( $field['name'], $reserved_keywords, true ) ) { - return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } - - if ( false !== $this->field_exists( $params ) ) { - return pods_error( sprintf( __( 'Field %1$s already exists, you cannot rename %2$s to that', 'pods' ), $field['name'], $old_name ), $this ); - } + if ( empty( $result ) ) { + return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this ); } + } + + /** + * Allow hooking after the table schema has been created or the table has been renamed. + * + * @since 2.8.0 + * + * @param array $pod The pod configuration. + * @param array $fields The list of fields on the pod. + * @param array $old_info The old information to reference. + */ + do_action( 'pods_api_save_pod_table_schema_after', $pod, $fields, $old_info ); + + return true; + } + + /** + * Handle saving the pod table schema. + * + * @since 2.8.0 + * + * @param array $pod The pod configuration. + * @param string $old_name The old pod name. + * + * @return bool Whether the pod was successfully renamed. + * + * @throws Exception + */ + public function save_pod_handle_rename( $pod, $old_name ) { + global $wpdb; + + $pod_name = sanitize_key( $pod['name'] ); + $pod_id = (int) $pod['id']; + $pod_type = pods_sanitize( $pod['type'] ); + $has_object = ! empty( $pod['object'] ); + $old_name = sanitize_key( $old_name ); + + // Skip if the name did not change. + if ( $pod_name === $old_name ) { + return false; + } + + // Skip if either name is empty. + if ( empty( $pod_name ) || empty( $old_name ) ) { + return false; + } + + // Rename items in the DB pointed at the old WP Object names. + if ( 'post_type' === $pod_type && ! $has_object ) { + $this->rename_wp_object_type( 'post', $old_name, $pod_name ); + } elseif ( 'taxonomy' === $pod_type && ! $has_object ) { + $this->rename_wp_object_type( 'taxonomy', $old_name, $pod_name ); + } elseif ( 'comment' === $pod_type && ! $has_object ) { + $this->rename_wp_object_type( 'comment', $old_name, $pod_name ); + } elseif ( 'settings' === $pod_type ) { + $this->rename_wp_object_type( 'settings', $old_name, $pod_name ); + } + + $fields_to_sync = []; + + // Sync any related fields if the name has changed + $fields_to_sync[] = pods_query( + " + SELECT `p`.`ID` + FROM `{$wpdb->posts}` AS `p` + LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` + LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID` + WHERE + `p`.`post_type` = '_pods_field' + AND `p`.`post_parent` != {$pod_id} + AND `pm`.`meta_key` = 'pick_object' + AND ( + `pm`.`meta_value` = 'pod' + OR `pm`.`meta_value` = '{$pod_type}' + ) + AND `pm2`.`meta_key` = 'pick_val' + AND `pm2`.`meta_value` = '{$old_name}' + " + ); + + $fields_to_sync[] = pods_query( + " + SELECT `p`.`ID` + FROM `{$wpdb->posts}` AS `p` + LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` + WHERE + `p`.`post_type` = '_pods_field' + AND `p`.`post_parent` != {$pod_id} + AND `pm`.`meta_key` = 'pick_object' + AND ( + `pm`.`meta_value` = 'pod-{$old_name}' + OR `pm`.`meta_value` = '{$pod_type}-{$old_name}' + ) + " + ); + + $fields_to_sync = array_merge( ...$fields_to_sync ); + $fields_to_sync = array_map( 'absint', $fields_to_sync ); + $fields_to_sync = array_unique( array_filter( $fields_to_sync ) ); + + // Update the field configurations for any related fields that changed. + if ( ! empty( $fields_to_sync ) ) { + foreach ( $fields_to_sync as $field_to_sync ) { + $found_field = $this->load_field( [ + 'id' => $field_to_sync->ID, + ] ); + + // Field not found. + if ( ! $found_field ) { + continue; + } + + // Save new location. + $found_field['pick_object'] = $pod_type; + $found_field['pick_val'] = $pod_name; + + $this->save_field( $found_field ); + } + } + + /** + * Allow hooking after the pod has been renamed. + * + * @since 2.8.0 + * + * @param array $pod The pod configuration. + * @param string $old_name The old pod name. + */ + do_action( 'pods_api_save_pod_handle_rename_after', $pod, $old_name ); + + return true; + } + + /** + * Handle syncing the built-in post type / taxonomy options. + * + * @since 2.8.0 + * + * @param array $pod The pod configuration. + * + * @return bool Whether the sync was successful. + */ + public function save_pod_handle_sync_built_in( $pod ) { + global $wpdb; + + if ( ! empty( $pod['object'] ) || ! in_array( $pod['type'], array( 'post_type', 'taxonomy' ), true ) ) { + return false; + } + + // Build list of 'built_in' for later. + $built_in = array(); + + $options = $pod; + + if ( is_object( $options ) ) { + $options = $pod->get_args(); + } + + foreach ( $options as $key => $val ) { + if ( false === strpos( $key, 'built_in_' ) ) { + continue; + } + + if ( false !== strpos( $key, 'built_in_post_types_' ) ) { + $built_in_type = 'post_type'; + } elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) ) { + $built_in_type = 'taxonomy'; + } else { + continue; + } + + // The built in type is the same as this pod type. + if ( $pod['type'] === $built_in_type ) { + continue; + } + + if ( ! isset( $built_in[ $built_in_type ] ) ) { + $built_in[ $built_in_type ] = array(); + } + + $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key ); + + $built_in[ $built_in_type ][ $built_in_object ] = (int) $val; + } + + $lookup_option = false; + $lookup_built_in = false; + + $lookup_name = $pod['name']; + + if ( 'post_type' === $pod['type'] ) { + $lookup_option = 'built_in_post_types_' . $lookup_name; + $lookup_built_in = 'taxonomy'; + } elseif ( 'taxonomy' === $pod['type'] ) { + $lookup_option = 'built_in_taxonomies_' . $lookup_name; + $lookup_built_in = 'post_type'; + } + + // The built in options were not found. + if ( empty( $lookup_option ) || empty( $lookup_built_in ) || ! isset( $built_in[ $lookup_built_in ] ) ) { + return false; + } + + foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) { + $search_val = 1; + + if ( 1 === (int) $val ) { + $search_val = 0; + } + + $built_in_object = pods_sanitize( $built_in_object ); + $lookup_option = pods_sanitize( $lookup_option ); + $lookup_built_in = pods_sanitize( $lookup_built_in ); + + $query = "SELECT p.ID FROM {$wpdb->posts} AS p + LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}' + LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}' + LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = '' + WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}' + AND pm2.meta_id IS NOT NULL + AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )"; + + $results = pods_query( $query ); + + if ( ! empty( $results ) ) { + foreach ( $results as $the_pod ) { + delete_post_meta( $the_pod->ID, $lookup_option ); + + add_post_meta( $the_pod->ID, $lookup_option, $val ); + } + } + } + + return true; + } + + /** + * Handle saving the groups/fields order for a pod. + * + * @since 2.8.0 + * + * @param array $groups List of group IDs and their fields to reorder. + * @param Pod $object The pod object. + * @param bool|int $db (optional) Whether to save into the DB or just return group array. + * + * @throws Exception + */ + public function save_pod_group_field_order( $groups, $object, $db = true ) { + $group_order = 0; + + foreach ( $groups as $group ) { + if ( ! is_array( $group ) || empty( $group['group_id'] ) ) { + continue; + } + + $group_id = (int) $group['group_id']; + + $this->save_group( [ + 'pod_data' => $object, + 'id' => $group_id, + 'weight' => $group_order, + ], false, $db ); + + $group_order ++; + + if ( empty( $group['fields'] ) ) { + continue; + } + + $group_field_order = 0; + + foreach ( $group['fields'] as $field_id ) { + $this->save_field( [ + 'pod_data' => $object, + 'id' => (int) $field_id, + 'new_group_id' => $group_id, + 'weight' => $group_field_order, + ], false, false, $db ); + + $group_field_order ++; + } + } + } + + /** + * Add field within a Pod + * + * $params['id'] int Field ID (id OR pod_id+pod+name required) + * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required) + * $params['pod'] string Pod name (id OR pod_id+pod+name required) + * $params['name'] string Field name (id OR pod_id+pod+name required) + * $params['label'] string (optional) Field label + * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email, + * file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg) + * $params['pick_object'] string (optional) Related Object (for relationships) + * $params['pick_val'] string (optional) Related Object name (for relationships) + * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships) + * $params['weight'] int (optional) Order in which the field appears + * + * @param array $params An associative array of parameters + * @param bool $table_operation (optional) Whether or not to handle table operations + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, + * will sanitize them if false. + * @param bool|int $db (optional) Whether to save into the DB or just return field array. + * + * @return int|array The field ID or field array (if !$db) + * + * @since 2.8.0 + */ + public function add_field( $params, $table_operation = true, $sanitized = false, $db = true ) { + $params = (object) $params; + + $params->is_new = true; + + return $this->save_field( $params, $table_operation, $sanitized, $db ); + } + + /** + * Add or edit a field within a Pod + * + * $params['id'] int Field ID (id OR pod_id+pod+name required) + * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required) + * $params['pod'] string Pod name (id OR pod_id+pod+name required) + * $params['name'] string Field name (id OR pod_id+pod+name required) + * $params['label'] string (optional) Field label + * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email, + * file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg) + * $params['pick_object'] string (optional) Related Object (for relationships) + * $params['pick_val'] string (optional) Related Object name (for relationships) + * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships) + * $params['weight'] int (optional) Order in which the field appears + * + * @param array|Field $params An associative array of parameters + * @param bool $table_operation (optional) Whether or not to handle table operations + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, + * will sanitize them if false. + * @param bool|int $db (optional) Whether to save into the DB or just return field array. + * + * @return int|array The field ID or field array (if !$db) + * @since 1.7.9 + */ + public function save_field( $params, $table_operation = true, $sanitized = false, $db = true ) { + if ( $params instanceof Field ) { + $params = [ + 'id' => $params->get_id(), + 'field' => $params, + ]; + } + + $params = (object) $params; + + $field = false; + + if ( isset( $params->field ) && $params->field instanceof Field ) { + $field = $params->field; + + $params->id = $field->get_id(); + + unset( $params->field ); + } + + /** + * @var $wpdb wpdb + */ + global $wpdb; + + if ( true !== $db ) { + $table_operation = false; + } + + $tableless_field_types = PodsForm::tableless_field_types(); + $simple_tableless_objects = PodsForm::simple_tableless_objects(); + + $pod = null; + $save_pod = false; + + if ( isset( $params->pod ) && $params->pod instanceof Pod ) { + $pod = $params->pod; + + $params->pod_id = $pod['id']; + $params->pod = $pod['name']; + } elseif ( isset( $params->pod_data ) ) { + $pod = $params->pod_data; + + unset( $params->pod_data ); + + $params->pod_id = $pod['id']; + $params->pod = $pod['name']; + + $save_pod = true; + } elseif ( isset( $params->pod_id ) ) { + $params->pod_id = pods_absint( $params->pod_id ); + } elseif ( true !== $db ) { + $params->pod_id = (int) $db; + } + + $group = null; + $new_group = null; + $group_identifier = null; + $new_group_identifier = null; + + if ( ! empty( $params->group_id ) ) { + $group_identifier = 'ID: ' . $params->group_id; + + $group = $this->load_group( [ + 'id' => $params->group_id, + 'pod' => $pod, + ] ); + } elseif ( ! empty( $params->group ) ) { + if ( $params->group instanceof Group ) { + $group = $params->group; + } else { + $group_identifier = 'Slug: ' . $params->group; + + $group = $this->load_group( [ + 'name' => $params->group, + 'pod' => $pod, + ] ); + } + } + + // Handle assigning to new groups. + if ( ! empty( $params->new_group_id ) ) { + $new_group_identifier = 'ID: ' . $params->new_group_id; + + $new_group = $this->load_group( [ + 'id' => $params->new_group_id, + 'pod' => $pod, + ] ); + + unset( $params->new_group_id ); + } elseif ( ! empty( $params->new_group ) ) { + if ( $params->new_group instanceof Group ) { + $new_group = $params->new_group; + } else { + $new_group_identifier = 'Slug: ' . $params->new_group; + + $new_group = $this->load_group( [ + 'name' => $params->new_group, + 'pod' => $pod, + ] ); + } + + unset( $params->new_group ); + } + + if ( $group instanceof Group ) { + $params->group_id = $group['id']; + $params->group = $group['name']; + } elseif ( false === $group ) { + return pods_error( sprintf( __( 'Group (%s) not found.', 'pods' ), $group_identifier ), $this ); + } + + if ( false === $new_group ) { + return pods_error( sprintf( __( 'New group (%s) not found.', 'pods' ), $new_group_identifier ), $this ); + } + + if ( false === $sanitized ) { + $params = pods_sanitize( $params ); + + $sanitized = true; + } + + $id_required = false; + + if ( isset( $params->id_required ) ) { + unset( $params->id_required ); + + $id_required = true; + } + + if ( ! $pod && ( ! isset( $params->pod ) || empty( $params->pod ) ) && ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) ) { + return pods_error( __( 'Pod ID or name is required', 'pods' ), $this ); + } + + if ( ! $pod ) { + if ( isset( $params->pod ) && ( is_array( $params->pod ) || $params->pod instanceof Pods\Whatsit ) ) { + $pod = $params->pod; + + $save_pod = true; + } elseif ( ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) ) { + $pod = $this->load_pod( array( 'name' => $params->pod ), false ); + } elseif ( ! isset( $params->pod ) && ( true === $db || 0 < $db ) ) { + $pod = $this->load_pod( array( 'id' => $params->pod_id ), false ); + } elseif ( true === $db || 0 < $db ) { + $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod ), false ); + } + } + + if ( empty( $pod ) && true === $db ) { + return pods_error( __( 'Pod not found', 'pods' ), $this ); + } + + $params->pod_id = $pod['id']; + $params->pod = $pod['name']; + + $params->is_new = isset( $params->is_new ) ? (boolean) $params->is_new : false; + + $reserved_keywords = pods_reserved_keywords(); + + if ( isset( $params->name ) ) { + $params->name = pods_clean_name( $params->name, true, 'meta' !== $pod['storage'] ); + + if ( $params->is_new && isset( $params->id ) ) { + $params->id = null; + } + } + + $field_obj = $field; + + if ( ! $field ) { + $load_params = [ + 'pod_id' => $params->pod_id, + ]; + + $fail_on_load = false; + + if ( ! empty( $params->id ) ) { + $load_params['id'] = $params->id; + + $fail_on_load = true; + } elseif ( ! empty( $params->old_name ) ) { + $load_params['name'] = $params->old_name; + + $fail_on_load = true; + } elseif ( ! empty( $params->name ) ) { + $load_params['name'] = $params->name; + } elseif ( ! empty( $params->label ) ) { + $load_params = false; + } else{ + return pods_error( __( 'Pod field name or label is required', 'pods' ), $this ); + } + + if ( $load_params ) { + $field_obj = $this->load_field( $load_params ); + + if ( $fail_on_load && ( empty( $field_obj ) || is_wp_error( $field_obj ) ) ) { + return $field_obj; + } + } + } + + if ( $field_obj ) { + $field = $field_obj->get_args(); + } + + if ( empty( $params->name ) ) { + if ( $field ) { + $params->name = $field['name']; + } elseif ( ! empty( $params->label ) ) { + $params->name = pods_clean_name( $params->label, true, 'meta' !== $pod['storage'] ); + } else { + return pods_error( __( 'Pod field name or label is required', 'pods' ), $this ); + } + } + + $old_id = null; + $old_name = null; + $old_type = null; + $old_definition = null; + $old_simple = null; + $old_options = null; + $old_sister_id = null; + $old_type_is_tableless = false; + + $act_safe_keywords = [ + 'name', + 'author', + 'permalink', + 'slug', + ]; + + $is_act = 'pod' === $pod->get_type(); + + if ( ! empty( $field ) ) { + $old_id = pods_v( 'id', $field ); + $old_name = pods_clean_name( $field['name'], true, 'meta' !== $pod['storage'] ); + $old_type = $field['type']; + $old_options = $field; + $old_sister_id = (int) pods_v( 'sister_id', $old_options, 0 ); + + $old_simple = ( 'pick' === $old_type && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ); + + if ( isset( $params->new_name ) && ! empty( $params->new_name ) ) { + $field['name'] = $params->new_name; + + unset( $params->new_name ); + } elseif ( isset( $params->name ) && ! empty( $params->name ) ) { + $field['name'] = $params->name; + } + + if ( $new_group && ( ! $group || $group->get_id() !== $new_group->get_id() ) ) { + $field['group'] = $new_group->get_id(); + } + + if ( $old_name !== $field['name'] || empty( $params->id ) || $old_id !== $params->id ) { + if ( + in_array( $field['name'], $reserved_keywords, true ) + && ( + ! $is_act + || ! in_array( $field['name'], $act_safe_keywords, true ) + ) + ) { + return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } + + if ( false !== $this->field_exists( $params, false ) ) { + return pods_error( sprintf( __( 'Field %1$s already exists, you cannot rename %2$s to that', 'pods' ), $field['name'], $old_name ), $this ); + } + } + + if ( ( $id_required || ! empty( $params->id ) ) && ( empty( $old_id ) || $old_id !== $params->id ) ) { + return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field['name'] ), $this ); + } + + if ( empty( $params->id ) ) { + $params->id = $old_id; + } + + $field_definition = false; + $old_type_is_tableless = in_array( $old_type, $tableless_field_types, true ); + + if ( $old_simple || ! $old_type_is_tableless ) { + $field_definition = $this->get_field_definition( $old_type, $old_options ); + } + + /** + * Allow filtering of the old field definition when saving updated field. + * + * @since 2.8.0 + * + * @param string|false $field_definition The SQL definition to use for the field's table column. + * @param string $type The field type. + * @param array $field The field data. + * @param bool $simple Whether the field is a simple tableless field. + * @param Pods\Whatsit\Field $field_obj The field object. + */ + $field_definition = apply_filters( 'pods_api_save_field_old_definition', $field_definition, $old_type, $field, $old_simple, $field_obj ); + + if ( ! empty( $field_definition ) ) { + $old_definition = "`{$old_name}` " . $field_definition; + } + } else { + $field = [ + 'id' => 0, + 'pod_id' => $params->pod_id, + 'name' => $params->name, + 'label' => $params->name, + 'description' => '', + 'type' => 'text', + 'pick_object' => '', + 'pick_val' => '', + 'sister_id' => '', + 'weight' => null, + 'options' => [], + ]; + + if ( $group ) { + $field['group'] = $group->get_id(); + } elseif ( $new_group ) { + $field['group'] = $new_group->get_id(); + } + } + + // Setup options + $options = get_object_vars( $params ); + + $options_ignore = [ + '_locale', + 'attributes', + 'dependency', + 'depends-on', + 'developer_mode', + 'excludes-on', + 'group', + 'group_id', + 'grouped', + 'is_new', + 'method', + 'object_type', + 'old_name', + 'parent', + 'pod_data', + 'sanitized', + 'storage_type', + 'table_info', + ]; + + foreach ( $options_ignore as $ignore ) { + if ( isset( $options[ $ignore ] ) ) { + unset( $options[ $ignore ] ); + } + } + + if ( isset( $options['method'] ) ) { + unset( $options['method'] ); + } elseif ( isset( $options['table_info'] ) ) { + unset( $options['table_info'] ); + } + + $exclude = [ + '_locale', + 'description', + 'group_id', + 'id', + 'is_new', + 'label', + 'name', + 'old_name', + 'options', + 'parent', + 'pick_object', + 'pick_val', + 'pod', + 'pod_id', + 'post_status', + 'sister_id', + 'type', + 'weight', + ]; + + foreach ( $exclude as $k => $exclude_field ) { + $aliases = array( $exclude_field ); + + if ( is_array( $exclude_field ) ) { + $aliases = array_merge( array( $k ), $exclude_field ); + $exclude_field = $k; + } + + foreach ( $aliases as $alias ) { + if ( isset( $options[ $alias ] ) ) { + $field[ $exclude_field ] = pods_trim( $options[ $alias ] ); + + unset( $options[ $alias ] ); + } + } + } + + if ( '' === $field['label'] ) { + $field['label'] = $field['name']; + } + + $type_is_tableless = in_array( $field['type'], $tableless_field_types, true ); + + if ( $type_is_tableless && 'pick' === $field['type'] ) { + // Clean up special drop-down in field editor and save out pick_val + $field['pick_object'] = pods_v( 'pick_object', $field, '', true ); + + if ( 0 === strpos( $field['pick_object'], 'pod-' ) ) { + $field['pick_val'] = pods_str_replace( 'pod-', '', $field['pick_object'], 1 ); + $field['pick_object'] = 'pod'; + } elseif ( 0 === strpos( $field['pick_object'], 'post_type-' ) ) { + $field['pick_val'] = pods_str_replace( 'post_type-', '', $field['pick_object'], 1 ); + $field['pick_object'] = 'post_type'; + } elseif ( 0 === strpos( $field['pick_object'], 'taxonomy-' ) ) { + $field['pick_val'] = pods_str_replace( 'taxonomy-', '', $field['pick_object'], 1 ); + $field['pick_object'] = 'taxonomy'; + } elseif ( 'table' === $field['pick_object'] && 0 < strlen( pods_v( 'pick_table', $field ) ) ) { + $field['pick_val'] = $field['pick_table']; + $field['pick_object'] = 'table'; + } elseif ( false === strpos( $field['pick_object'], '-' ) && ! in_array( $field['pick_object'], array( + 'pod', + 'post_type', + 'taxonomy' + ) ) ) { + $field['pick_val'] = ''; + } elseif ( 'custom-simple' === $field['pick_object'] ) { + $field['pick_val'] = ''; + } + } + + foreach ( $options as $o => $v ) { + $field[ $o ] = $v; + } + + // Check for strict mode (default: strict). + $strict_mode = ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT; + + $object_fields = (array) pods_v( 'object_fields', $pod, [], true ); + + if ( 0 < $old_id && ! $strict_mode ) { + $params->id = $old_id; + $field['id'] = $old_id; + } + + // Add new field + if ( ! isset( $params->id ) || empty( $params->id ) || empty( $field ) ) { + if ( $table_operation && $strict_mode && in_array( $field['name'], [ + 'created', + 'modified', + ], true ) && ! in_array( $field['type'], [ + 'date', + 'datetime', + ], true ) ) { + return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } + + if ( $table_operation && $strict_mode && 'author' === $field['name'] && 'pick' !== $field['type'] ) { + return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } + + if ( + in_array( $field['name'], $reserved_keywords, true ) + && ( + ! $is_act + || ! in_array( $field['name'], $act_safe_keywords, true ) + ) + ) { + return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } + + foreach ( $object_fields as $object_field => $object_field_opt ) { + if ( $object_field === $field['name'] || in_array( $field['name'], $object_field_opt['alias'], true ) ) { + return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name. Also consider what WordPress and Pods provide you built-in.', 'pods' ), $field['name'] ), $this ); + } + } + + // Reserved post_name values that can't be used as field names + if ( 'rss' === $field['name'] ) { + $field['name'] .= '2'; + } + + if ( 'slug' === $field['type'] && true === $db ) { + if ( in_array( $pod['type'], array( 'post_type', 'taxonomy', 'user' ) ) ) { + return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this ); + } + + $slug_field = get_posts( array( + 'post_type' => '_pods_field', + 'orderby' => 'menu_order', + 'order' => 'ASC', + 'posts_per_page' => 1, + 'post_parent' => $field['pod_id'], + 'meta_query' => array( + array( + 'key' => 'type', + 'value' => 'slug' + ) + ) + ) ); + + if ( ! empty( $slug_field ) ) { + return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this ); + } + } + + // Sink the new field to the bottom of the list + if ( null === $field['weight'] ) { + $field['weight'] = 0; + + $bottom_most_field = get_posts( array( + 'post_type' => '_pods_field', + 'orderby' => 'menu_order', + 'order' => 'DESC', + 'posts_per_page' => 1, + 'post_parent' => $field['pod_id'] + ) ); + + if ( ! empty( $bottom_most_field ) ) { + $field['weight'] = pods_absint( $bottom_most_field[0]->menu_order ) + 1; + } + } + + $field['weight'] = pods_absint( $field['weight'] ); + + $post_data = array( + 'post_name' => $field['name'], + 'post_title' => $field['label'], + 'post_content' => $field['description'], + 'post_type' => '_pods_field', + 'post_parent' => $field['pod_id'], + 'post_status' => 'publish', + 'menu_order' => $field['weight'] + ); + } else { + if ( in_array( $field['name'], array( 'id', 'ID' ) ) ) { + if ( null !== $old_name ) { + return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } else { + return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this ); + } + } + + if ( $strict_mode && null !== $old_name && $field['name'] !== $old_name ) { + if ( in_array( $field['name'], [ + 'created', + 'modified', + ] ) && ! in_array( $field['type'], [ + 'date', + 'datetime', + ] ) ) { + return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } + + if ( 'author' === $field['name'] && 'pick' !== $field['type'] ) { + return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } + } + + foreach ( $object_fields as $object_field => $object_field_opt ) { + if ( $object_field !== $field['name'] && ! in_array( $field['name'], $object_field_opt['alias'], true ) ) { + continue; + } + + if ( null !== $old_name ) { + return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + } else { + return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this ); + } + } + + $post_data = array( + 'ID' => $field['id'], + 'post_name' => $field['name'], + 'post_title' => $field['label'], + 'post_content' => $field['description'] + ); + + if ( null !== $field['weight'] ) { + $field['weight'] = pods_absint( $field['weight'] ); + + $post_data['menu_order'] = $field['weight']; + } + } + + $field_types = PodsForm::field_types_list(); + + if ( true === $db ) { + if ( ! has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) ) { + add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 ); + } + + $conflicted = false; + + // Headway compatibility fix + if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) { + remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); + + $conflicted = true; + } + + // Store the old field name + if ( $old_name && $old_name !== $post_data['post_name'] ) { + $field['old_name'] = $old_name; + } + + $meta = $field; + + $excluded_meta = array( + 'id', + 'name', + 'label', + 'description', + 'pod_id', + 'pod', + 'weight', + 'options', + 'fields', + 'groups', + 'object_fields', + 'object_type', + 'storage_type', + 'parent', + ); + + foreach ( $excluded_meta as $meta_key ) { + if ( isset( $meta[ $meta_key ] ) ) { + unset( $meta[ $meta_key ] ); + } + } + + // Get all field types except the current. + $field_types = array_diff( $field_types, [ $field['type'] ] ); + + $pattern = '/^(' . implode( '|', $field_types ) . ')_/'; + + // Filter meta that is not for the current field type. + $meta = array_filter( $meta, static function ( $value, $key ) use ( $pattern ) { + return 1 !== preg_match( $pattern, $key ); + }, ARRAY_FILTER_USE_BOTH ); + + $params->id = $this->save_wp_object( 'post', $post_data, $meta, true, true ); + + if ( $conflicted ) { + add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); + } + + if ( false === $params->id ) { + return pods_error( __( 'Cannot save Field', 'pods' ), $this ); + } + } else { + $params->id = $field['name']; + } + + $field['id'] = $params->id; + + $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ); + + $definition = false; + $field_definition = false; + + if ( $simple || ! $type_is_tableless ) { + $field_definition = $this->get_field_definition( $field['type'], $field ); + } + + /** + * Allow filtering of the field definition when saving field. + * + * @since 2.8.0 + * + * @param string|false $field_definition The SQL definition to use for the field's table column. + * @param string $type The field type. + * @param array $field The field data. + * @param bool $simple Whether the field is a simple tableless field. + * @param Pods\Whatsit\Field $field_obj The field object. + */ + $field_definition = apply_filters( 'pods_api_save_field_definition', $field_definition, $field['type'], $field, $simple, $field_obj ); + + if ( ! empty( $field_definition ) ) { + $definition = '`' . $field['name'] . '` ' . $field_definition; + } + + $has_definition = ! empty( $definition ); + $has_old_definition = ! empty( $old_definition ); + $simple_diff = $old_simple !== $simple; + $definition_diff = $old_definition !== $definition; + + $sister_id = (int) pods_v( 'sister_id', $field, 0 ); + + $definition_mode = 'bypass'; + + if ( $table_operation && 'table' === $pod['storage'] && ! pods_tableless() ) { + if ( ! empty( $old_id ) ) { + if ( ( ( $field['type'] !== $old_type ) || $simple_diff ) && ! $has_definition ) { + $definition_mode = 'drop'; + } elseif ( $has_definition ) { + if ( $simple_diff || $old_name !== $field['name'] || $definition_diff ) { + $definition_mode = 'add'; - if ( ( $id_required || ! empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) ) { - return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field['name'] ), $this ); + if ( $has_old_definition ) { + $definition_mode = 'change'; + } + } elseif ( $has_old_definition && $definition_diff ) { + $definition_mode = 'change'; + } + } + } elseif ( $has_definition ) { + $definition_mode = 'add'; + + if ( $has_old_definition ) { + $definition_mode = 'change'; + } } - if ( empty( $params->id ) ) { + if ( 'bypass' !== $definition_mode ) { + /** + * Allow hooking into before the table has been altered for any custom functionality needed. + * + * @since 2.7.17 + * + * @param string $definition_mode The definition mode used for the table field. + * @param Pods\Whatsit\Pod $pod The pod object. + * @param string $type The field type. + * @param array $field The field data. + * @param array $extra_info { + * Extra information about the field. + * + * @type bool $simple Whether the field is a simple tableless field. + * @type string $definition The field definition. + * @type null|string $old_name The old field name (if preexisting). + * @type null|string $old_definition The old field definition (if preexisting). + * @type null|array $old_options The old field options (if preexisting). + * @type Pods\Whatsit\Field $field_obj The field object. + * } + */ + do_action( 'pods_api_save_field_table_pre_alter', $definition_mode, $pod, $field['type'], $field, [ + 'simple' => $simple, + 'definition' => $definition, + 'old_name' => $old_name, + 'old_definition' => $old_definition, + 'old_options' => $old_options, + 'field_obj' => $field_obj, + ] ); + + if ( 'drop' === $definition_mode ) { + // Drop field column. + pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false ); + } elseif ( 'change' === $definition_mode ) { + // Change field column definition. + if ( $old_name && $old_name !== $field['name'] ) { + $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false ); + } else { + $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` MODIFY {$definition}", false ); + } + + if ( false === $test ) { + $definition_mode = 'add'; + } + } + + // If the old field doesn't exist, continue to add a new field + if ( 'add' === $definition_mode ) { + pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) ); + } + + /** + * Allow hooking into after the table has been altered for any custom functionality needed. + * + * @since 2.7.17 + * + * @param string $definition_mode The definition mode used for the table field. + * @param Pods\Whatsit\Pod $pod The pod object. + * @param string $type The field type. + * @param array $field The field object. + * @param array $extra_info { + * Extra information about the field. + * + * @type bool $simple Whether the field is a simple tableless field. + * @type string $definition The field definition. + * @type null|string $old_name The old field name (if preexisting). + * @type null|string $old_definition The old field definition (if preexisting). + * @type null|array $old_options The old field options (if preexisting). + * @type Pods\Whatsit\Field $field_obj The field object. + * } + */ + do_action( 'pods_api_save_field_table_altered', $definition_mode, $pod, $field['type'], $field, [ + 'simple' => $simple, + 'definition' => $definition, + 'old_name' => $old_name, + 'old_definition' => $old_definition, + 'old_options' => $old_options, + 'field_obj' => $field_obj, + ] ); + } + } + + if ( ! empty( $old_id ) && 'meta' === $pod['storage'] && $old_name !== $field['name'] && $pod['meta_table'] !== $pod['table'] ) { + $prepare = array( + $field['name'], + $old_name + ); + + // Users don't have a type + if ( ! empty( $pod['field_type'] ) ) { + $prepare[] = $pod['name']; + } + + $join_table = $pod['table']; + + // Taxonomies are the odd type out, terrible I know + if ( 'taxonomy' === $pod['type'] ) { + // wp_term_taxonomy has the 'taxonomy' field we need to limit by + $join_table = $wpdb->term_taxonomy; + } + + pods_query( " + UPDATE `{$pod[ 'meta_table' ]}` AS `m` + LEFT JOIN `{$join_table}` AS `t` + ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}` + SET + `m`.`{$pod[ 'meta_field_index' ]}` = %s + WHERE + `m`.`{$pod[ 'meta_field_index' ]}` = %s + " . ( ! empty( $pod['field_type'] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ), $prepare ); + } + + if ( $old_type_is_tableless && $field['type'] !== $old_type ) { + delete_post_meta( $old_sister_id, 'sister_id' ); + + if ( true === $db ) { + pods_query( " + DELETE pm + FROM {$wpdb->postmeta} AS pm + LEFT JOIN {$wpdb->posts} AS p + ON p.post_type = '_pods_field' + AND p.ID = pm.post_id + WHERE + p.ID IS NOT NULL + AND pm.meta_key = 'sister_id' + AND pm.meta_value = %d + ", array( + $params->id, + ) ); + + if ( pods_podsrel_enabled() ) { + pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false ); + + pods_query( ' + UPDATE `@wp_podsrel` + SET `related_field_id` = 0 + WHERE `field_id` = %d + ', array( + $old_sister_id, + ) ); + } + } + } elseif ( 0 < $sister_id ) { + update_post_meta( $sister_id, 'sister_id', $params->id ); + + if ( true === $db && pods_podsrel_enabled() ) { + pods_query( ' + UPDATE `@wp_podsrel` + SET `related_field_id` = %d + WHERE `field_id` = %d + ', array( + $params->id, + $sister_id, + ) ); + } + } elseif ( 0 < $old_sister_id ) { + delete_post_meta( $old_sister_id, 'sister_id' ); + + if ( true === $db && pods_podsrel_enabled() ) { + pods_query( ' + UPDATE `@wp_podsrel` + SET `related_field_id` = 0 + WHERE `field_id` = %d + ', array( + $old_sister_id, + ) ); + } + } + + if ( ! empty( $old_id ) && $old_name !== $field['name'] && true === $db ) { + pods_query( ' + UPDATE `@wp_postmeta` + SET `meta_value` = %s + WHERE + `post_id` = %d + AND `meta_key` = "pod_index" + AND `meta_value` = %s + ', array( + $field['name'], + $pod['id'], + $old_name, + ) ); + } + + $object_collection = Pods\Whatsit\Store::get_instance(); + + $storage_type = 'collection'; + + if ( true === $db ) { + $storage_type = $this->get_default_object_storage_type(); + } + + /** @var Pods\Whatsit\Storage $storage */ + $storage = $object_collection->get_storage_object( $storage_type ); + + $object = $storage->to_object( $field['id'], true ); + + if ( ! $object ) { + return pods_error( __( 'Cannot save field to collection', 'pods' ), $this ); + } + + if ( ! $save_pod ) { + $this->cache_flush_pods( $pod ); + } + + if ( true === $db ) { + return $params->id; + } else { + return $object; + } + } + + /** + * Add a Group within a Pod. + * + * @since 2.8.0 + * + * @param array $params { + * An associative array of parameters + * + * @type int|null $id The Group ID (id OR pod_id+name OR pod+name required). + * @type string|null $name The Group name (id OR pod_id+name OR pod+name required). + * @type int|null $pod_id The Pod ID (id OR pod_id+name OR pod+name required). + * @type string|null $pod The Pod name (id OR pod_id+name OR pod+name required). + * @type string|null $label The Group label. + * @type string|null $type The Group type. + * @type int|null $weight The order in which the Group appears. + * } + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, + * will sanitize them if false. + * @param bool|int $db (optional) Whether to save into the DB or just return group array. + * + * @return int|array The group ID or group array (if !$db) + * + * @throws \Exception + */ + public function add_group( $params, $sanitized = false, $db = true ) { + $params = (object) $params; + + $params->is_new = true; + + return $this->save_group( $params, $sanitized, $db ); + } + + /** + * Add or edit a Group within a Pod. + * + * @since 2.8.0 + * + * @param array|Group $params { + * An associative array of parameters + * + * @type int|null $id The Group ID (id OR pod_id+name OR pod+name required). + * @type string|null $name The Group name (id OR pod_id+name OR pod+name required). + * @type int|null $pod_id The Pod ID (id OR pod_id+name OR pod+name required). + * @type string|null $pod The Pod name (id OR pod_id+name OR pod+name required). + * @type string|null $label The Group label. + * @type string|null $type The Group type. + * @type int|null $weight The order in which the Group appears. + * @type bool $is_new Whether to try to add the group as a new group when passing name. + * @type bool $overwrite Whether to try to replace the existing group if name and no ID is passed. + * } + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, + * will sanitize them if false. + * @param bool|int $db (optional) Whether to save into the DB or just return group array. + * + * @return int|array The group ID or group array (if !$db) + * + * @throws \Exception + */ + public function save_group( $params, $sanitized = false, $db = true ) { + if ( $params instanceof Group ) { + $params = [ + 'id' => $params->get_id(), + 'group' => $params, + ]; + } + + $params = (object) $params; + + $pod = null; + $group = null; + + // Setup Pod if passed. + if ( isset( $params->pod_data ) && $params->pod_data instanceof Pod ) { + $pod = $params->pod_data; + + unset( $params->pod_data ); + + $params->pod = $pod->get_name(); + $params->pod_id = $pod->get_id(); + } elseif ( isset( $params->pod ) && $params->pod instanceof Pod ) { + $pod = $params->pod; + + $params->pod = $pod->get_name(); + $params->pod_id = $pod->get_id(); + } elseif ( isset( $params->pod ) && is_array( $params->pod ) ) { + $pod = $params->pod; + + $params->pod = $pod['name']; + $params->pod_id = $pod['id']; + } elseif ( isset( $params->pod_id ) ) { + $params->pod_id = pods_absint( $params->pod_id ); + } + + // Setup Group if passed. + if ( isset( $params->group ) && $params->group instanceof Group ) { + $group = $params->group; + + unset( $params->group ); + + $params->id = $group->get_id(); + } elseif ( isset( $params->group ) && is_array( $params->group ) ) { + $group = $params->group; + + unset( $params->group ); + + $params->id = $group['id']; + } elseif ( isset( $params->id ) ) { + $params->id = pods_absint( $params->id ); + } + + if ( false === $sanitized ) { + $params = pods_sanitize( $params ); + + $sanitized = true; + } + + $id_required = false; + + if ( isset( $params->id_required ) ) { + $id_required = (boolean) $params->id_required; + + unset( $params->id_required ); + } + + $params->is_new = isset( $params->is_new ) ? (boolean) $params->is_new : false; + $params->overwrite = isset( $params->overwrite ) ? (boolean) $params->overwrite : false; + + if ( ! $pod && ( ! isset( $params->pod ) || empty( $params->pod ) ) && ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) ) { + return pods_error( __( 'Pod ID or name is required', 'pods' ), $this ); + } + + if ( ! $pod ) { + if ( ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) ) { + $pod = $this->load_pod( array( 'name' => $params->pod ), false ); + } elseif ( ! isset( $params->pod ) && ( true === $db || 0 < $db ) ) { + $pod = $this->load_pod( array( 'id' => $params->pod_id ), false ); + } elseif ( true === $db || 0 < $db ) { + $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod ), false ); + } + } + + if ( empty( $pod ) && true === $db ) { + return pods_error( __( 'Pod not found', 'pods' ), $this ); + } + + $reserved_keywords = pods_reserved_keywords(); + + /** @var Pod $pod */ + $params->pod_id = $pod->get_id(); + $params->pod = $pod->get_name(); + + if ( isset( $params->name ) ) { + $params->name = pods_clean_name( $params->name, true, 'meta' !== $pod['storage'] ); + + if ( $params->is_new && isset( $params->id ) ) { + $params->id = null; + } + } + + if ( empty( $params->name ) && empty( $params->id ) ) { + return pods_error( __( 'Pod group name is required', 'pods' ), $this ); + } + + $load_params = array( + 'parent' => $params->pod_id, + ); + + if ( ! empty( $params->id ) ) { + $load_params['id'] = $params->id; + } elseif ( ! empty( $params->old_name ) ) { + $load_params['name'] = $params->old_name; + } elseif ( ! empty( $params->name ) ) { + $load_params['name'] = $params->name; + } + + $group = $this->load_group( $load_params ); + + if ( $group instanceof Group ) { + $group = $group->get_args(); + } + + $old_id = null; + $old_name = null; + + if ( ! empty( $group ) ) { + $old_id = $group['id']; + $old_name = $group['name']; + + // Maybe set up the group to save over the existing group. + if ( $params->overwrite && empty( $params->id ) ) { $params->id = $old_id; } - if ( ! in_array( $old_type, $tableless_field_types ) || $old_simple ) { - $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) ); + if ( isset( $params->new_name ) && ! empty( $params->new_name ) ) { + $group['name'] = $params->new_name; - if ( 0 < strlen( $definition ) ) { - $old_definition = "`{$old_name}` " . $definition; + unset( $params->new_name ); + } elseif ( isset( $params->name ) ) { + $group['name'] = $params->name; + } + + if ( $old_name !== $group['name'] || empty( $params->id ) || $old_id !== $params->id ) { + if ( in_array( $params->name, $reserved_keywords, true ) ) { + return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $params->name ), $this ); } + + if ( false !== $this->group_exists( $params, false ) ) { + return pods_error( sprintf( __( 'Group %1$s already exists, you cannot rename %2$s to that', 'pods' ), $params->name, $old_name ), $this ); + } + } + + if ( ( $id_required || ! empty( $params->id ) ) && ( empty( $old_id ) || $old_id !== $params->id ) ) { + return pods_error( sprintf( __( 'Group %s already exists', 'pods' ), $params->name ), $this ); + } + + if ( empty( $params->id ) ) { + $params->id = $old_id; } } else { - $field = array( + $group = [ 'id' => 0, 'pod_id' => $params->pod_id, - 'name' => $params->name, - 'label' => $params->name, - 'description' => '', - 'type' => 'text', - 'pick_object' => '', - 'pick_val' => '', - 'sister_id' => '', + 'name' => $params->name, + 'label' => $params->name, + 'description' => '', + 'type' => '', 'weight' => null, - 'options' => array() - ); + 'options' => [], + ]; } // Setup options $options = get_object_vars( $params ); - $options_ignore = array( + $options_ignore = [ 'method', 'table_info', 'attributes', @@ -2623,8 +4227,14 @@ public function save_field( $params, $table_operation = true, $sanitized = false 'developer_mode', 'dependency', 'depends-on', - 'excludes-on' - ); + 'excludes-on', + 'object_type', + 'storage_type', + 'is_new', + 'overwrite', + '_locale', + 'old_name', + ]; foreach ( $options_ignore as $ignore ) { if ( isset( $options[ $ignore ] ) ) { @@ -2632,13 +4242,7 @@ public function save_field( $params, $table_operation = true, $sanitized = false } } - if ( isset( $options['method'] ) ) { - unset( $options['method'] ); - } elseif ( isset( $options['table_info'] ) ) { - unset( $options['table_info'] ); - } - - $exclude = array( + $exclude = [ 'id', 'pod_id', 'pod', @@ -2646,212 +4250,106 @@ public function save_field( $params, $table_operation = true, $sanitized = false 'label', 'description', 'type', - 'pick_object', - 'pick_val', - 'sister_id', 'weight', - 'options' - ); + 'options', + 'is_new', + 'overwrite', + '_locale', + 'post_status', + ]; - foreach ( $exclude as $k => $exclude_field ) { - $aliases = array( $exclude_field ); + foreach ( $exclude as $k => $exclude_group ) { + $aliases = array( $exclude_group ); - if ( is_array( $exclude_field ) ) { - $aliases = array_merge( array( $k ), $exclude_field ); - $exclude_field = $k; + if ( is_array( $exclude_group ) ) { + $aliases = array_merge( array( $k ), $exclude_group ); + $exclude_group = $k; } foreach ( $aliases as $alias ) { if ( isset( $options[ $alias ] ) ) { - $field[ $exclude_field ] = pods_trim( $options[ $alias ] ); + $group[ $exclude_group ] = pods_trim( $options[ $alias ] ); unset( $options[ $alias ] ); } } } - if ( strlen( $field['label'] ) < 1 ) { - $field['label'] = $field['name']; + if ( '' === $group['label'] ) { + $group['label'] = $group['name']; } - $field['options']['type'] = $field['type']; - - if ( in_array( $field['options']['type'], $tableless_field_types ) ) { - // Clean up special drop-down in field editor and save out pick_val - $field['pick_object'] = pods_var( 'pick_object', $field, '', null, true ); - - if ( 0 === strpos( $field['pick_object'], 'pod-' ) ) { - $field['pick_val'] = pods_str_replace( 'pod-', '', $field['pick_object'], 1 ); - $field['pick_object'] = 'pod'; - } elseif ( 0 === strpos( $field['pick_object'], 'post_type-' ) ) { - $field['pick_val'] = pods_str_replace( 'post_type-', '', $field['pick_object'], 1 ); - $field['pick_object'] = 'post_type'; - } elseif ( 0 === strpos( $field['pick_object'], 'taxonomy-' ) ) { - $field['pick_val'] = pods_str_replace( 'taxonomy-', '', $field['pick_object'], 1 ); - $field['pick_object'] = 'taxonomy'; - } elseif ( 'table' === $field['pick_object'] && 0 < strlen( pods_var_raw( 'pick_table', $field['options'] ) ) ) { - $field['pick_val'] = $field['options']['pick_table']; - $field['pick_object'] = 'table'; - } elseif ( false === strpos( $field['pick_object'], '-' ) && ! in_array( $field['pick_object'], array( - 'pod', - 'post_type', - 'taxonomy' - ) ) ) { - $field['pick_val'] = ''; - } elseif ( 'custom-simple' === $field['pick_object'] ) { - $field['pick_val'] = ''; - } - - $field['options']['pick_object'] = $field['pick_object']; - $field['options']['pick_val'] = $field['pick_val']; - $field['options']['sister_id'] = pods_var( 'sister_id', $field ); - - unset( $field['pick_object'] ); - unset( $field['pick_val'] ); - - if ( isset( $field['sister_id'] ) ) { - unset( $field['sister_id'] ); - } + foreach ( $options as $o => $v ) { + $group[ $o ] = $v; } - $field['options'] = array_merge( $field['options'], $options ); + // Check for strict mode (default: strict). + $strict_mode = ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT; - $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true ); - - if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && ! PODS_FIELD_STRICT ) { + if ( 0 < $old_id && ! $strict_mode ) { $params->id = $old_id; - $field['id'] = $old_id; + $group['id'] = $old_id; } - // Add new field - if ( ! isset( $params->id ) || empty( $params->id ) || empty( $field ) ) { - if ( $table_operation && in_array( $field['name'], array( - 'created', - 'modified' - ) ) && ! in_array( $field['type'], array( - 'date', - 'datetime' - ) ) && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) { - return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } - - if ( $table_operation && 'author' === $field['name'] && 'pick' !== $field['type'] && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) { - return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } - - if ( in_array( $field['name'], $reserved_keywords, true ) ) { - return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } - - foreach ( $object_fields as $object_field => $object_field_opt ) { - if ( $object_field == $field['name'] || in_array( $field['name'], $object_field_opt['alias'] ) ) { - return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name. Also consider what WordPress and Pods provide you built-in.', 'pods' ), $field['name'] ), $this ); - } - } - - if ( in_array( $field['name'], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names - { - $field['name'] .= '2'; + // Add new group. + if ( ! isset( $params->id ) || empty( $params->id ) || empty( $group ) ) { + if ( in_array( $group['name'], $reserved_keywords, true ) ) { + return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $group['name'] ), $this ); } - if ( 'slug' === $field['type'] && true === $db ) { - if ( in_array( $pod['type'], array( 'post_type', 'taxonomy', 'user' ) ) ) { - return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this ); - } - - $slug_field = get_posts( array( - 'post_type' => '_pods_field', - 'orderby' => 'menu_order', - 'order' => 'ASC', - 'posts_per_page' => 1, - 'post_parent' => $field['pod_id'], - 'meta_query' => array( - array( - 'key' => 'type', - 'value' => 'slug' - ) - ) - ) ); - - if ( ! empty( $slug_field ) ) { - return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this ); - } + // Reserved post_name values that can't be used as group names + if ( 'rss' === $group['name'] ) { + $group['name'] .= '2'; } - // Sink the new field to the bottom of the list - if ( null === $field['weight'] ) { - $field['weight'] = 0; + // Sink the new group to the bottom of the list + if ( null === $group['weight'] ) { + $group['weight'] = 0; - $bottom_most_field = get_posts( array( - 'post_type' => '_pods_field', + $bottom_most_group = get_posts( array( + 'post_type' => '_pods_group', 'orderby' => 'menu_order', 'order' => 'DESC', 'posts_per_page' => 1, - 'post_parent' => $field['pod_id'] + 'post_parent' => $group['pod_id'] ) ); - if ( ! empty( $bottom_most_field ) ) { - $field['weight'] = pods_absint( $bottom_most_field[0]->menu_order ) + 1; + if ( ! empty( $bottom_most_group ) ) { + $group['weight'] = pods_absint( $bottom_most_group[0]->menu_order ) + 1; } } - $field['weight'] = pods_absint( $field['weight'] ); + $group['weight'] = pods_absint( $group['weight'] ); $post_data = array( - 'post_name' => $field['name'], - 'post_title' => $field['label'], - 'post_content' => $field['description'], - 'post_type' => '_pods_field', - 'post_parent' => $field['pod_id'], + 'post_name' => $group['name'], + 'post_title' => $group['label'], + 'post_content' => $group['description'], + 'post_type' => '_pods_group', + 'post_parent' => $group['pod_id'], 'post_status' => 'publish', - 'menu_order' => $field['weight'] + 'menu_order' => $group['weight'] ); } else { - if ( in_array( $field['name'], array( 'id', 'ID' ) ) ) { - if ( null !== $old_name ) { - return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } else { - return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this ); - } - } - - if ( null !== $old_name && $field['name'] !== $old_name && in_array( $field['name'], array( - 'created', - 'modified' - ) ) && ! in_array( $field['type'], array( - 'date', - 'datetime' - ) ) && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) { - return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } - - if ( null !== $old_name && $field['name'] !== $old_name && 'author' === $field['name'] && 'pick' !== $field['type'] && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) { - return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); - } - - foreach ( $object_fields as $object_field => $object_field_opt ) { - if ( $object_field !== $field['name'] && ! in_array( $field['name'], $object_field_opt['alias'] ) ) { - continue; - } - + if ( in_array( $group['name'], array( 'id', 'ID' ) ) ) { if ( null !== $old_name ) { - return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this ); + return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $group['name'] ), $this ); } else { - return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this ); + return pods_error( sprintf( __( '%s is not editable', 'pods' ), $group['name'] ), $this ); } } $post_data = array( - 'ID' => $field['id'], - 'post_name' => $field['name'], - 'post_title' => $field['label'], - 'post_content' => $field['description'] + 'ID' => $group['id'], + 'post_name' => $group['name'], + 'post_title' => $group['label'], + 'post_content' => $group['description'] ); - if ( null !== $field['weight'] ) { - $field['weight'] = pods_absint( $field['weight'] ); + if ( null !== $group['weight'] ) { + $group['weight'] = pods_absint( $group['weight'] ); - $post_data['menu_order'] = $field['weight']; + $post_data['menu_order'] = $group['weight']; } } @@ -2862,271 +4360,81 @@ public function save_field( $params, $table_operation = true, $sanitized = false $conflicted = false; - // Headway compatibility fix - if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) { - remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); - - $conflicted = true; - } - - // Store the old field name - if ( $old_name && $old_name !== $post_data['post_name'] ) { - $field['options']['old_name'] = $old_name; - } - - $params->id = $this->save_wp_object( 'post', $post_data, $field['options'], true, true ); - - if ( $conflicted ) { - add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); - } - - if ( false === $params->id ) { - return pods_error( __( 'Cannot save Field', 'pods' ), $this ); - } - } else { - $params->id = $field['name']; - } - - $field['id'] = $params->id; - - $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field['options'] ), $simple_tableless_objects, true ) ); - - $definition = false; - - if ( ! in_array( $field['type'], $tableless_field_types ) || $simple ) { - $field_definition = $this->get_field_definition( $field['type'], array_merge( $field, $field['options'] ) ); - - if ( 0 < strlen( $field_definition ) ) { - $definition = '`' . $field['name'] . '` ' . $field_definition; - } - } - - $sister_id = (int) pods_var( 'sister_id', $field['options'], 0 ); - - $definition_mode = 'bypass'; - - if ( $table_operation && 'table' === $pod['storage'] && ! pods_tableless() ) { - if ( ! empty( $old_id ) ) { - if ( ( $field['type'] !== $old_type || $old_simple !== $simple ) && empty( $definition ) ) { - $definition_mode = 'drop'; - } elseif ( 0 < strlen( $definition ) ) { - if ( $old_name !== $field['name'] || $old_simple !== $simple || $old_definition !== $definition ) { - $definition_mode = 'add'; - - if ( 0 < strlen( $old_definition ) ) { - $definition_mode = 'change'; - } - } elseif ( null !== $old_definition && $definition !== $old_definition ) { - $definition_mode = 'change'; - } - } - } elseif ( 0 < strlen( $definition ) ) { - $definition_mode = 'add'; - - if ( 0 < strlen( $old_definition ) ) { - $definition_mode = 'change'; - } - } - - if ( 'bypass' !== $definition_mode ) { - /** - * Allow hooking into before the table has been altered for any custom functionality needed. - * - * @since 2.7.17 - * - * @param string $definition_mode The definition mode used for the table field. - * @param array $pod The pod object. - * @param string $type The field type. - * @param array $field The field object. - * @param array $extra_info { - * Extra information about the field. - * - * @type bool $simple Whether the field is a simple tableless field. - * @type string $definition The field definition. - * @type null|string $old_name The old field name (if preexisting). - * @type null|string $old_definition The old field definition (if preexisting). - * @type null|array $old_options The old field options (if preexisting). - * } - */ - do_action( 'pods_api_save_field_table_pre_alter', $definition_mode, $pod, $field['type'], $field, array( - 'simple' => $simple, - 'definition' => $definition, - 'old_name' => $old_name, - 'old_definition' => $old_definition, - 'old_options' => $old_options, - ) ); - - if ( 'drop' === $definition_mode ) { - // Drop field column. - pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false ); - } elseif ( 'change' === $definition_mode ) { - // Change field column definition. - if ( $old_name && $old_name !== $field['name'] ) { - $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false ); - } else { - $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` MODIFY {$definition}", false ); - } - - if ( false === $test ) { - $definition_mode = 'add'; - } - } - - // If the old field doesn't exist, continue to add a new field - if ( 'add' === $definition_mode ) { - pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) ); - } - - /** - * Allow hooking into after the table has been altered for any custom functionality needed. - * - * @since 2.7.17 - * - * @param string $definition_mode The definition mode used for the table field. - * @param array $pod The pod object. - * @param string $type The field type. - * @param array $field The field object. - * @param array $extra_info { - * Extra information about the field. - * - * @type bool $simple Whether the field is a simple tableless field. - * @type string $definition The field definition. - * @type null|string $old_name The old field name (if preexisting). - * @type null|string $old_definition The old field definition (if preexisting). - * @type null|array $old_options The old field options (if preexisting). - * } - */ - do_action( 'pods_api_save_field_table_altered', $definition_mode, $pod, $field['type'], $field, array( - 'simple' => $simple, - 'definition' => $definition, - 'old_name' => $old_name, - 'old_definition' => $old_definition, - 'old_options' => $old_options, - ) ); - } - } - - if ( ! empty( $old_id ) && 'meta' === $pod['storage'] && $old_name !== $field['name'] && $pod['meta_table'] !== $pod['table'] ) { - $prepare = array( - $field['name'], - $old_name - ); - - // Users don't have a type - if ( ! empty( $pod['field_type'] ) ) { - $prepare[] = $pod['name']; - } - - $join_table = $pod['table']; + // Headway compatibility fix + if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) { + remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); - // Taxonomies are the odd type out, terrible I know - if ( 'taxonomy' === $pod['type'] ) { - // wp_term_taxonomy has the 'taxonomy' field we need to limit by - $join_table = $wpdb->term_taxonomy; + $conflicted = true; } - pods_query( " - UPDATE `{$pod[ 'meta_table' ]}` AS `m` - LEFT JOIN `{$join_table}` AS `t` - ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}` - SET - `m`.`{$pod[ 'meta_field_index' ]}` = %s - WHERE - `m`.`{$pod[ 'meta_field_index' ]}` = %s - " . ( ! empty( $pod['field_type'] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ), $prepare ); - } - - if ( $field['type'] !== $old_type && in_array( $old_type, $tableless_field_types ) ) { - delete_post_meta( $old_sister_id, 'sister_id' ); + // Store the old group name + if ( $old_name && $old_name !== $post_data['post_name'] ) { + $group['old_name'] = $old_name; + } - if ( true === $db ) { - pods_query( " - DELETE pm - FROM {$wpdb->postmeta} AS pm - LEFT JOIN {$wpdb->posts} AS p - ON p.post_type = '_pods_field' - AND p.ID = pm.post_id - WHERE - p.ID IS NOT NULL - AND pm.meta_key = 'sister_id' - AND pm.meta_value = %d - ", array( - $params->id - ) ); + $meta = $group; - if ( ! pods_tableless() ) { - pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false ); + $excluded_meta = array( + 'id', + 'name', + 'label', + 'description', + 'pod_id', + 'pod', + 'weight', + 'options', + 'groups', + 'group', + 'fields', + 'object_fields', + 'is_new', + 'overwrite', + '_locale', + ); - pods_query( " - UPDATE `@wp_podsrel` - SET `related_field_id` = 0 - WHERE `field_id` = %d - ", array( - $old_sister_id - ) ); + foreach ( $excluded_meta as $meta_key ) { + if ( isset( $meta[ $meta_key ] ) ) { + unset( $meta[ $meta_key ] ); } } - } elseif ( 0 < $sister_id ) { - update_post_meta( $sister_id, 'sister_id', $params->id ); - if ( true === $db && ( ! pods_tableless() ) ) { - pods_query( " - UPDATE `@wp_podsrel` - SET `related_field_id` = %d - WHERE `field_id` = %d - ", array( - $params->id, - $sister_id - ) ); + $params->id = $this->save_wp_object( 'post', $post_data, $meta, true, true ); + + if ( $conflicted ) { + add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ); } - } elseif ( 0 < $old_sister_id ) { - delete_post_meta( $old_sister_id, 'sister_id' ); - if ( true === $db && ( ! pods_tableless() ) ) { - pods_query( " - UPDATE `@wp_podsrel` - SET `related_field_id` = 0 - WHERE `field_id` = %d - ", array( - $old_sister_id - ) ); + if ( false === $params->id ) { + return pods_error( __( 'Cannot save Group', 'pods' ), $this ); } + } else { + $params->id = $group['name']; } - if ( ! empty( $old_id ) && $old_name !== $field['name'] && true === $db ) { - pods_query( " - UPDATE `@wp_postmeta` - SET `meta_value` = %s - WHERE - `post_id` = %d - AND `meta_key` = 'pod_index' - AND `meta_value` = %s - ", array( - $field['name'], - $pod['id'], - $old_name - ) ); - } + $group['id'] = $params->id; - if ( ! $save_pod ) { - $this->cache_flush_pods( $pod ); - } else { - pods_transient_clear( 'pods_field_' . $pod['name'] . '_' . $field['name'] ); + $object_collection = Pods\Whatsit\Store::get_instance(); - if ( ! empty( $old_id ) && $old_name !== $field['name'] ) { - pods_transient_clear( 'pods_field_' . $pod['name'] . '_' . $old_name ); - } - } + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); + + $object = $post_type_storage->to_object( $group['id'], true ); + + if ( ! $object ) { + return pods_error( __( 'Cannot save group to collection', 'pods' ), $this ); + } + + $this->cache_flush_pods( $object ); if ( true === $db ) { return $params->id; } else { - return $field; + return $object; } } /** - * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name) + * Fix Pod / Group / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name) * * @param string $slug Unique slug value * @param int $post_ID Post ID @@ -3140,8 +4448,7 @@ public function save_field( $params, $table_operation = true, $sanitized = false * @since 2.3.3 */ public function save_slug_fix( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) { - - if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) ) { + if ( in_array( $post_type, array( '_pods_pod', '_pods_group', '_pods_field' ), true ) && false !== strpos( $slug, '-' ) ) { $slug = $original_slug; } @@ -3154,7 +4461,6 @@ public function save_slug_fix( $slug, $post_ID, $post_status, $post_type, $post_ * $params['id'] int The Object ID * $params['name'] string The Object name * $params['type'] string The Object type - * $params['options'] Associative array of Object options * * @param array|object $params An associative array of parameters * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, @@ -3169,6 +4475,8 @@ public function save_object( $params, $sanitized = false ) { if ( false === $sanitized ) { $params = pods_sanitize( $params ); + + $sanitized = true; } if ( ! isset( $params->name ) || empty( $params->name ) ) { @@ -3179,56 +4487,37 @@ public function save_object( $params, $sanitized = false ) { return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this ); } - $object = array( - 'id' => 0, - 'name' => $params->name, - 'type' => $params->type, - 'code' => '', - 'options' => array() - ); + $object = [ + 'id' => isset( $params->id ) ? $params->id : 0, + 'name' => $params->name, + 'type' => $params->type, + 'code' => isset( $params->code ) ? $params->code : '', + ]; // Setup options $options = get_object_vars( $params ); + if ( isset( $options['options'] ) ) { + $options = array_merge( $options, $options['options'] ); + + unset( $options['options'] ); + } + if ( isset( $options['method'] ) ) { unset( $options['method'] ); } - $exclude = array( - 'id', - 'name', - 'helper_type', - 'code', - 'options', - 'status' - ); - - foreach ( $exclude as $k => $exclude_field ) { - $aliases = array( $exclude_field ); - - if ( is_array( $exclude_field ) ) { - $aliases = array_merge( array( $k ), $exclude_field ); - $exclude_field = $k; - } + $post_meta = $options; - foreach ( $aliases as $alias ) { - if ( isset( $options[ $alias ] ) ) { - $object[ $exclude_field ] = pods_trim( $options[ $alias ] ); + $exclude = array_keys( $object ); - unset( $options[ $alias ] ); - } + foreach ( $exclude as $excluded_key ) { + if ( isset( $post_meta[ $excluded_key ] ) ) { + unset( $post_meta[ $excluded_key ] ); } } - if ( 'helper' === $object['type'] ) { - $object['options']['helper_type'] = $object['helper_type']; - } - - if ( isset( $object['options']['code'] ) ) { - unset( $object['options']['code'] ); - } - - $object['options'] = array_merge( $object['options'], $options ); + $object = array_merge( $options, $object ); $post_data = array( 'post_name' => pods_clean_name( $object['name'], true ), @@ -3242,15 +4531,17 @@ public function save_object( $params, $sanitized = false ) { $post_data['ID'] = $object['id']; } - if ( null !== pods_var( 'status', $object, null, null, true ) ) { - $post_data['post_status'] = pods_var( 'status', $object, null, null, true ); + $post_status = pods_v( 'status', $object, null, true ); + + if ( null !== $post_status ) { + $post_data['post_status'] = $post_status; } remove_filter( 'content_save_pre', 'balanceTags', 50 ); $post_data = pods_sanitize( $post_data ); - $params->id = $this->save_post( $post_data, $object['options'], true, true ); + $params->id = $this->save_post( $post_data, $post_meta, true, true ); pods_transient_clear( 'pods_objects_' . $params->type ); pods_transient_clear( 'pods_objects_' . $params->type . '_get' ); @@ -3268,7 +4559,7 @@ public function save_object( $params, $sanitized = false ) { * $params['code'] string The template code * * @param array|object $params An associative array of parameters - * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, * will sanitize them if false. * * @return int The Template ID @@ -3294,7 +4585,7 @@ public function save_template( $params, $sanitized = false ) { * $params['code'] string The page code * * @param array|object $params An associative array of parameters - * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, * will sanitize them if false. * * @return int The page ID @@ -3331,29 +4622,16 @@ public function save_page( $params, $sanitized = false ) { * $params['code'] string The helper code * * @param array $params An associative array of parameters - * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will + * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will * sanitize them if false. * * @return int The helper ID * @since 1.7.9 + * + * @deprecated since 2.8.0 */ public function save_helper( $params, $sanitized = false ) { - - $params = (object) $params; - - if ( isset( $params->phpcode ) ) { - $params->code = $params->phpcode; - unset( $params->phpcode ); - } - - if ( isset( $params->type ) ) { - $params->helper_type = $params->type; - unset( $params->type ); - } - - $params->type = 'helper'; - - return $this->save_object( $params, $sanitized ); + return 0; } /** @@ -3382,6 +4660,7 @@ public function save_pod_item( $params ) { $tableless_field_types = PodsForm::tableless_field_types(); $repeatable_field_types = PodsForm::repeatable_field_types(); + $layout_field_types = PodsForm::layout_field_types(); $simple_tableless_objects = PodsForm::simple_tableless_objects(); $error_mode = $this->display_errors; @@ -3390,51 +4669,6 @@ public function save_pod_item( $params ) { $error_mode = $params->error_mode; } - // @deprecated 2.0.0 - if ( isset( $params->datatype ) ) { - pods_deprecated( '$params->pod instead of $params->datatype', '2.0' ); - - $params->pod = $params->datatype; - - unset( $params->datatype ); - - if ( isset( $params->pod_id ) ) { - pods_deprecated( '$params->id instead of $params->pod_id', '2.0' ); - - $params->id = $params->pod_id; - - unset( $params->pod_id ); - } - - if ( isset( $params->data ) && ! empty( $params->data ) && is_array( $params->data ) ) { - $check = current( $params->data ); - - if ( is_array( $check ) ) { - pods_deprecated( 'PodsAPI::save_pod_items', '2.0' ); - - return $this->save_pod_items( $params, $params->data ); - } - } - } - - // @deprecated 2.0.0 - if ( isset( $params->tbl_row_id ) ) { - pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' ); - - $params->id = $params->tbl_row_id; - - unset( $params->tbl_row_id ); - } - - // @deprecated 2.0.0 - if ( isset( $params->columns ) ) { - pods_deprecated( '$params->data instead of $params->columns', '2.0' ); - - $params->data = $params->columns; - - unset( $params->columns ); - } - if ( ! isset( $params->pod ) ) { $params->pod = false; } @@ -3520,7 +4754,7 @@ public function save_pod_item( $params ) { } // Get array of Pods - $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) ); + $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod ), false ); if ( false === $pod ) { return pods_error( __( 'Pod not found', 'pods' ), $error_mode ); @@ -3533,9 +4767,12 @@ public function save_pod_item( $params ) { $params->id = $pod['id']; } - $fields = $pod['fields']; + $fields = $pod->get_fields(); + $object_fields = $pod->get_object_fields(); - $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true ); + // Map the fields to Value_Field to store values. + $fields = array_map( [ Value_Field::class, 'init' ], $fields ); + $object_fields = array_map( [ Value_Field::class, 'init' ], $object_fields ); $fields_active = array(); $custom_data = array(); @@ -3546,14 +4783,17 @@ public function save_pod_item( $params ) { foreach ( $params->data as $field => $value ) { if ( isset( $object_fields[ $field ] ) ) { $object_fields[ $field ]['value'] = $value; - $fields_active[] = $field; + + $fields_active[] = $field; } elseif ( isset( $fields[ $field ] ) ) { - if ( 'save' === $params->from || true === PodsForm::permission( $fields[ $field ]['type'], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) { + if ( 'save' === $params->from || true === pods_permission( $fields[ $field ] ) ) { $fields[ $field ]['value'] = $value; - $fields_active[] = $field; - } elseif ( ! pods_has_permissions( $fields[ $field ]['options'] ) && pods_var( 'hidden', $fields[ $field ]['options'], false ) ) { + + $fields_active[] = $field; + } elseif ( ! pods_has_permissions( $fields[ $field ] ) && pods_v( 'hidden', $fields[ $field ], false ) ) { $fields[ $field ]['value'] = $value; - $fields_active[] = $field; + + $fields_active[] = $field; } } else { $found = false; @@ -3561,7 +4801,8 @@ public function save_pod_item( $params ) { foreach ( $object_fields as $object_field => $object_field_opt ) { if ( in_array( $field, $object_field_opt['alias'] ) ) { $object_fields[ $object_field ]['value'] = $value; - $fields_active[] = $object_field; + + $fields_active[] = $object_field; $found = true; @@ -3584,46 +4825,50 @@ public function save_pod_item( $params ) { unset( $params->data ); } - if ( empty( $params->id ) && ! in_array( 'created', $fields_active ) && isset( $fields['created'] ) && in_array( $fields['created']['type'], array( + if ( empty( $params->id ) && isset( $fields['created'] ) && ! in_array( 'created', $fields_active, true ) && in_array( $fields['created']['type'], array( 'date', 'datetime' - ) ) ) { + ), true ) ) { $fields['created']['value'] = current_time( 'mysql' ); - $fields_active[] = 'created'; + + $fields_active[] = 'created'; } - if ( ! in_array( 'modified', $fields_active ) && isset( $fields['modified'] ) && in_array( $fields['modified']['type'], array( + if ( isset( $fields['modified'] ) && ! in_array( 'modified', $fields_active, true ) && in_array( $fields['modified']['type'], array( 'date', 'datetime' - ) ) ) { + ), true ) ) { $fields['modified']['value'] = current_time( 'mysql' ); - $fields_active[] = 'modified'; + + $fields_active[] = 'modified'; } - if ( in_array( $pod['type'], array( + if ( empty( $params->id ) && ! empty( $pod['pod_field_index'] ) && isset( $fields[ $pod['pod_field_slug'] ] ) && in_array( $pod['type'], array( 'pod', 'table' - ) ) && empty( $params->id ) && ! empty( $pod['pod_field_index'] ) && in_array( $pod['pod_field_index'], $fields_active ) && ! in_array( $pod['pod_field_slug'], $fields_active ) && isset( $fields[ $pod['pod_field_slug'] ] ) ) { + ), true ) && in_array( $pod['pod_field_index'], $fields_active, true ) && ! in_array( $pod['pod_field_slug'], $fields_active, true ) ) { $fields[ $pod['pod_field_slug'] ]['value'] = ''; // this will get picked up by slug pre_save method - $fields_active[] = $pod['pod_field_slug']; + + $fields_active[] = $pod['pod_field_slug']; } // Handle hidden fields if ( empty( $params->id ) ) { foreach ( $fields as $field => $field_data ) { - if ( in_array( $field, $fields_active ) ) { + if ( in_array( $field, $fields_active, true ) ) { continue; } if ( in_array( $params->from, array( 'save', 'process_form' - ) ) || true === PodsForm::permission( $fields[ $field ]['type'], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) { - $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data['type'], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id ); + ), true ) || true === pods_permission( $fields[ $field ] ) ) { + $value = PodsForm::default_value( pods_v( $field, 'post' ), $field_data['type'], $field, pods_v( 'options', $field_data, $field_data, true ), $pod, $params->id ); if ( null !== $value && '' !== $value && false !== $value ) { $fields[ $field ]['value'] = $value; - $fields_active[] = $field; + + $fields_active[] = $field; } } } @@ -3631,34 +4876,40 @@ public function save_pod_item( $params ) { // Set default field values for object fields if ( ! empty( $object_fields ) ) { foreach ( $object_fields as $field => $field_data ) { - if ( in_array( $field, $fields_active ) ) { + if ( in_array( $field, $fields_active, true ) ) { continue; - } elseif ( ! isset( $field_data['default'] ) || strlen( $field_data['default'] ) < 1 ) { + } + + if ( ! isset( $field_data['default'] ) || '' === $field_data['default'] ) { continue; } - $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data['type'], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id ); + $value = PodsForm::default_value( pods_v( $field, 'post' ), $field_data['type'], $field, pods_v( 'options', $field_data, $field_data, true ), $pod, $params->id ); if ( null !== $value && '' !== $value && false !== $value ) { $object_fields[ $field ]['value'] = $value; - $fields_active[] = $field; + + $fields_active[] = $field; } } } // Set default field values for Pod fields foreach ( $fields as $field => $field_data ) { - if ( in_array( $field, $fields_active ) ) { + if ( in_array( $field, $fields_active, true ) ) { continue; - } elseif ( ! isset( $field_data['default'] ) || strlen( $field_data['default'] ) < 1 ) { + } + + if ( ! isset( $field_data['default'] ) || '' === $field_data['default'] ) { continue; } - $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data['type'], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id ); + $value = PodsForm::default_value( pods_v( $field, 'post' ), $field_data['type'], $field, pods_v( 'options', $field_data, $field_data, true ), $pod, $params->id ); if ( null !== $value && '' !== $value && false !== $value ) { $fields[ $field ]['value'] = $value; - $fields_active[] = $field; + + $fields_active[] = $field; } } } @@ -3728,24 +4979,12 @@ public function save_pod_item( $params ) { // Call any pre-save helpers (if not bypassed) if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) { - if ( ! empty( $pod['options'] ) && is_array( $pod['options'] ) ) { + if ( ! empty( $pod ) ) { $helpers = array( 'pre_save_helpers', 'post_save_helpers' ); foreach ( $helpers as $helper ) { - if ( isset( $pod['options'][ $helper ] ) && ! empty( $pod['options'][ $helper ] ) ) { - ${$helper} = explode( ',', $pod['options'][ $helper ] ); - } - } - } - - if ( ! empty( $pre_save_helpers ) ) { - pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' ); - - foreach ( $pre_save_helpers as $helper ) { - $helper = $this->load_helper( array( 'name' => $helper ) ); - - if ( false !== $helper ) { - eval( '?>' . $helper['code'] ); + if ( isset( $pod[ $helper ] ) && ! empty( $pod[ $helper ] ) ) { + ${$helper} = explode( ',', $pod[ $helper ] ); } } } @@ -3762,10 +5001,10 @@ public function save_pod_item( $params ) { $object_ID = 'ID'; - if ( 'comment' === $object_type ) { - $object_ID = 'comment_ID'; - } elseif ( 'taxonomy' === $object_type ) { - $object_ID = 'term_id'; + if ( ! empty( $pod['field_id'] ) ) { + $object_ID = $pod['field_id']; + } elseif ( ! empty( $pod['pod_field_id'] ) ) { + $object_ID = $pod['pod_field_id']; } $object_data = array(); @@ -3792,7 +5031,11 @@ public function save_pod_item( $params ) { $value = $field_data['value']; $type = $field_data['type']; - $options = pods_var( 'options', $field_data, array() ); + $options = pods_v( 'options', $field_data, [] ); + + if ( in_array( $type, $layout_field_types, true ) ) { + continue; + } // WPML AJAX compatibility if ( is_admin() @@ -3801,10 +5044,10 @@ public function save_pod_item( $params ) { && isset( $_POST['icl_ajx_action'] ) && isset( $_POST['_icl_nonce'] ) && wp_verify_nonce( $_POST['_icl_nonce'], $_POST['icl_ajx_action'] . '_nonce' ) ) ) { - $options['unique'] = 0; - $fields[ $field ]['options']['unique'] = 0; - $options['required'] = 0; - $fields[ $field ]['options']['required'] = 0; + $options['unique'] = 0; + $fields[ $field ]['unique'] = 0; + $options['required'] = 0; + $fields[ $field ]['required'] = 0; } else { // Validate value $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params ); @@ -3820,7 +5063,7 @@ public function save_pod_item( $params ) { } } - $value = PodsForm::pre_save( $field_data['type'], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params ); + $value = PodsForm::pre_save( $field_data['type'], $value, $params->id, $field, $field_data, pods_config_merge_fields( $fields, $object_fields ), $pod, $params ); $field_data['value'] = $value; @@ -3832,7 +5075,7 @@ public function save_pod_item( $params ) { $object_data[ $field ] = $value; } } else { - $simple = ( 'pick' === $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) ); + $simple = ( 'pick' === $type && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) ); $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params ); // Handle Simple Relationships @@ -3845,16 +5088,16 @@ public function save_pod_item( $params ) { } } - $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 ); + $pick_limit = (int) pods_v( 'pick_limit', $options, 0 ); - if ( 'single' === pods_var_raw( 'pick_format_type', $options ) ) { + if ( 'single' === pods_v( 'pick_format_type', $options ) ) { $pick_limit = 1; } - if ( 'custom-simple' === pods_var( 'pick_object', $field_data ) ) { - $custom = pods_var_raw( 'pick_custom', $options, '' ); + if ( 'custom-simple' === pods_v( 'pick_object', $field_data ) ) { + $custom = pods_v( 'pick_custom', $options, '' ); - $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data['name'], $value, array_merge( $field_data, $options ), $pod, $params->id ); + $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data['name'], $value, $field_data, $pod, $params->id ); // Input values are unslashed. Unslash database values as well to ensure correct comparison. $custom = pods_unslash( $custom ); @@ -3906,10 +5149,10 @@ public function save_pod_item( $params ) { if ( empty( $value ) ) { $value = ''; } elseif ( is_array( $value ) ) { - if ( 1 == $pick_limit || 1 == count( $value ) ) { + if ( 1 === $pick_limit || 1 === count( $value ) ) { // If there's just one item, don't save as an array, save the string $value = implode( '', $value ); - } elseif ( 'table' === pods_var( 'storage', $pod ) ) { + } elseif ( 'table' === pods_v( 'storage', $pod ) ) { // If storage is set to table, json encode, otherwise WP will serialize automatically $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value ); } @@ -3917,16 +5160,16 @@ public function save_pod_item( $params ) { } // Prepare all table / meta data - if ( ! in_array( $type, $tableless_field_types ) || $simple ) { - if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) { + if ( $simple || ! in_array( $type, $tableless_field_types, true ) ) { + if ( in_array( $type, $repeatable_field_types, true ) && 1 === (int) pods_v( $type . '_repeatable', $field_data, 0 ) ) { // Don't save an empty array, just make it an empty string if ( empty( $value ) ) { $value = ''; } elseif ( is_array( $value ) ) { - if ( 1 == count( $value ) ) { + if ( 1 === count( $value ) ) { // If there's just one item, don't save as an array, save the string $value = implode( '', $value ); - } elseif ( 'table' === pods_var( 'storage', $pod ) ) { + } elseif ( 'table' === pods_v( 'storage', $pod ) ) { // If storage is set to table, json encode, otherwise WP will serialize automatically $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value ); } @@ -4049,40 +5292,42 @@ public function save_pod_item( $params ) { pods_no_conflict_on( $pod['type'] ); } + $static_cache = tribe( Static_Cache::class ); + // Save relationship / file data if ( ! empty( $rel_fields ) ) { foreach ( $rel_fields as $type => $data ) { // Only handle tableless fields - if ( ! in_array( $type, $tableless_field_types ) ) { + if ( ! in_array( $type, $tableless_field_types, true ) ) { continue; } foreach ( $data as $field => $values ) { - $pick_val = pods_var( 'pick_val', $fields[ $field ] ); + $pick_val = pods_v( 'pick_val', $fields[ $field ] ); - if ( 'table' === pods_var( 'pick_object', $fields[ $field ] ) ) { - $pick_val = pods_var( 'pick_table', $fields[ $field ]['options'], $pick_val, null, true ); + if ( 'table' === pods_v( 'pick_object', $fields[ $field ] ) ) { + $pick_val = pods_v( 'pick_table', $fields[ $field ], $pick_val, true ); } if ( '__current__' === $pick_val ) { - if ( is_object( $pod ) ) { - $pick_val = $pod->pod; - } elseif ( is_array( $pod ) ) { + if ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) { $pick_val = $pod['name']; - } elseif ( 0 < strlen( $pod ) ) { + } elseif ( is_object( $pod ) && isset( $pod->pod ) ) { + $pick_val = $pod->pod; + } elseif ( is_string( $pod ) && 0 < strlen( $pod ) ) { $pick_val = $pod; } } - $fields[ $field ]['options']['table_info'] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ]['options'] ); + $fields[ $field ]['table_info'] = pods_api()->get_table_info( pods_v( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ] ); - if ( isset( $fields[ $field ]['options']['table_info']['pod'] ) && ! empty( $fields[ $field ]['options']['table_info']['pod'] ) && isset( $fields[ $field ]['options']['table_info']['pod']['name'] ) ) { - $search_data = pods( $fields[ $field ]['options']['table_info']['pod']['name'] ); + if ( isset( $fields[ $field ]['table_info']['pod'] ) && ! empty( $fields[ $field ]['table_info']['pod'] ) && isset( $fields[ $field ]['table_info']['pod']['name'] ) ) { + $search_data = pods( $fields[ $field ]['table_info']['pod']['name'] ); $data_mode = 'pods'; } else { $search_data = pods_data(); - $search_data->table( $fields[ $field ]['options']['table_info'] ); + $search_data->table( $fields[ $field ]['table_info'] ); $data_mode = 'data'; } @@ -4101,17 +5346,17 @@ public function save_pod_item( $params ) { $find_rel_params = false; } - $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ]['options'], 0 ); + $related_limit = (int) pods_v( $type . '_limit', $fields[ $field ], 0 ); - if ( 'single' === pods_var_raw( $type . '_format_type', $fields[ $field ]['options'] ) ) { + if ( 'single' === pods_v( $type . '_format_type', $fields[ $field ] ) ) { $related_limit = 1; } // Enforce integers / unique values for IDs $value_ids = array(); - $is_file_field = in_array( $type, PodsForm::file_field_types() ); - $is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ]['options'] ) ); + $is_file_field = in_array( $type, PodsForm::file_field_types(), true ); + $is_taggable = ( in_array( $type, PodsForm::tableless_field_types(), true ) && 1 === (int) pods_v( $type . '_taggable', $fields[ $field ] ) ); // @todo Handle simple relationships eventually foreach ( $values as $v ) { @@ -4199,9 +5444,11 @@ public function save_pod_item( $params ) { $values = array_slice( $values, 0, $related_limit ); } + $related_data = $static_cache->get( $fields[ $field ]['name'] . '/' . $fields[ $field ]['id'], 'PodsField_Pick/related_data' ) ?: []; + // Get current values - if ( 'pick' === $type && isset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ]['current_ids'] ) ) { - $related_ids = PodsField_Pick::$related_data[ $fields[ $field ]['id'] ]['current_ids']; + if ( 'pick' === $type && isset( $related_data[ 'current_ids_' . $params->id ] ) ) { + $related_ids = $related_data[ 'current_ids_' . $params->id ]; } else { $related_ids = $this->lookup_related_items( $fields[ $field ]['id'], $pod['id'], $params->id, $fields[ $field ], $pod ); } @@ -4209,14 +5456,16 @@ public function save_pod_item( $params ) { // Get ids to remove $remove_ids = array_diff( $related_ids, $value_ids ); - // Delete relationships - if ( ! empty( $remove_ids ) ) { - $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] ); - } + if ( ! empty( $fields[ $field ] ) ) { + // Delete relationships + if ( ! empty( $remove_ids ) ) { + $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] ); + } - // Save relationships - if ( ! empty( $value_ids ) ) { - $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] ); + // Save relationships + if ( ! empty( $value_ids ) ) { + $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] ); + } } $field_save_values = $value_ids; @@ -4226,15 +5475,20 @@ public function save_pod_item( $params ) { } // Run save function for field type (where needed) - PodsForm::save( $type, $field_save_values, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ]['options'] ), array_merge( $fields, $object_fields ), $pod, $params ); + PodsForm::save( $type, $field_save_values, $params->id, $field, $fields[ $field ], pods_config_merge_fields( $fields, $object_fields ), $pod, $params ); } // Unset data no longer needed if ( 'pick' === $type ) { foreach ( $data as $field => $values ) { - if ( isset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ] ) ) { - unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ]['id'] ]['related_field']['id'] ] ); - unset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ] ); + $related_data = $static_cache->get( $fields[ $field ]['name'] . '/' . $fields[ $field ]['id'], 'PodsField_Pick/related_data' ) ?: []; + + if ( ! empty( $related_data ) ) { + if ( ! empty( $related_data['related_field'] ) ) { + $static_cache->delete( $related_data['related_field']['name'] . '/' . $related_data['related_field']['id'], 'PodsField_Pick/related_data' ); + } + + $static_cache->delete( $fields[ $field ]['name'] . '/' . $fields[ $field ]['id'], 'PodsField_Pick/related_data' ); } } } @@ -4286,21 +5540,6 @@ public function save_pod_item( $params ) { $this->do_hook( 'post_edit_pod_item', $compact_pieces, $params->id ); $this->do_hook( "post_edit_pod_item_{$params->pod}", $compact_pieces, $params->id ); } - - // Call any post-save helpers (if not bypassed) - if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) { - if ( ! empty( $post_save_helpers ) ) { - pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' ); - - foreach ( $post_save_helpers as $helper ) { - $helper = $this->load_helper( array( 'name' => $helper ) ); - - if ( false !== $helper && ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) ) { - eval( '?>' . $helper['code'] ); - } - } - } - } } // Success! Return the id @@ -4357,10 +5596,11 @@ public function save_pod_items( $params, $data ) { * @return array List of changed fields (if $mode = 'get') */ public static function handle_changed_fields( $pod, $id, $mode = 'set' ) { + $static_cache = tribe( Static_Cache::class ); - static $changed_pods_cache = array(); - static $old_fields_cache = array(); - static $changed_fields_cache = array(); + $changed_pods_cache = $static_cache->get( 'changed_pods_cache', __CLASS__ ) ?: []; + $old_fields_cache = $static_cache->get( 'old_fields_cache', __CLASS__ ) ?: []; + $changed_fields_cache = $static_cache->get( 'changed_fields_cache', __CLASS__ ) ?: []; $cache_key = $pod . '|' . $id; @@ -4418,6 +5658,10 @@ public static function handle_changed_fields( $pod, $id, $mode = 'set' ) { } } + $static_cache->set( 'changed_pods_cache', $changed_pods_cache, __CLASS__ ); + $static_cache->set( 'old_fields_cache', $old_fields_cache, __CLASS__ ); + $static_cache->set( 'changed_fields_cache', $changed_fields_cache, __CLASS__ ); + return $changed_fields; } @@ -4432,32 +5676,39 @@ public static function handle_changed_fields( $pod, $id, $mode = 'set' ) { * @deprecated 2.7.0 Use PodsAPI::handle_changed_fields */ public function get_changed_fields( $pieces ) { + _deprecated_function( __METHOD__, '2.7.0', 'PodsAPI::handle_changed_fields' ); return self::handle_changed_fields( $pieces['params']->pod, $pieces['params']->id, 'get' ); - } /** * Save relationships * - * @param int $id ID of item - * @param int|array $related_id ID or IDs to save - * @param array $pod Pod data - * @param array $field Field data + * @param int $id ID of item. + * @param int|array $related_ids ID(s) for items to save. + * @param array|Pod $pod The Pod object. + * @param array|Field $field The Field object. + * + * @return array List of ID(s) that were setup for saving. */ public function save_relationships( $id, $related_ids, $pod, $field ) { + $static_cache = tribe( Static_Cache::class ); + + $related_data = $static_cache->get( $field['name'] . '/' . $field['id'], 'PodsField_Pick/related_data' ) ?: []; // Get current values - if ( 'pick' === $field['type'] && isset( PodsField_Pick::$related_data[ $field['id'] ] ) && isset( PodsField_Pick::$related_data[ $field['id'] ]['current_ids'] ) ) { - $current_ids = PodsField_Pick::$related_data[ $field['id'] ]['current_ids']; + if ( 'pick' === $field['type'] && isset( $related_data[ 'current_ids_' . $id ] ) ) { + $current_ids = $related_data[ 'current_ids_' . $id ]; } else { $current_ids = $this->lookup_related_items( $field['id'], $pod['id'], $id, $field, $pod ); } - if ( isset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ) ) { - // Delete relationship from cache - unset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ); - } + $static_cache = tribe( Static_Cache::class ); + + $cache_key = $pod['id'] . '|' . $field['id']; + + // Delete relationship from cache. + $static_cache->delete( $cache_key, __CLASS__ . '/related_item_cache' ); if ( ! is_array( $related_ids ) ) { $related_ids = implode( ',', $related_ids ); @@ -4469,9 +5720,9 @@ public function save_relationships( $id, $related_ids, $pod, $field ) { $related_ids = array_unique( array_filter( $related_ids ) ); - $related_limit = (int) pods_var_raw( $field['type'] . '_limit', $field['options'], 0 ); + $related_limit = (int) pods_v( $field['type'] . '_limit', $field, 0 ); - if ( 'single' === pods_var_raw( $field['type'] . '_format_type', $field['options'] ) ) { + if ( 'single' === pods_v( $field['type'] . '_format_type', $field ) ) { $related_limit = 1; } @@ -4481,10 +5732,16 @@ public function save_relationships( $id, $related_ids, $pod, $field ) { } // Post Types, Media, Users, and Comments (meta-based) - if ( in_array( $pod['type'], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) { + if ( pods_relationship_meta_storage_enabled( $field, $pod ) && in_array( $pod['type'], [ + 'post_type', + 'media', + 'taxonomy', + 'user', + 'comment', + ], true ) ) { $object_type = $pod['type']; - if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) { + if ( in_array( $object_type, [ 'post_type', 'media' ], true ) ) { $object_type = 'post'; } elseif ( 'taxonomy' === $object_type ) { $object_type = 'term'; @@ -4513,18 +5770,18 @@ public function save_relationships( $id, $related_ids, $pod, $field ) { $related_pod_id = 0; $related_field_id = 0; - if ( 'pick' === $field['type'] && isset( PodsField_Pick::$related_data[ $field['id'] ] ) && ! empty( PodsField_Pick::$related_data[ $field['id'] ]['related_field'] ) ) { - $related_pod_id = PodsField_Pick::$related_data[ $field['id'] ]['related_pod']['id']; - $related_field_id = PodsField_Pick::$related_data[ $field['id'] ]['related_field']['id']; + if ( 'pick' === $field['type'] && ! empty( $related_data['related_field'] ) ) { + $related_pod_id = $related_data['related_pod']['id']; + $related_field_id = $related_data['related_field']['id']; } // Relationships table - if ( ! pods_tableless() ) { + if ( pods_podsrel_enabled() ) { $related_weight = 0; foreach ( $related_ids as $related_id ) { if ( in_array( $related_id, $current_ids ) ) { - pods_query( " + pods_query( ' UPDATE `@wp_podsrel` SET `pod_id` = %d, @@ -4539,7 +5796,7 @@ public function save_relationships( $id, $related_ids, $pod, $field ) { AND `field_id` = %d AND `item_id` = %d AND `related_item_id` = %d - ", array( + ', array( $pod['id'], $field['id'], $id, @@ -4554,7 +5811,7 @@ public function save_relationships( $id, $related_ids, $pod, $field ) { $related_id, ) ); } else { - pods_query( " + pods_query( ' INSERT INTO `@wp_podsrel` ( `pod_id`, @@ -4566,36 +5823,165 @@ public function save_relationships( $id, $related_ids, $pod, $field ) { `weight` ) VALUES ( %d, %d, %d, %d, %d, %d, %d ) - ", array( + ', array( $pod['id'], $field['id'], $id, $related_pod_id, $related_field_id, $related_id, - $related_weight + $related_weight, ) ); } - $related_weight ++; + $related_weight ++; + } + } + + /** + * Allow custom saving actions for relationships. + * + * @since 2.8.0 + * + * @param int $id ID of item. + * @param array $related_ids ID(s) for items to save. + * @param array|Pod $pod The Pod object. + * @param array|Field $field The Field object. + */ + do_action( 'pods_api_save_relationships', $id, $related_ids, $field, $pod ); + + return $related_ids; + } + + /** + * Duplicate a Pod. + * + * $params['id'] int The Pod ID. + * $params['name'] string The Pod name. + * $params['new_name'] string The new Pod name. + * + * @since 2.3.0 + * + * @param array $params An associative array of parameters. + * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error. + * + * @return int|false New Group ID or false if not successful. + */ + public function duplicate_pod( $params, $strict = false ) { + + if ( ! is_object( $params ) && ! is_array( $params ) ) { + if ( is_numeric( $params ) ) { + $params = array( 'id' => $params ); + } else { + $params = array( 'name' => $params ); + } + + $params = (object) pods_sanitize( $params ); + } else { + $params = (object) pods_sanitize( $params ); + } + + $pod = $this->load_pod( $params, false ); + + if ( empty( $pod ) ) { + if ( false !== $strict ) { + return pods_error( __( 'Pod not found', 'pods' ), $this ); + } + + return false; + } elseif ( in_array( $pod['type'], array( 'media', 'user', 'comment' ) ) ) { + if ( false !== $strict ) { + return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this ); + } + + return false; + } elseif ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod['object'] ) ) { + $pod['object'] = ''; + } + + if ( $pod instanceof Pod ) { + $pod = $pod->export( + [ + 'include_groups' => true, + 'include_fields' => false, + ] + ); + } + + if ( isset( $params->new_name ) ) { + $pod['name'] = $params->new_name; + } + + $try = 1; + + $check_name = $pod['name']; + $new_label = $pod['label']; + + while ( $this->load_pod( array( 'name' => $check_name ), false ) ) { + $try ++; + + $check_name = $pod['name'] . $try; + $new_label = $pod['label'] . $try; + } + + $pod['name'] = $check_name; + $pod['label'] = $new_label; + + $groups = $pod['groups']; + + unset( $pod['id'], $pod['parent'], $pod['object_type'], $pod['storage_type'], $pod['groups'] ); + + try { + $pod_id = $this->save_pod( $pod ); + } catch ( Exception $exception ) { + return false; + } + + if ( ! is_int( $pod_id ) ) { + return false; + } + + foreach ( $groups as $group => $group_data ) { + $fields = $group_data['fields']; + + unset( $group_data['id'], $group_data['parent'], $group_data['object_type'], $group_data['storage_type'], $group_data['fields'] ); + + $group_data['pod_id'] = $pod_id; + + $group_id = $this->save_group( $group_data ); + + foreach ( $fields as $field => $field_data ) { + unset( $field_data['id'], $field_data['parent'], $field_data['object_type'], $field_data['storage_type'], $field_data['group'] ); + + $field_data['pod_id'] = $pod_id; + $field_data['group_id'] = $group_id; + + try { + $this->save_field( $field_data ); + } catch ( Exception $exception ) { + // Field not saved. + } } } + + return $pod_id; } /** - * Duplicate a Pod + * Duplicate a Group. * - * $params['id'] int The Pod ID - * $params['name'] string The Pod name - * $params['new_name'] string The new Pod name + * $params['id'] int The Group ID. + * $params['name'] string The Group name. + * $params['new_name'] string The new Group name. * - * @param array $params An associative array of parameters - * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error + * @since 2.8.0 * - * @return int New Pod ID - * @since 2.3.0 + * @param array $params An associative array of parameters. + * @param bool $strict (optional) Makes sure a group exists, if it doesn't throws an error. + * + * @return int|false New Group ID or false if not successful. */ - public function duplicate_pod( $params, $strict = false ) { + public function duplicate_group( $params, $strict = false ) { if ( ! is_object( $params ) && ! is_array( $params ) ) { if ( is_numeric( $params ) ) { @@ -4609,68 +5995,95 @@ public function duplicate_pod( $params, $strict = false ) { $params = (object) pods_sanitize( $params ); } - $params->table_info = false; + if ( ! empty( $params->pod_id ) ) { + $load_params['parent'] = $params->pod_id; + } elseif ( ! empty( $params->pod ) ) { + $load_params['pod'] = $params->pod; + } - $pod = $this->load_pod( $params, $strict ); + $group = $this->load_group( $params, false ); - if ( empty( $pod ) ) { + if ( empty( $group ) ) { if ( false !== $strict ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); + return pods_error( __( 'Group not found', 'pods' ), $this ); } return false; - } elseif ( in_array( $pod['type'], array( 'media', 'user', 'comment' ) ) ) { - if ( false !== $strict ) { - return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this ); - } + } - return false; - } elseif ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod['object'] ) ) { - $pod['object'] = ''; + if ( $group instanceof Group ) { + $group = $group->export( + [ + 'include_fields' => true, + ] + ); } - unset( $pod['id'] ); + unset( $group['id'] ); if ( isset( $params->new_name ) ) { - $pod['name'] = $params->new_name; + $group['name'] = $params->new_name; } $try = 1; - $check_name = $pod['name']; - $new_label = $pod['label']; + $check_name = $group['name']; + $new_label = $group['label']; - while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) { + while ( $this->load_group( array( 'name' => $check_name ), false ) ) { $try ++; - $check_name = $pod['name'] . $try; - $new_label = $pod['label'] . $try; + $check_name = $group['name'] . $try; + $new_label = $group['label'] . $try; } - $pod['name'] = $check_name; - $pod['label'] = $new_label; + $group['name'] = $check_name; + $group['label'] = $new_label; + + $fields = $group['fields']; + + unset( $group['id'], $group['parent'], $group['object_type'], $group['storage_type'], $group['fields'] ); + + try { + $group_id = $this->save_group( $group ); + } catch ( Exception $exception ) { + return false; + } + + if ( ! is_int( $group_id ) ) { + return false; + } + + foreach ( $fields as $field => $field_data ) { + unset( $field_data['id'], $field_data['parent'], $field_data['object_type'], $field_data['storage_type'], $field_data['group'] ); - foreach ( $pod['fields'] as $field => $field_data ) { - unset( $pod['fields'][ $field ]['id'] ); + $field_data['group_id'] = $group_id; + + try { + $this->save_field( $field_data ); + } catch ( Exception $exception ) { + // Field not saved. + } } - return $this->save_pod( $pod ); + return $group_id; } /** - * Duplicate a Field + * Duplicate a Field. * - * $params['pod_id'] int The Pod ID - * $params['pod'] string The Pod name - * $params['id'] int The Field ID - * $params['name'] string The Field name - * $params['new_name'] string The new Field name - * - * @param array $params An associative array of parameters - * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error + * $params['pod_id'] int The Pod ID. + * $params['pod'] string The Pod name. + * $params['id'] int The Field ID. + * $params['name'] string The Field name. + * $params['new_name'] string The new Field name. * - * @return int New Field ID * @since 2.3.10 + * + * @param array $params An associative array of parameters. + * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error. + * + * @return int|false New Field ID or false if not successful. */ public function duplicate_field( $params, $strict = false ) { @@ -4684,9 +6097,21 @@ public function duplicate_field( $params, $strict = false ) { $params = (object) pods_sanitize( $params ); - $params->table_info = false; + $load_params = array(); + + if ( ! empty( $params->pod_id ) ) { + $load_params['parent'] = $params->pod_id; + } elseif ( ! empty( $params->pod ) ) { + $load_params['pod'] = $params->pod; + } + + if ( ! empty( $params->id ) ) { + $load_params['id'] = $params->id; + } elseif ( ! empty( $params->name ) ) { + $load_params['name'] = $params->name; + } - $field = $this->load_field( $params, $strict ); + $field = $this->load_field( $load_params, $strict ); if ( empty( $field ) ) { if ( false !== $strict ) { @@ -4696,7 +6121,9 @@ public function duplicate_field( $params, $strict = false ) { return false; } - unset( $field['id'] ); + if ( $field instanceof Field ) { + $field = $field->export(); + } if ( isset( $params->new_name ) ) { $field['name'] = $params->new_name; @@ -4708,9 +6135,8 @@ public function duplicate_field( $params, $strict = false ) { $new_label = $field['label']; while ( $this->load_field( array( - 'pod_id' => $field['pod_id'], - 'name' => $check_name, - 'table_info' => false + 'parent' => $field['pod_id'], + 'name' => $check_name, ), false ) ) { $try ++; @@ -4721,6 +6147,8 @@ public function duplicate_field( $params, $strict = false ) { $field['name'] = $check_name; $field['label'] = $new_label; + unset( $field['id'], $field['object_type'], $field['storage_type'] ); + return $this->save_field( $field, true, true ); } @@ -4744,11 +6172,10 @@ public function duplicate_pod_item( $params ) { $params = (object) pods_sanitize( $params ); $load_pod_params = array( - 'name' => $params->pod, - 'table_info' => false, + 'name' => $params->pod, ); - $pod = $this->load_pod( $load_pod_params ); + $pod = $this->load_pod( $load_pod_params, false ); if ( false === $pod ) { return pods_error( __( 'Pod not found', 'pods' ), $this ); @@ -4759,8 +6186,8 @@ public function duplicate_pod_item( $params ) { $params->pod = $pod->pod; $params->pod_id = $pod->pod_id; - $fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true ); - $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true ); + $fields = (array) pods_v( 'fields', $pod->pod_data, [], true ); + $object_fields = (array) pods_v( 'object_fields', $pod->pod_data, [], true ); if ( ! empty( $object_fields ) ) { $fields = array_merge( $object_fields, $fields ); @@ -4777,7 +6204,7 @@ public function duplicate_pod_item( $params ) { $pod->pod_data['field_slug'], ); - if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ) ) ) { + if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ), true ) ) { $ignore_fields = array( 'ID', 'post_name', @@ -4921,7 +6348,7 @@ private function export_pod_item_level( $pod, $params ) { $tableless_field_types = PodsForm::tableless_field_types(); $simple_tableless_objects = PodsForm::simple_tableless_objects(); - $object_fields = (array) pods_v( 'object_fields', $pod->pod_data, array(), true ); + $object_fields = (array) is_object( $pod->pod_data ) ? $pod->pod_data->get_object_fields() : pods_v( 'object_fields', $pod->pod_data, [], true ); $export_fields = array(); @@ -4943,7 +6370,7 @@ private function export_pod_item_level( $pod, $params ) { // If in rest, check if this pod can be exposed if ( 'rest' === $context ) { - $read_all = (int) pods_v( 'read_all', $pod->pod_data['options'], 0 ); + $read_all = (int) pods_v( 'read_all', $pod->pod_data, 0 ); if ( 1 === $read_all ) { $show_in_rest = true; @@ -4951,7 +6378,9 @@ private function export_pod_item_level( $pod, $params ) { } foreach ( $fields as $k => $field ) { - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $field = array( 'id' => 0, 'name' => $field @@ -4975,11 +6404,13 @@ private function export_pod_item_level( $pod, $params ) { } } - $field = $pod->fields[ $field['name'] ]; + $field = $pod->fields( $field['name'] ); $field['lookup_name'] = $field['name']; - if ( in_array( $field['type'], $tableless_field_types, true ) && ! in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ) { - if ( 'pick' === $field['type'] ) { + $field_type = pods_v( 'type', $field, 'text' ); + + if ( in_array( $field_type, $tableless_field_types, true ) && ! in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ) { + if ( 'pick' === $field_type ) { if ( empty( $field['table_info'] ) ) { $field['table_info'] = $this->get_table_info( pods_v( 'pick_object', $field ), pods_v( 'pick_val', $field ), null, null, $field ); } @@ -4987,7 +6418,7 @@ private function export_pod_item_level( $pod, $params ) { if ( ! empty( $field['table_info'] ) && 'table' !== $field['table_info']['object_type'] ) { $field['lookup_name'] .= '.' . $field['table_info']['field_id']; } - } elseif ( in_array( $field['type'], PodsForm::file_field_types() ) ) { + } elseif ( in_array( $field_type, PodsForm::file_field_types(), true ) ) { $field['lookup_name'] .= '.guid'; } } @@ -4998,7 +6429,7 @@ private function export_pod_item_level( $pod, $params ) { $field['lookup_name'] = $field['name']; $export_fields[ $field['name'] ] = $field; - } elseif ( $field['name'] == $pod->pod_data['field_id'] ) { + } elseif ( $field['name'] === $pod->pod_data['field_id'] ) { $field['type'] = 'number'; $field['lookup_name'] = $field['name']; @@ -5010,9 +6441,9 @@ private function export_pod_item_level( $pod, $params ) { foreach ( $export_fields as $field ) { // Return IDs (or guid for files) if only one level deep - if ( 1 == $depth ) { + if ( 1 === $depth ) { $data[ $field['name'] ] = $pod->field( array( 'name' => $field['lookup_name'], 'output' => 'arrays' ) ); - } elseif ( ( - 1 == $depth || $current_depth < $depth ) && 'pick' === $field['type'] && ! in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) { + } elseif ( ( - 1 === $depth || $current_depth < $depth ) && 'pick' === $field['type'] && ! in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ) { // Recurse depth levels for pick fields if $depth allows $related_data = array(); @@ -5021,15 +6452,15 @@ private function export_pod_item_level( $pod, $params ) { if ( ! empty( $related_ids ) ) { $related_ids = (array) $related_ids; - $pick_object = pods_var_raw( 'pick_object', $field ); + $pick_object = pods_v( 'pick_object', $field ); - $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false ); + $related_pod = pods( pods_v( 'pick_val', $field ), null, false ); // If this isn't a Pod, return data exactly as Pods does normally - if ( empty( $related_pod ) || empty( $related_pod->pod_data ) || ( 'pod' !== $pick_object && $pick_object !== pods_v( 'type', $related_pod->pod_data, null ) ) || $related_pod->pod == $pod->pod ) { + if ( empty( $related_pod ) || empty( $related_pod->pod_data ) || ( 'pod' !== $pick_object && $pick_object !== $related_pod->pod_data['type'] ) || $related_pod->pod === $pod->pod ) { $related_data = $pod->field( array( 'name' => $field['name'], 'output' => 'arrays' ) ); } else { - $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true ); + $related_object_fields = (array) pods_v( 'object_fields', $related_pod->pod_data, [], true ); $related_fields = array_merge( $related_pod->fields, $related_object_fields ); @@ -5102,16 +6533,7 @@ public function reorder_pod_item( $params ) { $params = (object) pods_sanitize( $params ); - // @deprecated 2.0.0 - if ( isset( $params->datatype ) ) { - pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' ); - - $params->pod = $params->datatype; - - unset( $params->datatype ); - } - - if ( null === pods_var_raw( 'pod', $params, null, null, true ) ) { + if ( null === pods_v( 'pod', $params, null, true ) ) { return pods_error( __( '$params->pod is required', 'pods' ), $this ); } @@ -5119,17 +6541,17 @@ public function reorder_pod_item( $params ) { $params->order = explode( ',', $params->order ); } - $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) ); - - $params->name = $pod['name']; + $pod = $this->load_pod( array( 'name' => $params->pod ), false ); if ( false === $pod ) { return pods_error( __( 'Pod is required', 'pods' ), $this ); } + $params->name = $pod['name']; + foreach ( $params->order as $order => $id ) { if ( isset( $pod['fields'][ $params->field ] ) || isset( $pod['object_fields'][ $params->field ] ) ) { - if ( 'table' === $pod['storage'] && ( ! pods_tableless() ) ) { + if ( 'table' === $pod['storage'] && ! pods_tableless() ) { if ( isset( $pod['fields'][ $params->field ] ) ) { pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" ); } else { @@ -5167,20 +6589,21 @@ public function reorder_pod_item( $params ) { * @since 1.9.0 */ public function reset_pod( $params, $pod = false ) { - - $params = (object) pods_sanitize( $params ); - - $params->table_info = true; - if ( empty( $pod ) ) { - $pod = $this->load_pod( $params ); + $pod = $this->load_pod( $params, false ); } if ( false === $pod ) { return pods_error( __( 'Pod not found', 'pods' ), $this ); } - $params->id = $pod['id']; + if ( is_array( $params ) || is_object( $params ) ) { + $params = (object) pods_sanitize( $params ); + } else { + $params = new stdClass(); + } + + $params->id = (int) $pod['id']; $params->name = $pod['name']; if ( ! pods_tableless() ) { @@ -5195,14 +6618,23 @@ public function reset_pod( $params, $pod = false ) { } } + } + + if ( pods_podsrel_enabled() ) { pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false ); } // @todo Delete relationships from tableless relationships - // Delete all posts/revisions from this post type - if ( in_array( $pod['type'], array( 'post_type', 'media' ) ) ) { - $type = pods_var( 'object', $pod, $pod['name'], null, true ); + if ( in_array( $pod['type'], [ 'post_type', 'media' ], true ) ) { + // Delete all posts/revisions from this post type. + $type = $pod['name']; + + if ( ! empty( $pod['object'] ) ) { + $type = $pod['object']; + } + + $type = pods_sanitize( $type ); $sql = " DELETE `t`, `r`, `m` @@ -5216,7 +6648,7 @@ public function reset_pod( $params, $pod = false ) { pods_query( $sql, false ); } elseif ( 'taxonomy' === $pod['type'] ) { - // Delete all terms from this taxonomy + // Delete all terms from this taxonomy. if ( function_exists( 'get_term_meta' ) ) { $sql = " DELETE `t`, `m`, `tt`, `tr` @@ -5251,7 +6683,13 @@ public function reset_pod( $params, $pod = false ) { pods_query( $sql, false ); } elseif ( 'comment' === $pod['type'] ) { // Delete all comments - $type = pods_var( 'object', $pod, $pod['name'], null, true ); + $type = $pod['name']; + + if ( ! empty( $pod['object'] ) ) { + $type = $pod['object']; + } + + $type = pods_sanitize( $type ); $sql = " DELETE `t`, `m` @@ -5275,9 +6713,9 @@ public function reset_pod( $params, $pod = false ) { * $params['id'] int The Pod ID * $params['name'] string The Pod name * - * @param array $params An associative array of parameters - * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error - * @param bool $delete_all (optional) Whether to delete all content from a WP object + * @param array|string|int $params An associative array of parameters, the pod name, or pod ID. + * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error + * @param bool $delete_all (optional) Whether to delete all content from a WP object * * @uses PodsAPI::load_pod * @uses wp_delete_post @@ -5287,31 +6725,7 @@ public function reset_pod( $params, $pod = false ) { * @since 1.7.9 */ public function delete_pod( $params, $strict = false, $delete_all = false ) { - - /** - * @var $wpdb wpdb - */ - global $wpdb; - - if ( ! is_object( $params ) && ! is_array( $params ) ) { - if ( is_numeric( $params ) ) { - $params = array( 'id' => $params ); - } else { - $params = array( 'name' => $params ); - } - - $params = (object) pods_sanitize( $params ); - } else { - $params = (object) pods_sanitize( $params ); - } - - if ( ! isset( $params->delete_all ) ) { - $params->delete_all = $delete_all; - } - - $params->table_info = false; - - $pod = $this->load_pod( $params, $strict ); + $pod = $this->load_pod( $params, false ); if ( empty( $pod ) ) { if ( false !== $strict ) { @@ -5321,331 +6735,153 @@ public function delete_pod( $params, $strict = false, $delete_all = false ) { return false; } - $params->id = (int) $pod['id']; - $params->name = $pod['name']; - - // Reset content - if ( true === $params->delete_all ) { - $this->reset_pod( $params, $pod ); - } - - foreach ( $pod['fields'] as $field ) { - $field['pod'] = $pod; - - $this->delete_field( $field, false ); - } - - // Only delete the post once the fields are taken care of, it's not required anymore - $success = wp_delete_post( $params->id ); - - if ( ! $success ) { - return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this ); - } - - if ( ! pods_tableless() ) { - if ( 'table' === $pod['storage'] ) { - try { - pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false ); - } catch ( Exception $e ) { - // Allow pod to be deleted if the table doesn't exist - if ( false === strpos( $e->getMessage(), 'Unknown table' ) ) { - return pods_error( $e->getMessage(), $this ); - } - } - } - - pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false ); - } - - // @todo Delete relationships from tableless relationships - - // Delete any relationship references - $sql = " - DELETE `pm` - FROM `{$wpdb->postmeta}` AS `pm` - LEFT JOIN `{$wpdb->posts}` AS `p` - ON `p`.`post_type` = '_pods_field' - AND `p`.`ID` = `pm`.`post_id` - LEFT JOIN `{$wpdb->postmeta}` AS `pm2` - ON `pm2`.`meta_key` = 'pick_object' - AND `pm2`.`meta_value` = 'pod' - AND `pm2`.`post_id` = `pm`.`post_id` - WHERE - `p`.`ID` IS NOT NULL - AND `pm2`.`meta_id` IS NOT NULL - AND `pm`.`meta_key` = 'pick_val' - AND `pm`.`meta_value` = '{$params->name}' - "; - - pods_query( $sql ); - - $this->cache_flush_pods( $pod ); - - return true; - } - - /** - * Drop a field within a Pod - * - * $params['id'] int The field ID - * $params['name'] int The field name - * $params['pod'] string The Pod name - * $params['pod_id'] string The Pod name - * - * @param array $params An associative array of parameters - * @param bool $table_operation Whether or not to handle table operations - * - * @uses PodsAPI::load_field - * @uses wp_delete_post - * @uses pods_query - * - * @return bool - * @since 1.7.9 - */ - public function delete_field( $params, $table_operation = true ) { - /** * @var $wpdb wpdb */ global $wpdb; - $tableless_field_types = PodsForm::tableless_field_types(); - $simple_tableless_objects = PodsForm::simple_tableless_objects(); - - $params = (object) pods_sanitize( $params ); - - if ( ! isset( $params->pod ) ) { - $params->pod = ''; - } - - if ( ! isset( $params->pod_id ) ) { - $params->pod_id = 0; - } - - $pod = $params->pod; - - $save_pod = false; - - if ( ! is_array( $pod ) ) { - $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) ); + if ( is_array( $params ) || is_object( $params ) ) { + $params = (object) pods_sanitize( $params ); } else { - $save_pod = true; - } - - if ( empty( $pod ) ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } - - $params->pod_id = $pod['id']; - $params->pod = $pod['name']; - - if ( ! isset( $params->name ) ) { - $params->name = ''; - } - - if ( ! isset( $params->id ) ) { - $params->id = 0; - } - - $field = $this->load_field( array( - 'name' => $params->name, - 'id' => $params->id, - 'pod' => $params->pod, - 'pod_id' => $params->pod_id - ) ); - - if ( false === $field ) { - return pods_error( __( 'Field not found', 'pods' ), $this ); + $params = new stdClass(); } - $params->id = $field['id']; - $params->name = $field['name']; + $params->id = (int) $pod['id']; + $params->name = $pod['name']; - $simple = ( 'pick' === $field['type'] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ); - $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params ); + $type = $pod['name']; - if ( $table_operation && 'table' === $pod['storage'] && ( ! in_array( $field['type'], $tableless_field_types ) || $simple ) ) { - pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false ); + if ( ! empty( $pod['object'] ) ) { + $type = $pod['object']; } - $success = wp_delete_post( $params->id ); - - if ( ! $success ) { - return pods_error( __( 'Field unable to be deleted', 'pods' ), $this ); + if ( ! isset( $params->delete_all ) ) { + $params->delete_all = $delete_all; } - $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm - LEFT JOIN {$wpdb->posts} AS p - ON p.post_type = '_pods_field' AND p.ID = pm.post_id - WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) ); + $params->delete_all = (boolean) $params->delete_all; - if ( ( ! pods_tableless() ) && $table_operation ) { - pods_query( "DELETE FROM `@wp_podsrel` WHERE (`pod_id` = {$params->pod_id} AND `field_id` = {$params->id}) OR (`related_pod_id` = {$params->pod_id} AND `related_field_id` = {$params->id})", false ); + // Reset content + if ( true === $params->delete_all ) { + $this->reset_pod( $params, $pod ); } - // @todo Delete tableless relationship meta + foreach ( $pod['fields'] as $field ) { + $delete_field = array( + 'id' => $field->get_id(), + 'name' => $field->get_name(), + 'pod' => $pod, + ); - if ( true === $save_pod ) { - $this->cache_flush_pods( $pod ); + $this->delete_field( $delete_field, false ); } - return true; - } + $object_collection = Pods\Whatsit\Store::get_instance(); - /** - * Drop a Pod Object - * - * $params['id'] int The object ID - * $params['name'] string The object name - * $params['type'] string The object type - * - * @param array|object $params An associative array of parameters - * - * @uses wp_delete_post - * - * @return bool - * @since 2.0.0 - */ - public function delete_object( $params ) { + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); - $params = (object) $params; - $object = $this->load_object( $params ); + $object = $post_type_storage->to_object( $params->id ); - if ( empty( $object ) ) { - return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this ); - } + $success = false; - $success = wp_delete_post( $params->id ); + if ( $object ) { + $success = $post_type_storage->delete( $object ); + } if ( ! $success ) { - return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this ); + return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this ); } - pods_transient_clear( 'pods_objects_' . $params->type ); - - return true; - } + // @todo Push this logic into pods_object_storage_delete_pod action. + if ( ! pods_tableless() ) { + if ( 'table' === $pod['storage'] ) { + try { + pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false ); + } catch ( Exception $e ) { + // Allow pod to be deleted if the table doesn't exist + if ( false === strpos( $e->getMessage(), 'Unknown table' ) ) { + return pods_error( $e->getMessage(), $this ); + } + } + } - /** - * @see PodsAPI::delete_object - * - * Drop a Pod Template - * - * $params['id'] int The template ID - * $params['name'] string The template name - * - * @param array $params An associative array of parameters - * - * @return bool - * @since 1.7.9 - */ - public function delete_template( $params ) { + if ( pods_podsrel_enabled() ) { + pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false ); + } + } - $params = (object) $params; - $params->type = 'template'; + // @todo Delete relationships from tableless relationships - return $this->delete_object( $params ); - } + // Delete any relationship references + $sql = " + DELETE `pm` + FROM `{$wpdb->postmeta}` AS `pm` + LEFT JOIN `{$wpdb->posts}` AS `p` + ON `p`.`post_type` = '_pods_field' + AND `p`.`ID` = `pm`.`post_id` + LEFT JOIN `{$wpdb->postmeta}` AS `pm2` + ON `pm2`.`meta_key` = 'pick_object' + AND `pm2`.`meta_value` = 'pod' + AND `pm2`.`post_id` = `pm`.`post_id` + WHERE + `p`.`ID` IS NOT NULL + AND `pm2`.`meta_id` IS NOT NULL + AND `pm`.`meta_key` = 'pick_val' + AND `pm`.`meta_value` = '{$type}' + "; - /** - * @see PodsAPI::delete_object - * - * Drop a Pod Page - * - * $params['id'] int The page ID - * $params['uri'] string The page URI - * - * @param array $params An associative array of parameters - * - * @return bool - * @since 1.7.9 - */ - public function delete_page( $params ) { + pods_query( $sql ); - $params = (object) $params; - if ( isset( $params->uri ) ) { - $params->name = $params->uri; - unset( $params->uri ); - } - if ( isset( $params->name ) ) { - $params->name = trim( $params->name, '/' ); - } - $params->type = 'page'; + $this->cache_flush_pods( $pod ); - return $this->delete_object( $params ); + return true; } /** - * @see PodsAPI::delete_object - * - * Drop a Pod Helper - * - * $params['id'] int The helper ID - * $params['name'] string The helper name - * - * @param array $params An associative array of parameters + * Drop a field within a Pod * - * @return bool - * @since 1.7.9 - */ - public function delete_helper( $params ) { - - $params = (object) $params; - $params->type = 'helper'; - - return $this->delete_object( $params ); - } - - /** - * Drop a single pod item + * $params['id'] int The field ID + * $params['name'] int The field name + * $params['pod'] string The Pod name + * $params['pod_id'] string The Pod name * - * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter) - * $params['pod'] string (optional) The Pod name (used with id parameter) - * $params['pod_id'] int (optional) The Pod ID (used with id parameter) - * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers + * @param array|object|Field $params An associative array or object of parameters, or the Field object itself. + * @param bool $table_operation Whether or not to handle table operations. * - * @param array $params An associative array of parameters - * @param bool $wp Whether to run WP object delete action + * @uses PodsAPI::load_field + * @uses wp_delete_post + * @uses pods_query * * @return bool * @since 1.7.9 */ - public function delete_pod_item( $params, $wp = true ) { - - $params = (object) pods_sanitize( $params ); - - // @deprecated 2.0.0 - if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) { - if ( isset( $params->tbl_row_id ) ) { - pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' ); - $params->id = $params->tbl_row_id; - unset( $params->tbl_row_id ); - } + public function delete_field( $params, $table_operation = true ) { - if ( isset( $params->pod_id ) ) { - pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' ); - $params->id = $params->pod_id; - unset( $params->pod_id ); - } + /** + * @var $wpdb wpdb + */ + global $wpdb; - if ( isset( $params->dataype_id ) ) { - pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' ); - $params->pod_id = $params->dataype_id; - unset( $params->dataype_id ); - } + $tableless_field_types = PodsForm::tableless_field_types(); + $simple_tableless_objects = PodsForm::simple_tableless_objects(); + $field = null; + $pod = null; - if ( isset( $params->datatype ) ) { - pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' ); - $params->pod = $params->datatype; - unset( $params->datatype ); - } - } + // Check if the params is a field. + if ( $params instanceof Field ) { + $field = $params; + $pod = $field->get_parent_object(); - if ( ! isset( $params->id ) ) { - return pods_error( __( 'Pod Item not found', 'pods' ), $this ); + $params = [ + 'name' => $field->get_name(), + 'id' => $field->get_id(), + 'pod' => $field->get_parent(), + 'pod_id' => $field->get_parent_id(), + ]; } - $params->id = pods_absint( $params->id ); + $params = (object) $params; if ( ! isset( $params->pod ) ) { $params->pod = ''; @@ -5655,1056 +6891,927 @@ public function delete_pod_item( $params, $wp = true ) { $params->pod_id = 0; } - $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) ); - - if ( false === $pod ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } - - $params->pod_id = $pod['id']; - $params->pod = $pod['name']; - - // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls - $bypass_helpers = false; - - if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers ) { - $bypass_helpers = true; + if ( ! $pod ) { + $pod = $params->pod; } - $pre_delete_helpers = array(); - $post_delete_helpers = array(); - - if ( false === $bypass_helpers ) { - // Plugin hook - $this->do_hook( 'pre_delete_pod_item', $params, $pod ); - $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod ); - - // Call any pre-save helpers (if not bypassed) - if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) { - if ( ! empty( $pod['options'] ) && is_array( $pod['options'] ) ) { - $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' ); + $save_pod = false; - foreach ( $helpers as $helper ) { - if ( isset( $pod['options'][ $helper ] ) && ! empty( $pod['options'][ $helper ] ) ) { - ${$helper} = explode( ',', $pod['options'][ $helper ] ); - } - } - } + if ( ! ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) ) { + $load_params = array(); - if ( ! empty( $pre_delete_helpers ) ) { - pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' ); + if ( ! empty( $params->pod_id ) ) { + $load_params['id'] = $params->pod_id; + } elseif ( is_int( $pod ) && ! empty( $pod ) ) { + $load_params['id'] = $pod; + } elseif ( ! empty( $params->pod ) ) { + $load_params['name'] = $params->pod; + } elseif ( is_string( $pod ) && 0 < strlen( $pod ) ) { + $load_params['name'] = $pod; + } - foreach ( $pre_delete_helpers as $helper ) { - $helper = $this->load_helper( array( 'name' => $helper ) ); + $pod = false; - if ( false !== $helper ) { - eval( '?>' . $helper['code'] ); - } - } - } + if ( $load_params ) { + $pod = $this->load_pod( $load_params, false ); } + } else { + $save_pod = true; } - // Delete object from relationship fields - $this->delete_object_from_relationships( $params->id, $pod ); - - if ( 'table' === $pod['storage'] ) { - pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" ); + if ( empty( $pod ) && empty( $params->id ) ) { + return pods_error( __( 'Pod not found', 'pods' ), $this ); } - if ( $wp ) { - if ( 'taxonomy' === $pod['type'] ) { - $taxonomy = $pod['name']; - - if ( ! empty( $pod['object'] ) ) { - $taxonomy = $pod['object']; - } - - wp_delete_term( $params->id, $taxonomy ); - } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) { - $this->delete_wp_object( $pod['type'], $params->id ); - } + if ( $pod ) { + $params->pod_id = $pod['id']; + $params->pod = $pod['name']; } - if ( false === $bypass_helpers ) { - // Plugin hook - $this->do_hook( 'post_delete_pod_item', $params, $pod ); - $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod ); - - // Call any post-save helpers (if not bypassed) - if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) { - if ( ! empty( $post_delete_helpers ) ) { - pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' ); - - foreach ( $post_delete_helpers as $helper ) { - $helper = $this->load_helper( array( 'name' => $helper ) ); + $params = pods_sanitize( $params ); - if ( false !== $helper ) { - eval( '?>' . $helper['code'] ); - } - } - } - } + if ( ! isset( $params->name ) ) { + $params->name = ''; } - pods_cache_clear( $params->id, 'pods_items_' . $params->pod ); + if ( ! isset( $params->id ) ) { + $params->id = 0; + } - return true; - } + if ( ! $field ) { + $load_params = []; - /** - * Delete an object from tableless fields - * - * @param int $id - * @param string $type - * @param string $name - * - * @return bool - * - * @since 2.3.0 - */ - public function delete_object_from_relationships( $id, $object, $name = null ) { + if ( $params->pod_id ) { + $load_params['parent'] = $params->pod_id; + } - /** - * @var $pods_init \PodsInit - * @todo Use pods_init() function? - */ - global $pods_init; + if ( ! empty( $params->id ) ) { + $load_params['id'] = $params->id; + } elseif ( ! empty( $params->name ) ) { + $load_params['name'] = $params->name; + } - $pod = false; + $field = $this->load_field( $load_params ); - // Run any bidirectional delete operations - if ( is_array( $object ) ) { - $pod = $object; - } elseif ( is_object( $pods_init ) ) { - $pod = PodsInit::$meta->get_object( $object, $name ); + if ( false === $field ) { + return pods_error( __( 'Field not found', 'pods' ), $this ); + } } + $params->id = $field['id']; + $params->name = $field['name']; - if ( ! empty( $pod ) ) { - $object = $pod['type']; - $name = $pod['name']; + // Get the pod from the field if pod information not provided. + if ( false === $pod ) { + $pod = $field->get_parent_object(); - foreach ( $pod['fields'] as $field ) { - PodsForm::delete( $field['type'], $id, $field['name'], array_merge( $field, $field['options'] ), $pod ); + if ( $pod ) { + $params->pod_id = $pod['id']; + $params->pod = $pod['name']; } } - // Lookup related fields (non-bidirectional) - $params = array( - 'where' => array( - array( - 'key' => 'type', - 'value' => 'pick' - ), - array( - 'key' => 'pick_object', - 'value' => $object - ) - ) - ); + $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ); + $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params ); - if ( ! empty( $name ) && $name !== $object ) { - $params['where'][] = array( - 'key' => 'pick_val', - 'value' => $name - ); + // @todo Push this logic into pods_object_storage_delete_pod action. + if ( $table_operation && $pod && 'table' === $pod['storage'] && ( ! in_array( $field['type'], $tableless_field_types, true ) || $simple ) ) { + pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false ); } - $fields = $this->load_fields( $params, false ); - - if ( ! empty( $pod ) && 'media' === $pod['type'] ) { - $params['where'] = array( - array( - 'key' => 'type', - 'value' => 'file' - ) - ); + $object_collection = Pods\Whatsit\Store::get_instance(); - $fields = array_merge( $fields, $this->load_fields( $params, false ) ); - } + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); - if ( is_array( $fields ) && ! empty( $fields ) ) { - foreach ( $fields as $related_field ) { - $related_pod = $this->load_pod( array( 'id' => $related_field['pod_id'], 'fields' => false ), false ); + $success = false; - if ( empty( $related_pod ) ) { - continue; - } + if ( $post_type_storage ) { + $object = $post_type_storage->to_object( $params->id ); - $related_from = $this->lookup_related_items_from( $related_field['id'], $related_pod['id'], $id, $related_field, $related_pod ); + if ( $object ) { + $success = $post_type_storage->delete( $object ); + } + } - $this->delete_relationships( $related_from, $id, $related_pod, $related_field ); - } + if ( ! $success ) { + return pods_error( __( 'Field unable to be deleted', 'pods' ), $this ); } - if ( ! empty( $pod ) && ! pods_tableless() ) { - pods_query( " - DELETE FROM `@wp_podsrel` - WHERE - ( - `pod_id` = %d - AND `item_id` = %d - ) - OR ( - `related_pod_id` = %d - AND `related_item_id` = %d - ) - ", array( - $pod['id'], - $id, + // @todo Push this logic into pods_object_storage_delete_pod action. + $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm + LEFT JOIN {$wpdb->posts} AS p + ON p.post_type = '_pods_field' AND p.ID = pm.post_id + WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) ); - $pod['id'], - $id - ) ); + if ( $table_operation && pods_podsrel_enabled() ) { + pods_query( "DELETE FROM `@wp_podsrel` WHERE (`pod_id` = {$params->pod_id} AND `field_id` = {$params->id}) OR (`related_pod_id` = {$params->pod_id} AND `related_field_id` = {$params->id})", false ); } + // @todo Delete tableless relationship meta + return true; } /** - * Delete relationships + * Delete a Pod and all its content * - * @param int|array $related_id IDs for items to save - * @param int|array $id ID or IDs to remove - * @param array $related_pod Pod data - * @param array $related_field Field data + * $params['id'] int The Group ID + * $params['name'] string The Group name + * $params['pod'] string|Pods\Whatsit\Pod The Pod name or object. + * $params['pod_id'] string The Pod ID. * - * @return void + * @since 2.8.0 * - * @since 2.3.0 + * @param array|string|int $params An associative array of parameters, the pod name, or pod ID. + * @param bool $strict (optional) Makes sure a group exists, if it doesn't throws an error. + * @param bool $delete_all (optional) Whether to delete all fields from the group too. + * + * @return bool Whether the group was deleted successfully. */ - public function delete_relationships( $related_id, $id, $related_pod, $related_field ) { + public function delete_group( $params, $strict = false, $delete_all = false ) { + /** + * @var $wpdb wpdb + */ + global $wpdb; - if ( is_array( $related_id ) ) { - foreach ( $related_id as $rid ) { - $this->delete_relationships( $rid, $id, $related_pod, $related_field ); + if ( ! is_object( $params ) && ! is_array( $params ) ) { + if ( is_numeric( $params ) ) { + $params = [ 'id' => $params ]; + } else { + $params = [ 'name' => $params ]; } - return; + $params = (object) pods_sanitize( $params ); + } else { + $params = (object) pods_sanitize( $params ); } - if ( is_array( $id ) ) { - foreach ( $id as $rid ) { - $this->delete_relationships( $related_id, $rid, $related_pod, $related_field ); - } - - return; + if ( ! isset( $params->delete_all ) ) { + $params->delete_all = (boolean) $delete_all; } - $id = (int) $id; - - if ( empty( $id ) ) { - return; - } + $group = $this->load_group( $params, false ); - $related_ids = $this->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); + if ( empty( $group ) ) { + if ( false !== $strict ) { + return pods_error( __( 'Group not found', 'pods' ), $this ); + } - if ( empty( $related_ids ) ) { - return; - } elseif ( ! in_array( $id, $related_ids ) ) { - return; + return false; } - if ( isset( self::$related_item_cache[ $related_pod['id'] ][ $related_field['id'] ] ) ) { - // Delete relationship from cache - unset( self::$related_item_cache[ $related_pod['id'] ][ $related_field['id'] ] ); - } + $pod = $group->get_parent(); - // @codingStandardsIgnoreLine - unset( $related_ids[ array_search( $id, $related_ids ) ] ); + $params->id = (int) $group['id']; + $params->name = $group['name']; - $no_conflict = pods_no_conflict_check( $related_pod['type'] ); + // Delete all fields. + if ( true === $params->delete_all ) { + foreach ( $group['fields'] as $field ) { + $delete_field = [ + 'id' => $field->get_id(), + 'name' => $field->get_name(), + 'pod' => $pod, + ]; - if ( ! $no_conflict ) { - pods_no_conflict_on( $related_pod['type'] ); + $this->delete_field( $delete_field, false ); + } } - // Post Types, Media, Users, and Comments (meta-based) - if ( in_array( $related_pod['type'], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) { - $object_type = $related_pod['type']; + $object_collection = Pods\Whatsit\Store::get_instance(); - if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) { - $object_type = 'post'; - } elseif ( 'taxonomy' === $object_type ) { - $object_type = 'term'; - } + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); - delete_metadata( $object_type, $related_id, $related_field['name'] ); + $object = $post_type_storage->to_object( $params->id ); - if ( ! empty( $related_ids ) ) { - update_metadata( $object_type, $related_id, '_pods_' . $related_field['name'], $related_ids ); + $success = false; - foreach ( $related_ids as $rel_id ) { - add_metadata( $object_type, $related_id, $related_field['name'], $rel_id ); - } - } else { - delete_metadata( $object_type, $related_id, '_pods_' . $related_field['name'] ); - } - } elseif ( 'settings' === $related_pod['type'] ) { - // Custom Settings Pages (options-based) - if ( ! empty( $related_ids ) ) { - update_option( $related_pod['name'] . '_' . $related_field['name'], $related_ids ); - } else { - delete_option( $related_pod['name'] . '_' . $related_field['name'] ); - } + if ( $object ) { + $success = $post_type_storage->delete( $object ); } - // Relationships table - if ( ! pods_tableless() ) { - pods_query( " - DELETE FROM `@wp_podsrel` - WHERE - ( - `pod_id` = %d - AND `field_id` = %d - AND `item_id` = %d - AND `related_item_id` = %d - ) - OR ( - `related_pod_id` = %d - AND `related_field_id` = %d - AND `related_item_id` = %d - AND `item_id` = %d - ) - ", array( - $related_pod['id'], - $related_field['id'], - $related_id, - $id, - - $related_pod['id'], - $related_field['id'], - $related_id, - $id - ) ); + if ( ! $success ) { + return pods_error( __( 'Group unable to be deleted', 'pods' ), $this ); } - if ( ! $no_conflict ) { - pods_no_conflict_off( $related_pod['type'] ); - } + return true; } /** - * Check if a Pod exists + * Drop a Pod Object * - * $params['id'] int Pod ID - * $params['name'] string Pod name + * $params['id'] int The object ID + * $params['name'] string The object name + * $params['type'] string The object type * - * @param array $params An associative array of parameters + * @param array|object $params An associative array of parameters * - * @return bool True if exists + * @uses wp_delete_post * - * @since 1.12 + * @return bool + * @since 2.0.0 */ - public function pod_exists( $params, $type = null ) { + public function delete_object( $params ) { + $object = $this->load_object( $params ); - if ( is_string( $params ) ) { - $params = array( 'name' => $params ); + if ( empty( $object ) ) { + return pods_error( sprintf( esc_html__( '%s Object not found', 'pods' ), ucwords( $params->type ) ), $this ); } - $params = (object) pods_sanitize( $params ); + $object_collection = Pods\Whatsit\Store::get_instance(); - if ( ! empty( $params->id ) || ! empty( $params->name ) ) { - if ( ! isset( $params->name ) ) { - $dummy = (int) $params->id; - $pod = get_post( $dummy ); - } else { - $pod = get_posts( array( - 'name' => $params->name, - 'post_type' => '_pods_pod', - 'posts_per_page' => 1 - ) ); + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); - if ( is_array( $pod ) && ! empty( $pod[0] ) ) { - $pod = $pod[0]; - } - } + $object = $post_type_storage->to_object( $params->id ); - if ( ! empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) ) { - return true; - } + $success = false; + + if ( $object ) { + $success = $post_type_storage->delete( $object ); + } + + if ( ! $success ) { + return pods_error( sprintf( esc_html__( '%s Object not deleted', 'pods' ), ucwords( $params->type ) ), $this ); } - return false; + pods_transient_clear( 'pods_objects_' . $params->type ); + + return true; } /** - * Get number of pods for a specific pod type + * @see PodsAPI::delete_object * - * @param string $type Type to get count + * Drop a Pod Template * - * @return int Total number of pods for a type + * $params['id'] int The template ID + * $params['name'] string The template name * - * @since 2.6.6 + * @param array $params An associative array of parameters + * + * @return bool + * @since 1.7.9 */ - public function get_pod_type_count( $type ) { + public function delete_template( $params ) { + $params = (object) $params; + $params->type = 'template'; - $args = array( - 'post_type' => '_pods_pod', - 'posts_per_page' => - 1, - 'nopaging' => true, - 'fields' => 'ids', - 'meta_query' => array( - array( - 'key' => 'type', - 'value' => $type, - ), - ), - ); + return $this->delete_object( $params ); + } - $posts = get_posts( $args ); + /** + * @see PodsAPI::delete_object + * + * Drop a Pod Page + * + * $params['id'] int The page ID + * $params['uri'] string The page URI + * + * @param array $params An associative array of parameters + * + * @return bool + * @since 1.7.9 + */ + public function delete_page( $params ) { + $params = (object) $params; + + if ( isset( $params->uri ) ) { + $params->name = $params->uri; - $total = count( $posts ); + unset( $params->uri ); + } + + if ( isset( $params->name ) ) { + $params->name = trim( $params->name, '/' ); + } + + $params->type = 'page'; - return $total; + return $this->delete_object( $params ); + } + /** + * @see PodsAPI::delete_object + * + * Drop a Pod Helper + * + * $params['id'] int The helper ID + * $params['name'] string The helper name + * + * @param array $params An associative array of parameters + * + * @return bool + * @since 1.7.9 + * + * @deprecated since 2.8.0 + */ + public function delete_helper( $params ) { + return false; } /** - * Load a Pod and all of its fields + * Drop a single pod item * - * $params['id'] int The Pod ID - * $params['name'] string The Pod name - * $params['fields'] bool Whether to load fields (default is true) - * $params['bypass_cache'] boolean Bypass the cache when getting data + * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter) + * $params['pod'] string (optional) The Pod name (used with id parameter) + * $params['pod_id'] int (optional) The Pod ID (used with id parameter) + * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers * - * @param array|object $params An associative array of parameters or pod name as a string - * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work + * @param array $params An associative array of parameters + * @param bool $wp Whether to run WP object delete action * - * @return array|bool|mixed|void + * @return bool * @since 1.7.9 */ - public function load_pod( $params, $strict = true ) { + public function delete_pod_item( $params, $wp = true ) { - /** - * @var $sitepress SitePress - * @var $wpdb wpdb - */ - global $wpdb; + $params = (object) $params; - $current_language = false; - $load_fields = true; - $bypass_cache = false; + if ( ! isset( $params->id ) ) { + return pods_error( __( 'Pod Item not found', 'pods' ), $this ); + } - // Get current language data - $lang_data = pods_i18n()->get_current_language_data(); + $params->id = pods_absint( $params->id ); - if ( $lang_data ) { - if ( ! empty( $lang_data['language'] ) ) { - $current_language = $lang_data['language']; - } + if ( ! isset( $params->pod ) ) { + $params->pod = ''; } - if ( ! is_array( $params ) && ! is_object( $params ) ) { - $params = array( 'name' => $params, 'table_info' => false, 'fields' => true ); + if ( ! isset( $params->pod_id ) ) { + $params->pod_id = 0; } - if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && isset( $params->fields ) && ! $params->fields ) { - $load_fields = false; - } elseif ( is_array( $params ) && isset( $params['fields'] ) && ! $params['fields'] ) { - $load_fields = false; + if ( ! isset( $params->strict ) ) { + $params->strict = true; } - $table_info = false; + $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id ), false ); + + if ( false === $pod ) { + if ( $params->strict ) { + return pods_error( __( 'Pod not found', 'pods' ), $this ); + } - if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->table_info ) ) { - $table_info = true; - } elseif ( is_array( $params ) && ! empty( $params['table_info'] ) ) { - $table_info = true; + return false; } - $transient = 'pods_' . $wpdb->prefix . '_pod'; + $params->pod_id = $pod['id']; + $params->pod = $pod['name']; - if ( ! empty( $current_language ) ) { - $transient .= '_' . $current_language; - } + $params = pods_sanitize( $params ); - if ( ! $load_fields ) { - $transient .= '_nofields'; - } + // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls + $bypass_helpers = false; - if ( $table_info ) { - $transient .= '_tableinfo'; + if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers ) { + $bypass_helpers = true; } - $check_pod = $params; + $pre_delete_helpers = array(); + $post_delete_helpers = array(); - if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->pod ) ) { - $check_pod = $params->pod; - } elseif ( is_array( $params ) && ! empty( $params['pod'] ) ) { - $check_pod = $params['pod']; - } + if ( false === $bypass_helpers ) { + // Plugin hook + $this->do_hook( 'pre_delete_pod_item', $params, $pod ); + $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod ); - if ( is_object( $check_pod ) && ( is_a( $check_pod, 'WP_Post' ) || isset( $check_pod->post_name ) ) ) { - $pod = false; + // Call any pre-save helpers (if not bypassed) + if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) { + if ( ! empty( $pod ) ) { + $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' ); - if ( pods_api_cache() ) { - $pod = pods_transient_get( $transient . '_' . $check_pod->post_name ); + foreach ( $helpers as $helper ) { + if ( isset( $pod[ $helper ] ) && ! empty( $pod[ $helper ] ) ) { + ${$helper} = explode( ',', $pod[ $helper ] ); + } + } + } } + } - if ( false !== $pod && ( ! $table_info || isset( $pod['table'] ) ) ) { - // @todo Is this needed anymore for WPML? - if ( in_array( $pod['type'], array( - 'post_type', - 'taxonomy' - ) ) && did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { - $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) ); - } + // Delete object from relationship fields + $this->delete_object_from_relationships( $params->id, $pod ); - return $pod; - } + if ( 'table' === $pod['storage'] ) { + pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" ); + } - $_pod = get_object_vars( $check_pod ); - } else { - $params = (object) pods_sanitize( $params ); + if ( $wp ) { + if ( 'taxonomy' === $pod['type'] ) { + $taxonomy = $pod['name']; - if ( ( ! isset( $params->id ) || empty( $params->id ) ) && ( ! isset( $params->name ) || empty( $params->name ) ) ) { - if ( $strict ) { - return pods_error( __( 'Either Pod ID or Name are required', 'pods' ), $this ); + if ( ! empty( $pod['object'] ) ) { + $taxonomy = $pod['object']; } - return false; + wp_delete_term( $params->id, $taxonomy ); + } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) { + $this->delete_wp_object( $pod['type'], $params->id ); } + } - if ( ! empty( $params->bypass_cache ) ) { - $bypass_cache = true; - } + if ( false === $bypass_helpers ) { + // Plugin hook + $this->do_hook( 'post_delete_pod_item', $params, $pod ); + $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod ); + } - if ( isset( $params->name ) ) { - $pod = false; + pods_cache_clear( $params->id, 'pods_items_' . $params->pod ); - if ( '_pods_pod' === $params->name ) { - $pod = array( - 'id' => 0, - 'name' => $params->name, - 'object' => $params->name, - 'label' => __( 'Pods', 'pods' ), - 'type' => 'post_type', - 'storage' => 'meta', - 'options' => array( - 'label_singular' => __( 'Pod', 'pods' ) - ), - 'fields' => array() - ); - } elseif ( '_pods_field' === $params->name ) { - $pod = array( - 'id' => 0, - 'name' => $params->name, - 'object' => $params->name, - 'label' => __( 'Pod Fields', 'pods' ), - 'type' => 'post_type', - 'storage' => 'meta', - 'options' => array( - 'label_singular' => __( 'Pod Field', 'pods' ) - ), - 'fields' => array() - ); - } elseif ( ! $bypass_cache & pods_api_cache() ) { - $pod = pods_transient_get( $transient . '_' . $params->name ); - } + return true; + } - if ( false !== $pod && ( ! $table_info || isset( $pod['table'] ) ) ) { - if ( in_array( $pod['type'], array( - 'post_type', - 'taxonomy' - ) ) && did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { - $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) ); - } + /** + * Delete an object from tableless fields. + * + * @param int $id + * @param string $type + * @param string $name + * + * @return bool + * + * @since 2.3.0 + */ + public function delete_object_from_relationships( $id, $object, $name = null ) { - return $pod; - } - } + /** + * @var $pods_init \PodsInit + * @todo Use pods_init() function? + */ + global $pods_init; - if ( ! isset( $params->name ) ) { - $dummy = (int) $params->id; - $pod = get_post( $dummy ); - } else { - $pod = get_posts( array( - 'name' => $params->name, - 'post_type' => '_pods_pod', - 'posts_per_page' => 1 - ) ); - } + $pod = false; - if ( empty( $pod ) ) { - if ( $strict ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } + // Run any bidirectional delete operations + if ( is_array( $object ) || $object instanceof Pods\Whatsit ) { + $pod = $object; + } elseif ( is_object( $pods_init ) ) { + $pod = PodsInit::$meta->get_object( $object, $name ); + } - return false; - } + if ( ! empty( $pod ) ) { + $object = $pod['type']; + $name = $pod['name']; - if ( is_array( $pod ) && ! empty( $pod[0] ) ) { - $pod = $pod[0]; + foreach ( $pod['fields'] as $field ) { + PodsForm::delete( $field['type'], $id, $field['name'], $field, $pod ); } - - $_pod = get_object_vars( $pod ); } - $pod = false; + // Lookup related fields (non-bidirectional) + $params = array( + 'args' => array( + 'type' => 'pick', + 'pick_object' => $object, + ), + ); - if ( ! $bypass_cache || pods_api_cache() ) { - $pod = pods_transient_get( $transient . '_' . $_pod['post_name'] ); + if ( ! empty( $name ) && $name !== $object ) { + $params['args']['pick_val'] = $name; } - if ( false !== $pod && ( ! $table_info || isset( $pod['table'] ) ) ) { - if ( in_array( $pod['type'], array( - 'post_type', - 'taxonomy' - ) ) && did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { - $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) ); + try { + $fields = $this->load_fields( $params ); + + if ( ! empty( $pod ) && 'media' === $pod['type'] ) { + $params['args']['type'] = 'file'; + + $fields = pods_config_merge_fields( $fields, $this->load_fields( $params ) ); } - return $pod; - } + if ( is_array( $fields ) && ! empty( $fields ) ) { + foreach ( $fields as $related_field ) { + $related_pod = $this->load_pod( [ 'id' => $related_field['pod_id'] ], false ); - $pod = array( - 'id' => $_pod['ID'], - 'name' => $_pod['post_name'], - 'label' => $_pod['post_title'], - 'description' => $_pod['post_content'] - ); + if ( empty( $related_pod ) ) { + continue; + } - if ( strlen( $pod['label'] ) < 1 ) { - $pod['label'] = $pod['name']; + $related_from = $this->lookup_related_items_from( $related_field['id'], $related_pod['id'], $id, $related_field, $related_pod ); + + $this->delete_relationships( $related_from, $id, $related_pod, $related_field ); + } + } + } catch ( Exception $exception ) { + // Nothing left to do here. } - // @todo update with a method to put all options in - $defaults = array( - 'show_in_menu' => 1, - 'type' => 'post_type', - 'storage' => 'meta', - 'object' => '', - 'alias' => '' - ); + if ( ! empty( $pod ) ) { + if ( pods_podsrel_enabled() ) { + pods_query( ' + DELETE FROM `@wp_podsrel` + WHERE + ( + `pod_id` = %d + AND `item_id` = %d + ) + OR ( + `related_pod_id` = %d + AND `related_item_id` = %d + ) + ', [ + $pod['id'], + $id, - if ( $bypass_cache ) { - wp_cache_delete( $pod['id'], 'post_meta' ); + $pod['id'], + $id, + ] ); + } - update_postmeta_cache( array( $pod['id'] ) ); + /** + * Allow custom deletion actions for relationships. + * + * @since 2.8.0 + * + * @param int $id ID to remove. + * @param array|Pod $pod The Pod object. + */ + do_action( 'pods_api_delete_object_from_relationships', $id, $pod ); } - $pod['options'] = get_post_meta( $pod['id'] ); + return true; + } - foreach ( $pod['options'] as $option => $value ) { - if ( is_array( $value ) ) { - foreach ( $value as $k => $v ) { - if ( ! is_array( $v ) ) { - $value[ $k ] = maybe_unserialize( $v ); - } - } + /** + * Handle deletion of relationship data. + * + * @since 2.3.0 + * + * @param int|array $related_id ID(s) for items to save. + * @param int|array $id ID(s) to remove. + * @param array|Pod $related_pod The related Pod object. + * @param array|Field $related_field The related Field object. + * @param bool $force Whether to force the deletion, even if found related IDs not set or matching. + */ + public function delete_relationships( $related_id, $id, $related_pod, $related_field, $force = true ) { - if ( 1 == count( $value ) ) { - $value = current( $value ); - } - } else { - $value = maybe_unserialize( $value ); + if ( is_array( $related_id ) ) { + foreach ( $related_id as $rid ) { + $this->delete_relationships( $rid, $id, $related_pod, $related_field ); } - $pod['options'][ $option ] = $value; + return; } - $pod['options'] = array_merge( $defaults, $pod['options'] ); + if ( is_array( $id ) ) { + foreach ( $id as $rid ) { + $this->delete_relationships( $related_id, $rid, $related_pod, $related_field ); + } - $pod['type'] = $pod['options']['type']; - $pod['storage'] = $pod['options']['storage']; - $pod['object'] = $pod['options']['object']; - $pod['alias'] = $pod['options']['alias']; + return; + } - unset( $pod['options']['type'] ); - unset( $pod['options']['storage'] ); - unset( $pod['options']['object'] ); - unset( $pod['options']['alias'] ); + $id = (int) $id; - if ( $table_info ) { - $pod = array_merge( $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ), $pod ); + if ( empty( $id ) ) { + return; } - // Override old 'none' storage type - if ( 'taxonomy' === $pod['type'] && 'none' === $pod['storage'] && function_exists( 'get_term_meta' ) ) { - $pod['storage'] = 'meta'; - } + $related_ids = $this->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); - if ( isset( $pod['pod'] ) ) { - unset( $pod['pod'] ); + if ( ! $force ) { + if ( empty( $related_ids ) ) { + return; + } elseif ( ! in_array( $id, $related_ids ) ) { + return; + } } - $pod['fields'] = array(); + $static_cache = tribe( Static_Cache::class ); + + $cache_key = $related_pod['id'] . '|' . $related_field['id']; + + // Delete relationship from cache. + $static_cache->delete( $cache_key, __CLASS__ . '/related_item_cache' ); - $pod['object_fields'] = array(); + // @codingStandardsIgnoreLine + $key = array_search( $id, $related_ids ); - if ( 'pod' !== $pod['type'] ) { - $pod['object_fields'] = $this->get_wp_object_fields( $pod['type'], $pod ); + if ( false !== $key ) { + unset( $related_ids[ $key ] ); } - $fields = get_posts( array( - 'post_type' => '_pods_field', - 'posts_per_page' => - 1, - 'nopaging' => true, - 'post_parent' => $pod['id'], - 'orderby' => 'menu_order', - 'order' => 'ASC' - ) ); + $no_conflict = pods_no_conflict_check( $related_pod['type'] ); - if ( ! empty( $fields ) ) { - foreach ( $fields as $field ) { - $field->pod = $pod['name']; - $field->table_info = $table_info; - $field->bypass_cache = $bypass_cache; + if ( ! $no_conflict ) { + pods_no_conflict_on( $related_pod['type'] ); + } - if ( $load_fields ) { - $field = $this->load_field( $field ); + // Post Types, Media, Users, and Comments (meta-based) + if ( pods_relationship_meta_storage_enabled( $related_field, $related_pod ) && in_array( $related_pod['type'], [ + 'post_type', + 'media', + 'taxonomy', + 'user', + 'comment', + ], true ) ) { + $object_type = $related_pod['type']; - $field = PodsForm::field_setup( $field, null, $field['type'] ); - } else { - if ( $bypass_cache ) { - wp_cache_delete( $field->ID, 'post_meta' ); + if ( in_array( $object_type, [ 'post_type', 'media' ], true ) ) { + $object_type = 'post'; + } elseif ( 'taxonomy' === $object_type ) { + $object_type = 'term'; + } - update_postmeta_cache( array( $field->ID ) ); - } + delete_metadata( $object_type, $related_id, $related_field['name'] ); - $field = array( - 'id' => $field->ID, - 'name' => $field->post_name, - 'label' => $field->post_title, - 'type' => get_post_meta( $field->ID, 'type', true ) - ); + if ( ! empty( $related_ids ) ) { + update_metadata( $object_type, $related_id, '_pods_' . $related_field['name'], $related_ids ); + + foreach ( $related_ids as $rel_id ) { + add_metadata( $object_type, $related_id, $related_field['name'], $rel_id ); } + } else { + delete_metadata( $object_type, $related_id, '_pods_' . $related_field['name'] ); + } + } elseif ( 'settings' === $related_pod['type'] ) { + // Custom Settings Pages (options-based) + if ( ! empty( $related_ids ) ) { + update_option( $related_pod['name'] . '_' . $related_field['name'], $related_ids ); + } else { + delete_option( $related_pod['name'] . '_' . $related_field['name'] ); + } + } + + // Relationships table + if ( pods_podsrel_enabled() ) { + pods_query( ' + DELETE FROM `@wp_podsrel` + WHERE + ( + `pod_id` = %d + AND `field_id` = %d + AND `item_id` = %d + AND `related_item_id` = %d + ) + OR ( + `related_pod_id` = %d + AND `related_field_id` = %d + AND `related_item_id` = %d + AND `item_id` = %d + ) + ', array( + $related_pod['id'], + $related_field['id'], + $related_id, + $id, - $pod['fields'][ $field['name'] ] = $field; - } + $related_pod['id'], + $related_field['id'], + $related_id, + $id, + ) ); } - if ( did_action( 'init' ) && pods_api_cache() ) { - pods_transient_set( $transient . '_' . $pod['name'], $pod ); - } + /** + * Allow custom deletion actions for relationships. + * + * @since 2.8.0 + * + * @param int|array $related_id ID(s) for items to save. + * @param int|array $id ID(s) to remove. + * @param array|Pod $related_pod The related Pod object. + * @param array|Field $related_field The related Field object. + */ + do_action( 'pods_api_delete_relationships', $related_id, $id, $related_field, $related_pod ); - return $pod; + if ( ! $no_conflict ) { + pods_no_conflict_off( $related_pod['type'] ); + } } /** - * Load a list of Pods based on filters specified. + * Check if a Pod exists * - * $params['type'] string/array Pod Type(s) to filter by - * $params['object'] string/array Pod Object(s) to filter by - * $params['options'] array Pod Option(s) key=>value array to filter by - * $params['orderby'] string ORDER BY clause of query - * $params['limit'] string Number of Pods to return - * $params['where'] string WHERE clause of query - * $params['ids'] string|array IDs of Objects - * $params['count'] boolean Return only a count of Pods - * $params['names'] boolean Return only an array of name => label - * $params['ids'] boolean Return only an array of ID => label - * $params['fields'] boolean Return pod fields with Pods (default is true) - * $params['key_names'] boolean Return pods keyed by name - * $params['bypass_cache'] boolean Bypass the cache when getting data + * $params['id'] int Pod ID + * $params['name'] string Pod name * * @param array $params An associative array of parameters * - * @return array|mixed - * - * @uses PodsAPI::load_pod + * @return bool True if exists * - * @since 2.0.0 + * @since 1.12 */ - public function load_pods( $params = null ) { - - $current_language = false; - - // Get current language data - $lang_data = pods_i18n()->get_current_language_data(); + public function pod_exists( $params, $type = null ) { - if ( $lang_data ) { - if ( ! empty( $lang_data['language'] ) ) { - $current_language = $lang_data['language']; - } + if ( is_string( $params ) ) { + $params = array( 'name' => $params ); } $params = (object) pods_sanitize( $params ); - $order = 'ASC'; - $orderby = 'menu_order title'; - $limit = - 1; - $ids = false; - - $meta_query = array(); - $cache_key = ''; - - $bypass_cache = false; - - if ( ! empty( $params->bypass_cache ) ) { - $bypass_cache = true; - } + if ( ! empty( $params->id ) || ! empty( $params->name ) ) { + if ( ! isset( $params->name ) ) { + $dummy = (int) $params->id; + $pod = get_post( $dummy ); + } else { + $pod = get_posts( array( + 'name' => $params->name, + 'post_type' => '_pods_pod', + 'posts_per_page' => 1 + ) ); - if ( isset( $params->type ) && ! empty( $params->type ) ) { - if ( ! is_array( $params->type ) ) { - $params->type = array( trim( $params->type ) ); + if ( is_array( $pod ) && ! empty( $pod[0] ) ) { + $pod = $pod[0]; + } } - sort( $params->type ); - - $meta_query[] = array( - 'key' => 'type', - 'value' => $params->type, - 'compare' => 'IN' - ); - - if ( 0 < count( $params->type ) ) { - $cache_key .= '_type_' . trim( implode( '_', $params->type ) ); + if ( ! empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) ) { + return true; } } - if ( isset( $params->object ) && ! empty( $params->object ) ) { - if ( ! is_array( $params->object ) ) { - $params->object = array( $params->object ); - } - - $params->object = pods_trim( $params->object ); - - sort( $params->object ); - - $meta_query[] = array( - 'key' => 'object', - 'value' => $params->object, - 'compare' => 'IN' - ); + return false; + } - if ( 1 == count( $params->object ) ) { - $cache_key .= '_object_' . trim( implode( '', $params->object ) ); - } - } + /** + * Get number of pods for a specific pod type + * + * @param string $type Type to get count + * + * @return int Total number of pods for a type + * + * @since 2.6.6 + */ + public function get_pod_type_count( $type ) { - if ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) { - foreach ( $params->options as $option => $value ) { - if ( ! is_array( $value ) ) { - $value = array( $value ); - } + $args = array( + 'post_type' => '_pods_pod', + 'posts_per_page' => - 1, + 'nopaging' => true, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => 'type', + 'value' => $type, + ), + ), + ); - $value = pods_trim( $value ); + $posts = get_posts( $args ); - sort( $value ); + return count( $posts ); - $meta_query[] = array( - 'key' => $option, - 'value' => pods_sanitize( $value ), - 'compare' => 'IN' - ); - } + } - $cache_key = ''; + /** + * Load a Pod. + * + * @param array|int|WP_Post|string $params { + * An associative array of parameters. + * + * @type int $id The Pod ID. + * @type string $name The Pod name. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work. + * + * @return Pods\Whatsit\Pod|false Pod object or false if not found. + * + * @throws Exception + * @since 1.7.9 + */ + public function load_pod( $params, $strict = false ) { + if ( $params instanceof Pod ) { + return $params; } - if ( isset( $params->where ) && is_array( $params->where ) ) { - $meta_query = array_merge( $meta_query, (array) $params->where ); + if ( $params instanceof WP_Post ) { + return $this->get_pods_object_from_wp_post( $params ); } - if ( isset( $params->order ) && ! empty( $params->order ) && in_array( strtoupper( $params->order ), array( - 'ASC', - 'DESC' - ) ) ) { - $order = strtoupper( $params->order ); + if ( is_numeric( $params ) ) { + $params = [ + 'id' => $params, + ]; + } elseif ( is_string( $params ) ) { + $params = [ + 'name' => $params, + ]; } - if ( isset( $params->orderby ) && ! empty( $params->orderby ) ) { - $orderby = strtoupper( $params->orderby ); + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( (object) $params ); } - if ( isset( $params->limit ) && ! empty( $params->limit ) ) { - $limit = pods_absint( $params->limit ); + if ( empty( $params ) ) { + return false; } - if ( isset( $params->ids ) && ! empty( $params->ids ) ) { - $ids = $params->ids; + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); - if ( ! is_array( $ids ) ) { - $ids = explode( ',', $ids ); + if ( ! $api_cache ) { + $params['bypass_cache'] = true; } } - if ( empty( $ids ) ) { - $ids = false; + if ( isset( $params['fields'] ) ) { + unset( $params['fields'] ); } - $pre_key = ''; - - if ( ! empty( $current_language ) ) { - $pre_key .= '_' . $current_language; + if ( isset( $params['table_info'] ) ) { + unset( $params['table_info'] ); } - if ( isset( $params->count ) && $params->count ) { - $pre_key .= '_count'; - } + $params['object_type'] = 'pod'; + $params['include_internal'] = true; - if ( isset( $params->ids ) && $params->ids && ! empty( $ids ) ) { - $pre_key .= '_ids_' . implode( '_', $ids ); + if ( isset( $params['name'] ) && '' === $params['name'] ) { + unset( $params['name'] ); } - if ( isset( $params->names ) && $params->names ) { - $pre_key .= '_names'; - } elseif ( isset( $params->names_ids ) && $params->names_ids ) { - $pre_key .= '_names_ids'; + if ( isset( $params['id'] ) && in_array( $params['id'], array( '', 0 ), true ) ) { + unset( $params['id'] ); } - if ( isset( $params->key_names ) && $params->key_names ) { - $pre_key .= '_namekeys'; - } + $object = $this->_load_object( $params ); - if ( isset( $params->fields ) && ! $params->fields ) { - $pre_key .= '_nofields'; - } + $pod = 'n/a'; - if ( isset( $params->table_info ) && $params->table_info ) { - $pre_key .= '_tableinfo'; + if ( ! empty( $params['name'] ) ) { + $pod = $params['name']; + } elseif ( ! empty( $params['id'] ) ) { + $pod = $params['id']; } - $pre_key .= '_get'; - - if ( empty( $cache_key ) ) { - $cache_key = 'pods' . $pre_key . '_all'; - } else { - $cache_key = 'pods' . $pre_key . $cache_key; + if ( $object ) { + return $object; } - if ( ! $bypass_cache && pods_api_cache() && ! empty( $cache_key ) && ( 'pods' . ( ! empty( $current_language ) ? '_' . $current_language : '' ) . '_get_all' !== $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' === $orderby ) && empty( $ids ) ) { - $the_pods = pods_transient_get( $cache_key ); - - if ( false === $the_pods ) { - $the_pods = pods_cache_get( $cache_key, 'pods' ); - } - - if ( ! is_array( $the_pods ) && 'none' === $the_pods ) { - return array(); - } elseif ( false !== $the_pods ) { - return $the_pods; - } + if ( $strict ) { + return pods_error( __( 'Pod not found', 'pods' ), $this ); } - $the_pods = array(); - - $args = array( - 'post_type' => '_pods_pod', - 'nopaging' => true, - 'posts_per_page' => $limit, - 'order' => $order, - 'orderby' => $orderby, - 'meta_query' => $meta_query, - ); + return false; + } - // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099) - if ( false !== $ids ) { - $args['post__in'] = $ids; + /** + * Load a list of Pods based on filters specified. + * + * @param array $params { + * An associative array of parameters + * + * @type string|array $type Pod type(s) to filter by. + * @type string|array $id ID(s) of Objects. + * @type array $args Args(s) key=>value array to filter by. + * @type boolean $count Return only a count of pods. + * @type boolean $names Return only an array of name => label. + * @type boolean $ids Return only an array of ID => label. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @return Pods\Whatsit\Pod[]|int List of pod objects or count. + * + * @throws Exception + * + * @since 2.0.0 + */ + public function load_pods( $params = [] ) { + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( (object) $params ); } - $_pods = get_posts( $args ); - - $export_ignore = array( - 'object_type', - 'object_name', - 'table', - 'meta_table', - 'pod_table', - 'field_id', - 'field_index', - 'field_slug', - 'field_type', - 'field_parent', - 'field_parent_select', - 'meta_field_id', - 'meta_field_index', - 'meta_field_value', - 'pod_field_id', - 'pod_field_index', - 'object_fields', - 'join', - 'where', - 'where_default', - 'orderby', - 'pod', - 'recurse', - 'table_info', - 'attributes', - 'group', - 'grouped', - 'developer_mode', - 'dependency', - 'depends-on', - 'excludes-on' - ); - - $total_fields = 0; - - if ( isset( $params->count ) && $params->count ) { - $the_pods = count( $_pods ); - } else { - foreach ( $_pods as $pod ) { - if ( isset( $params->names ) && $params->names ) { - $the_pods[ $pod->post_name ] = $pod->post_title; - } elseif ( isset( $params->names_ids ) && $params->names_ids ) { - $the_pods[ $pod->ID ] = $pod->post_name; - } else { - if ( isset( $params->fields ) && ! $params->fields ) { - $pod->fields = false; - } + $include_internal = false; - $pod = $this->load_pod( array( - 'pod' => $pod, - 'table_info' => ! empty( $params->table_info ), - 'bypass_cache' => $bypass_cache - ) ); + if ( isset( $params['include_internal'] ) ) { + $include_internal = (boolean) $params['include_internal']; - // Remove extra data not needed - if ( pods_var( 'export', $params, false ) && ( ! isset( $params->fields ) || $params->fields ) ) { - foreach ( $export_ignore as $ignore ) { - if ( isset( $pod[ $ignore ] ) ) { - unset( $pod[ $ignore ] ); - } - } + unset( $params['include_internal'] ); + } - foreach ( $pod['fields'] as $field => $field_data ) { - if ( isset( $pod['fields'][ $field ]['table_info'] ) ) { - unset( $pod['fields'][ $field ]['table_info'] ); - } - } - } + if ( ! $include_internal ) { + $params['internal'] = false; + } - $total_fields += count( $pod['fields'] ); + if ( isset( $params['fields'] ) ) { + unset( $params['fields'] ); + } - if ( isset( $params->key_names ) && $params->key_names ) { - $the_pods[ $pod['name'] ] = $pod; - } else { - $the_pods[ $pod['id'] ] = $pod; - } - } - } + if ( isset( $params['table_info'] ) ) { + unset( $params['table_info'] ); } - if ( ( ! function_exists( 'pll_current_language' ) || ! empty( $params->refresh ) ) && ! empty( $cache_key ) && ( 'pods' !== $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' === $orderby ) && empty( $ids ) ) { - $total_pods = (int) ( is_array( $the_pods ) ) ? count( $the_pods ) : $the_pods; - // Too many Pods can cause issues with the DB when caching is not enabled - if ( 15 < $total_pods || 75 < (int) $total_fields ) { - pods_transient_clear( $cache_key ); + if ( isset( $params['object_fields'] ) ) { + unset( $params['object_fields'] ); + } - if ( pods_api_cache() ) { - if ( empty( $the_pods ) && ( ! isset( $params->count ) || ! $params->count ) ) { - pods_cache_set( $cache_key, 'none', 'pods' ); - } else { - pods_cache_set( $cache_key, $the_pods, 'pods' ); - } - } - } else { - pods_cache_clear( $cache_key, 'pods' ); + // Backcompat handling. + if ( ! empty( $params['ids'] ) ) { + $params['id'] = $params['ids']; - if ( pods_api_cache() ) { - if ( empty( $the_pods ) && ( ! isset( $params->count ) || ! $params->count ) ) { - pods_transient_set( $cache_key, 'none' ); - } else { - pods_transient_set( $cache_key, $the_pods ); - } - } - } + unset( $params['ids'] ); } - return $the_pods; + $params['object_type'] = 'pod'; + + return $this->_load_objects( $params ); } /** @@ -6714,476 +7821,521 @@ public function load_pods( $params = null ) { * $params['id'] int The field ID * $params['name'] string The field name * - * @param array $params An associative array of parameters + * @param array $params An associative array of parameters + * @param boolean $allow_id Whether to allow the ID when checking if the group exists. * * @return bool * * @since 1.12 */ - public function field_exists( $params ) { + public function field_exists( $params, $allow_id = true ) { + $params = (object) $params; - $params = (object) pods_sanitize( $params ); + $allowed = [ + 'name', + 'pod_id', + 'pod', + ]; - if ( ( ! empty( $params->id ) || ! empty( $params->name ) ) && isset( $params->pod_id ) && ! empty( $params->pod_id ) ) { - if ( ! isset( $params->name ) ) { - $dummy = (int) $params->id; - $field = get_post( $dummy ); - } else { - $field = get_posts( array( - 'name' => $params->name, - 'post_type' => '_pods_field', - 'posts_per_page' => 1, - 'post_parent' => $params->pod_id - ) ); - } + if ( $allow_id ) { + $allowed[] = 'id'; + } - if ( ! empty( $field ) ) { - return true; + $load_params = []; + + foreach ( $allowed as $param ) { + if ( ! isset( $params->{$param} ) ) { + continue; } + + $load_params[ $param ] = $params->{$param}; } - return false; + try { + return (boolean) $this->load_field( $load_params ); + } catch ( Exception $exception ) { + return false; + } } /** - * Load a field + * Load a field. * - * $params['pod_id'] int The Pod ID - * $params['pod'] string The Pod name - * $params['id'] int The field ID - * $params['name'] string The field name - * $params['table_info'] boolean Whether to lookup a pick field's table info - * $params['bypass_cache'] boolean Bypass the cache when getting data + * @param array|int $params { + * An associative array of parameters. + * + * @type int $pod_id The Pod ID. + * @type string $pod The Pod name. + * @type int $id The field ID. + * @type string $name The field name. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } * - * @param array $params An associative array of parameters - * @param boolean $strict Whether to require a field exist or not when loading the info + * @param boolean $strict Whether to require a field exist or not when loading the info. * - * @return array|bool Array with field data, false if field not found + * @return Pods\Whatsit\Field|bool Field object or false if not found. + * + * @throws Exception + * @throws Exception * @since 1.7.9 */ public function load_field( $params, $strict = false ) { - - $params = (object) $params; - - if ( ! isset( $params->table_info ) ) { - $params->table_info = false; + if ( $params instanceof Field ) { + return $params; } - $bypass_cache = false; - - if ( ! empty( $params->bypass_cache ) ) { - $bypass_cache = true; + if ( $params instanceof WP_Post ) { + return $this->get_pods_object_from_wp_post( $params ); } - $pod = array(); - $field = array(); - - if ( isset( $params->post_title ) ) { - $_field = $params; - } elseif ( isset( $params->id ) && ! empty( $params->id ) ) { - $dummy = (int) $params->id; - $_field = get_post( $dummy ); - } else { - if ( ! isset( $params->pod ) ) { - $params->pod = ''; - } + if ( is_numeric( $params ) ) { + $params = [ + 'id' => $params, + ]; + } elseif ( is_string( $params ) ) { + $params = [ + 'name' => $params, + ]; + } - if ( ! isset( $params->pod_id ) ) { - $params->pod_id = 0; - } + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( (object) $params ); + } - if ( isset( $params->pod_data ) ) { - $pod = $params->pod_data; - } else { - $pod = $this->load_pod( array( - 'name' => $params->pod, - 'id' => $params->pod_id, - 'table_info' => false, - 'bypass_cache' => $bypass_cache - ), false ); - - if ( false === $pod ) { - if ( $strict ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); - return false; - } + if ( ! $api_cache ) { + $params['bypass_cache'] = true; } + } - $params->pod_id = $pod['id']; - $params->pod = $pod['name']; + if ( isset( $params['table_info'] ) ) { + unset( $params['table_info'] ); + } - if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) ) { - return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this ); - } + if ( isset( $params['pod_id'] ) ) { + $params['parent'] = (int) $params['pod_id']; - $params->name = pods_clean_name( $params->name, true, ( 'meta' === $pod['storage'] ? false : true ) ); + unset( $params['pod_id'] ); + } - if ( isset( $pod['fields'][ $params->name ] ) && isset( $pod['fields'][ $params->name ]['id'] ) ) { - return $pod['fields'][ $params->name ]; - } + if ( isset( $params['pod'] ) ) { + if ( empty( $params['parent'] ) ) { + $params['parent'] = 0; - $field = false; + $pod = $this->load_pod( $params['pod'], false ); - if ( ! $bypass_cache && pods_api_cache() ) { - $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name ); + if ( $pod ) { + $params['parent'] = $pod->get_id(); + } } - if ( empty( $field ) ) { - $field = get_posts( array( - 'name' => $params->name, - 'post_type' => '_pods_field', - 'posts_per_page' => 1, - 'post_parent' => $params->pod_id - ) ); + unset( $params['pod'] ); + } - if ( empty( $field ) || empty( $field[0] ) ) { - if ( $strict ) { - return pods_error( __( 'Field not found', 'pods' ), $this ); - } + if ( isset( $params['group_id'] ) ) { + $params['group'] = (int) $params['group_id']; - return false; - } + unset( $params['group_id'] ); + } - $_field = $field[0]; + if ( isset( $params['group'] ) ) { + $group = $this->load_group( $params['group'], false ); - $field = array(); + if ( $group ) { + $params['group'] = $group->get_id(); } } - if ( empty( $_field ) ) { - if ( $strict ) { - return pods_error( __( 'Field not found', 'pods' ), $this ); - } + $params['object_type'] = 'field'; + $params['include_internal'] = true; - return false; + $object = $this->_load_object( $params ); + + if ( $object ) { + return $object; } - $_field = get_object_vars( $_field ); + if ( $strict ) { + return pods_error( __( 'Pod field not found', 'pods' ), $this ); + } - if ( ! isset( $pod['name'] ) && ! isset( $_field['pod'] ) ) { - if ( 0 < $_field['post_parent'] ) { - $pod = $this->load_pod( array( 'id' => $_field['post_parent'], 'table_info' => false ), false ); - } + return false; + } - if ( empty( $pod ) ) { - if ( $strict ) { - return pods_error( __( 'Pod for field not found', 'pods' ), $this ); - } + /** + * Traverse fields and load their information. + * + * @param array $params { + * An associative array of parameters. + * + * @type string $pod The Pod name. + * @type array $expand The field name(s) to expand. + * @type array $types The field type(s). + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @return Pods\Whatsit\Field[] List of field objects. + * + * @since 2.8.0 + */ + public function traverse_fields( array $params ) { + $fields = array(); - return false; + try { + // pod and expand are required parameters. + if ( empty( $params['pod'] ) || empty( $params['expand'] ) ) { + return array(); } - } - if ( empty( $field ) ) { - if ( ! $bypass_cache && pods_api_cache() && ( isset( $pod['name'] ) || isset( $_field['pod'] ) ) ) { - $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field['post_name'] ); + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); + + if ( ! $api_cache ) { + $params['bypass_cache'] = true; + } } - if ( empty( $field ) ) { - $defaults = array( - 'type' => 'text' - ); + $pod = $params['pod']; + $expand = $params['expand']; + $types = ! empty( $params['types'] ) ? (array) $params['types'] : PodsForm::tableless_field_types(); - $field = array( - 'id' => $_field['ID'], - 'name' => $_field['post_name'], - 'label' => $_field['post_title'], - 'description' => $_field['post_content'], - 'weight' => $_field['menu_order'], - 'pod_id' => $_field['post_parent'], - 'pick_object' => '', - 'pick_val' => '', - 'sister_id' => '', - 'table_info' => array() + // For each in expand, load field, fall back to load pod if an object field. + foreach ( $expand as $field_name ) { + $args = array( + 'pod' => $pod, + 'name' => $field_name, + 'type' => $types, ); - if ( isset( $pod['name'] ) ) { - $field['pod'] = $pod['name']; - } elseif ( isset( $_field['pod'] ) ) { - $field['pod'] = $_field['pod']; - } - - if ( $bypass_cache ) { - wp_cache_delete( $field['id'], 'post_meta' ); + $field = $this->load_field( $args ); - update_postmeta_cache( array( $field['id'] ) ); - } + if ( ! $field instanceof Field ) { + // Check if this is an object field. + $pod_data = $this->load_pod( $pod ); - $field['options'] = get_post_meta( $field['id'] ); + if ( ! $pod_data instanceof Pod ) { + break; + } - $options_ignore = array( - 'method', - 'table_info', - 'attributes', - 'group', - 'grouped', - 'developer_mode', - 'dependency', - 'depends-on', - 'excludes-on' - ); + $field = $pod_data->get_field( $field_name ); - foreach ( $options_ignore as $ignore ) { - if ( isset( $field['options'][ $ignore ] ) ) { - unset( $field['options'][ $ignore ] ); + if ( ! $field instanceof Object_Field || ! in_array( $field['type'], $types, true ) ) { + break; } } - foreach ( $field['options'] as $option => $value ) { - if ( is_array( $value ) ) { - foreach ( $value as $k => $v ) { - if ( ! is_array( $v ) ) { - $value[ $k ] = maybe_unserialize( $v ); - } - } + $fields[] = $field; - if ( 1 == count( $value ) ) { - $value = current( $value ); - } - } else { - $value = maybe_unserialize( $value ); - } + $pod = $field->get_related_object_name(); - $field['options'][ $option ] = $value; + if ( null === $pod ) { + break; } + } + } catch ( \Exception $e ) { + // Do nothing. + } - $field['options'] = array_merge( $defaults, $field['options'] ); + return $fields; + } - $field['type'] = $field['options']['type']; + /** + * Load fields by Pod, ID, Name, and/or Type. + * + * @param array $params { + * An associative array of parameters. + * + * @type int $pod_id The Pod ID. + * @type string $pod The Pod name. + * @type string|array $id The field ID(s). + * @type string|array $name The field name(s). + * @type string|array $type The field type(s). + * @type array $args Arg(s) key=>value array to filter by. + * @type boolean $count Return only a count of fields. + * @type boolean $names Return only an array of name => label. + * @type boolean $ids Return only an array of ID => label. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @return Pods\Whatsit\Field[]|int List of field objects or count. + * + * @throws Exception + * + * @since 1.7.9 + */ + public function load_fields( $params = [] ) { + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( $params ); + } - unset( $field['options']['type'] ); + $include_internal = false; - if ( isset( $field['options']['pick_object'] ) ) { - $field['pick_object'] = $field['options']['pick_object']; + if ( isset( $params['include_internal'] ) ) { + $include_internal = (boolean) $params['include_internal']; - unset( $field['options']['pick_object'] ); - } + unset( $params['include_internal'] ); + } - if ( isset( $field['options']['pick_val'] ) ) { - $field['pick_val'] = $field['options']['pick_val']; + if ( ! $include_internal ) { + $params['internal'] = false; + } - unset( $field['options']['pick_val'] ); - } + if ( isset( $params['table_info'] ) ) { + unset( $params['table_info'] ); + } - if ( isset( $field['options']['sister_id'] ) ) { - $field['sister_id'] = $field['options']['sister_id']; + // Backcompat handling. + if ( ! empty( $params['ids'] ) ) { + $params['id'] = $params['ids']; - unset( $field['options']['sister_id'] ); - } + unset( $params['ids'] ); + } - if ( isset( $field['options']['sister_field_id'] ) ) { - unset( $field['options']['sister_field_id'] ); - } + if ( isset( $params['pod_id'] ) ) { + $params['parent'] = (int) $params['pod_id']; - if ( pods_api_cache() && ( isset( $pod['name'] ) || isset( $_field['pod'] ) ) ) { - pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field['name'], $field ); - } - } + unset( $params['pod_id'] ); } - $field['table_info'] = array(); + if ( isset( $params['pod'] ) ) { + if ( empty( $params['parent'] ) ) { + $params['parent'] = 0; + + $pod = $this->load_pod( $params['pod'], false ); + + if ( $pod ) { + $params['parent'] = $pod->get_id(); + } + } - if ( 'pick' === $field['type'] && $params->table_info ) { - $field['table_info'] = $this->get_table_info( $field['pick_object'], $field['pick_val'], null, null, $field ); + unset( $params['pod'] ); } - return $field; + $params['object_type'] = 'field'; + + return $this->_load_objects( $params ); } /** - * Load fields by Pod, ID, Name, and/or Type + * Check if a Pod's group exists * - * $params['pod_id'] int The Pod ID - * $params['pod'] string The Pod name - * $params['id'] array The field IDs - * $params['name'] array The field names - * $params['type'] array The field types - * $params['options'] array Field Option(s) key=>value array to filter by - * $params['where'] string WHERE clause of query - * $params['object_fields'] bool Whether to include the object fields for WP objects, default true + * @param array|int|WP_Post $params { + * An associative array of parameters. * - * @param array $params An associative array of parameters - * @param bool $strict Whether to require a field exist or not when loading the info + * @type int $pod_id The Pod ID. + * @type string $pod The Pod name. + * @type int $id The Group ID. + * @type string $name The Group name. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * @param boolean $allow_id Whether to allow the ID when checking if the group exists. * - * @return array Array of field data. + * @return bool * - * @since 1.7.9 + * @since 2.8.0 */ - public function load_fields( $params, $strict = false ) { + public function group_exists( $params, $allow_id = true ) { + $params = (object) $params; + + $allowed = [ + 'name', + 'pod_id', + 'pod', + ]; - // @todo Get away from using md5/serialize, I'm sure we can cache specific parts - $cache_key = md5( serialize( $params ) ); - if ( isset( $this->fields_cache[ $cache_key ] ) ) { - return $this->fields_cache[ $cache_key ]; + if ( $allow_id ) { + $allowed[] = 'id'; } - $params = (object) pods_sanitize( $params ); + $load_params = []; - if ( ! isset( $params->pod ) || empty( $params->pod ) ) { - $params->pod = ''; - } + foreach ( $allowed as $param ) { + if ( ! isset( $params->{$param} ) ) { + continue; + } - if ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) { - $params->pod_id = 0; + $load_params[ $param ] = $params->{$param}; } - if ( ! isset( $params->name ) || empty( $params->name ) ) { - $params->name = array(); - } else { - $params->name = (array) $params->name; + try { + return (boolean) $this->load_group( $load_params ); + } catch ( Exception $exception ) { + return false; } + } - if ( ! isset( $params->id ) || empty( $params->id ) ) { - $params->id = array(); - } else { - $params->id = (array) $params->id; - - foreach ( $params->id as &$id ) { - $id = pods_absint( $id ); - } + /** + * Load a Group. + * + * @param array|int|WP_Post $params { + * An associative array of parameters. + * + * @type int $pod_id The Pod ID. + * @type string $pod The Pod name. + * @type int $id The Group ID. + * @type string $name The Group name. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work. + * + * @return Pods\Whatsit\Group|false Group object or false if not found. + * + * @throws Exception + * @since 2.8.0 + */ + public function load_group( $params, $strict = false ) { + if ( $params instanceof Group ) { + return $params; } - if ( ! isset( $params->type ) || empty( $params->type ) ) { - $params->type = array(); - } else { - $params->type = (array) $params->type; + if ( $params instanceof WP_Post ) { + return $this->get_pods_object_from_wp_post( $params ); } - if ( ! isset( $params->object_fields ) ) { - $params->object_fields = true; - } else { - $params->object_fields = (boolean) $params->object_fields; + if ( is_numeric( $params ) ) { + $params = [ + 'id' => $params, + ]; + } elseif ( is_string( $params ) ) { + $params = [ + 'name' => $params, + ]; } - $fields = array(); - - if ( ! empty( $params->pod ) || ! empty( $params->pod_id ) ) { - $pod = $this->load_pod( array( - 'name' => $params->pod, - 'id' => $params->pod_id, - 'table_info' => true - ), false ); - - if ( false === $pod ) { - if ( $strict ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( (object) $params ); + } - return $fields; - } + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); - if ( $params->object_fields && ! empty( $pod['object_fields'] ) ) { - $pod['fields'] = array_merge( $pod['object_fields'], $pod['fields'] ); + if ( ! $api_cache ) { + $params['bypass_cache'] = true; } + } - foreach ( $pod['fields'] as $field ) { - if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) ) { - $fields[ $field['name'] ] = $field; - } elseif ( in_array( $fields['name'], $params->name ) || in_array( $fields['id'], $params->id ) || in_array( $fields['type'], $params->type ) ) { - $fields[ $field['name'] ] = $field; - } - } - } elseif ( ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && ! empty( $params->where ) && is_array( $params->where ) ) ) { - $order = 'ASC'; - $orderby = 'menu_order title'; - $limit = - 1; - $ids = false; + if ( isset( $params['table_info'] ) ) { + unset( $params['table_info'] ); + } - $meta_query = array(); + if ( isset( $params['pod_id'] ) ) { + $params['parent'] = (int) $params['pod_id']; - if ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) { - foreach ( $params->options as $option => $value ) { - if ( ! is_array( $value ) ) { - $value = array( $value ); - } + unset( $params['pod_id'] ); + } - $value = pods_trim( $value ); + if ( isset( $params['pod'] ) ) { + if ( empty( $params['parent'] ) ) { + $params['parent'] = 0; - sort( $value ); + $pod = $this->load_pod( $params['pod'], false ); - $meta_query[] = array( - 'key' => $option, - 'value' => pods_sanitize( $value ), - 'compare' => 'IN' - ); + if ( $pod ) { + $params['parent'] = $pod->get_id(); } } - if ( isset( $params->where ) && ! empty( $params->where ) && is_array( $params->where ) ) { - $meta_query = array_merge( $meta_query, (array) $params->where ); - } + unset( $params['pod'] ); + } - $args = array( - 'post_type' => '_pods_field', - 'nopaging' => true, - 'posts_per_page' => $limit, - 'order' => $order, - 'orderby' => $orderby, - 'meta_query' => $meta_query, - ); + $params['object_type'] = 'group'; + $params['include_internal'] = true; - // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099) - if ( false !== $ids ) { - $args['post__in'] = $ids; - } + $object = $this->_load_object( $params ); + + if ( $object ) { + return $object; + } - $fields = array(); + if ( $strict ) { + return pods_error( __( 'Pod group not found', 'pods' ), $this ); + } - $_fields = get_posts( $args ); + return false; + } - foreach ( $_fields as $field ) { - $field = $this->load_field( $field, false ); + /** + * Load a list of Groups based on filters specified. + * + * @param array $params { + * An associative array of parameters. + * + * @type int $pod_id The Pod ID. + * @type string $pod The Pod name. + * @type string|array $id The group ID(s). + * @type array $name The group names. + * @type array $type The group types. + * @type array $args Arg(s) key=>value to filter by. + * @type boolean $count Return only a count of objects. + * @type boolean $names Return only an array of name => label. + * @type boolean $ids Return only an array of ID => label. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @return Pods\Whatsit\Group[]|int List of group objects or count. + * + * @throws Exception + * + * @since 2.8.0 + */ + public function load_groups( $params = [] ) { + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( $params ); + } - if ( ! empty( $field ) ) { - $fields[ $field['id'] ] = $field; - } - } - } else { - if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) ) { - return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this ); - } + $include_internal = false; - $lookup = array(); + if ( isset( $params['include_internal'] ) ) { + $include_internal = (boolean) $params['include_internal']; - if ( ! empty( $params->name ) ) { - $fields = implode( "', '", $params->name ); + unset( $params['include_internal'] ); + } - $lookup[] = "`post_name` IN ( '{$fields}' )"; - } + if ( ! $include_internal ) { + $params['internal'] = false; + } - if ( ! empty( $params->id ) ) { - $fields = implode( ", ", $params->id ); + if ( isset( $params['table_info'] ) ) { + unset( $params['table_info'] ); + } - $lookup[] = "`ID` IN ( {$fields} )"; - } + if ( isset( $params['object_fields'] ) ) { + unset( $params['object_fields'] ); + } - $lookup = implode( ' AND ', $lookup ); + if ( isset( $params['pod_id'] ) ) { + $params['parent'] = (int) $params['pod_id']; - $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" ); + unset( $params['pod_id'] ); + } - $fields = array(); + if ( isset( $params['pod'] ) ) { + if ( empty( $params['parent'] ) ) { + $params['parent'] = 0; - if ( ! empty( $result ) ) { - foreach ( $result as $field ) { - $field = $this->load_field( array( - 'id' => $field->ID, - 'name' => $field->post_name, - 'pod_id' => $field->post_parent - ), false ); + $pod = $this->load_pod( $params['pod'], false ); - if ( ! empty( $field ) && ( empty( $params->type ) || in_array( $field['type'], $params->type ) ) ) { - $fields[ $field['id'] ] = $field; - } + if ( $pod ) { + $params['parent'] = $pod->get_id(); } } - } - if ( isset( $cache_key ) ) { - $this->fields_cache[ $cache_key ] = $fields; + + unset( $params['pod'] ); } - return $fields; + $params['object_type'] = 'group'; + + return $this->_load_objects( $params ); } /** @@ -7200,59 +8352,29 @@ public function load_fields( $params, $strict = false ) { * @since 2.0.0 */ public function load_object( $params, $strict = false ) { + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( (object) $params ); + } - if ( is_object( $params ) && isset( $params->post_title ) ) { - $_object = get_object_vars( $params ); - } else { - $params = (object) pods_sanitize( $params ); - - if ( ! isset( $params->type ) || empty( $params->type ) ) { - return pods_error( __( 'Object type is required', 'pods' ), $this ); - } - - if ( ( ! isset( $params->id ) || empty( $params->id ) ) && ( ! isset( $params->name ) || empty( $params->name ) ) ) { - return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this ); - } - - /** - * @var $wpdb wpdb - */ - global $wpdb; - - if ( isset( $params->name ) ) { - $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' ); - } else { - $object = $params->id; - - $_object = get_post( $object, ARRAY_A ); - } - - if ( empty( $_object ) ) { - if ( $strict ) { - return pods_error( __( 'Object not found', 'pods' ), $this ); - } - - return false; - } + if ( ! isset( $params['type'] ) ) { + return false; } - $object = array( - 'id' => $_object['ID'], - 'name' => $_object['post_title'], - 'code' => $_object['post_content'], - 'type' => str_replace( '_pods_', '', $_object['post_type'] ), - 'slug' => $_object['post_name'] - ); + $params['object_type'] = $params['type']; - $object['options'] = get_post_meta( $object['id'] ); + unset( $params['type'] ); - foreach ( $object['options'] as $option => &$value ) { - if ( is_array( $value ) && 1 == count( $value ) ) { - $value = current( $value ); + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); + + if ( ! $api_cache ) { + $params['bypass_cache'] = true; } } - return $object; + return $this->_load_object( $params, $strict ); } /** @@ -7271,109 +8393,35 @@ public function load_object( $params, $strict = false ) { * @since 2.0.0 */ public function load_objects( $params ) { - - $params = (object) pods_sanitize( $params ); - - if ( ! isset( $params->type ) || empty( $params->type ) ) { - return pods_error( __( 'Pods Object type is required', 'pods' ), $this ); - } - - $order = 'ASC'; - $orderby = 'menu_order'; - $limit = - 1; - $ids = false; - - $meta_query = array(); - $cache_key = ''; - - if ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) { - foreach ( $params->options as $option => $value ) { - if ( ! is_array( $value ) ) { - $value = array( $value ); - } - - $value = pods_trim( $value ); - - sort( $value ); - - $meta_query[] = array( - 'key' => $option, - 'value' => pods_sanitize( $value ), - 'compare' => 'IN' - ); - } + // Backwards compatibility handling. + if ( is_object( $params ) ) { + $params = get_object_vars( (object) $params ); } - if ( isset( $params->where ) && is_array( $params->where ) ) { - $meta_query = array_merge( $meta_query, (array) $params->where ); - } - - if ( isset( $params->order ) && ! empty( $params->order ) && in_array( strtoupper( $params->order ), array( - 'ASC', - 'DESC' - ) ) ) { - $order = strtoupper( $params->order ); - } - - if ( isset( $params->orderby ) && ! empty( $params->orderby ) ) { - $orderby = strtoupper( $params->orderby ); + if ( ! isset( $params['type'] ) ) { + return array(); } - if ( isset( $params->limit ) && ! empty( $params->limit ) ) { - $limit = pods_absint( $params->limit ); - } + $params['object_type'] = $params['type']; - if ( isset( $params->ids ) && ! empty( $params->ids ) ) { - $ids = $params->ids; + unset( $params['type'] ); - if ( ! is_array( $ids ) ) { - $ids = explode( ',', $ids ); - } - } + if ( isset( $params['ids'] ) ) { + $params['id'] = $params['ids']; - if ( empty( $ids ) ) { - $ids = false; + unset( $params['ids'] ); } - if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' === $orderby ) && empty( $ids ) ) { - $cache_key = 'pods_objects_' . $params->type; + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); - $the_objects = pods_transient_get( $cache_key ); - - if ( false !== $the_objects ) { - return $the_objects; + if ( ! $api_cache ) { + $params['bypass_cache'] = true; } } - $the_objects = array(); - - $args = array( - 'post_type' => '_pods_' . $params->type, - 'nopaging' => true, - 'posts_per_page' => $limit, - 'order' => $order, - 'orderby' => $orderby, - 'meta_query' => $meta_query, - ); - - // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099) - if ( false !== $ids ) { - $args['post__in'] = $ids; - } - - $objects = get_posts( $args ); - - foreach ( $objects as $object ) { - $object = $this->load_object( $object ); - - $the_objects[ $object['name'] ] = $object; - } - - if ( pods_api_cache() && ! empty( $cache_key ) ) { - pods_transient_set( $cache_key, $the_objects ); - } - - return $the_objects; + return $this->_load_objects( $params ); } /** @@ -7390,7 +8438,6 @@ public function load_objects( $params ) { * @since 1.7.9 */ public function load_template( $params ) { - if ( ! class_exists( 'Pods_Templates' ) ) { return false; } @@ -7398,6 +8445,12 @@ public function load_template( $params ) { $params = (object) $params; $params->type = 'template'; + if ( isset( $params->name ) ) { + $params->title = $params->name; + + unset( $params->name ); + } + return $this->load_object( $params ); } @@ -7418,7 +8471,6 @@ public function load_template( $params ) { * @since 2.0.0 */ public function load_templates( $params = null ) { - if ( ! class_exists( 'Pods_Templates' ) ) { return array(); } @@ -7444,16 +8496,24 @@ public function load_templates( $params = null ) { * @since 1.7.9 */ public function load_page( $params ) { - if ( ! class_exists( 'Pods_Pages' ) ) { return false; } $params = (object) $params; - if ( ! isset( $params->name ) && isset( $params->uri ) ) { - $params->name = $params->uri; + + if ( isset( $params->name ) ) { + $params->title = $params->name; + + unset( $params->name ); + } + + if ( ! isset( $params->title ) && isset( $params->uri ) ) { + $params->title = $params->uri; + unset( $params->uri ); } + $params->type = 'page'; return $this->load_object( $params ); @@ -7476,7 +8536,6 @@ public function load_page( $params ) { * @since 2.0.0 */ public function load_pages( $params = null ) { - if ( ! class_exists( 'Pods_Pages' ) ) { return array(); } @@ -7500,17 +8559,11 @@ public function load_pages( $params = null ) { * @return array|bool * * @since 1.7.9 + * + * @deprecated since 2.8.0 */ public function load_helper( $params ) { - - if ( ! class_exists( 'Pods_Helpers' ) ) { - return false; - } - - $params = (object) $params; - $params->type = 'helper'; - - return $this->load_object( $params ); + return false; } /** @@ -7528,17 +8581,11 @@ public function load_helper( $params ) { * @return array * * @since 2.0.0 + * + * @deprecated since 2.8.0 */ public function load_helpers( $params = null ) { - - if ( ! class_exists( 'Pods_Helpers' ) ) { - return array(); - } - - $params = (object) $params; - $params->type = 'helper'; - - return $this->load_objects( $params ); + return []; } /** @@ -7605,7 +8652,7 @@ public function load_sister_fields( $params, $pod = null ) { $params = (object) pods_sanitize( $params ); if ( empty( $pod ) ) { - $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false ); + $pod = $this->load_pod( array( 'name' => $params->pod ), false ); if ( false === $pod ) { return pods_error( __( 'Pod not found', 'pods' ), $this ); @@ -7630,7 +8677,7 @@ public function load_sister_fields( $params, $pod = null ) { $type = $params->related_pod; } - $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false ); + $related_pod = $this->load_pod( array( 'name' => $params->related_pod ), false ); if ( false === $related_pod || ( false !== $type && 'pod' !== $type && $type !== $related_pod['type'] ) ) { return pods_error( __( 'Related Pod not found', 'pods' ), $this ); @@ -7644,8 +8691,8 @@ public function load_sister_fields( $params, $pod = null ) { foreach ( $related_pod['fields'] as $field ) { if ( 'pick' === $field['type'] && in_array( $field['pick_object'], array( $pod['type'], - 'pod' - ) ) && ( $params->pod == $field['pick_object'] || $params->pod == $field['pick_val'] ) ) { + 'pod', + ), true ) && ( $params->pod == $field['pick_object'] || $params->pod == $field['pick_val'] ) ) { $sister_fields[ $field['id'] ] = esc_html( $field['label'] . ' (' . $field['name'] . ')' ); } } @@ -7739,18 +8786,31 @@ private function get_field_definition( $type, $options = null ) { * * @since 2.0.0 */ - public function handle_field_validation( &$value, $field, $object_fields, $fields, $pod, $params ) { + public function handle_field_validation( &$value, $field, $object_fields, $fields, $pod, $params = [] ) { $tableless_field_types = PodsForm::tableless_field_types(); - $fields = array_merge( $fields, $object_fields ); + $fields = pods_config_merge_fields( $fields, $object_fields ); $options = $fields[ $field ]; - $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) ); + if ( is_array( $params ) ) { + $params = (object) $params; + } + + $id = 0; + + if ( is_object( $params ) ) { + $id = $params->id; + } elseif ( $pod instanceof Pods ) { + $id = $pod->id(); + } - if ( is_object( $pod ) ) { + // Normalize to Pod config object. + if ( $pod instanceof Pods ) { $pod = $pod->pod_data; + } elseif ( ! is_array( $pod ) && ! $pod instanceof Pod ) { + $pod = null; } $type = $options['type']; @@ -7758,12 +8818,12 @@ public function handle_field_validation( &$value, $field, $object_fields, $field $label = empty( $label ) ? $field : $label; // Verify required fields - if ( 1 == pods_var( 'required', $options['options'], 0 ) && 'slug' !== $type ) { + if ( 'slug' !== $type && 1 === (int) pods_v( 'required', $options, 0 ) ) { if ( '' === $value || null === $value || array() === $value ) { return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this ); } - if ( 'multi' === pods_var( 'pick_format_type', $options['options'] ) && 'autocomplete' !== pods_var( 'pick_format_multi', $options['options'] ) ) { + if ( 'multi' === pods_v( 'pick_format_type', $options ) && 'autocomplete' !== pods_v( 'pick_format_multi', $options ) ) { $has_value = false; $check_value = (array) $value; @@ -7785,12 +8845,12 @@ public function handle_field_validation( &$value, $field, $object_fields, $field // @todo move this to after pre-save preparations // Verify unique fields - if ( 1 == pods_var( 'unique', $options['options'], 0 ) && '' !== $value && null !== $value && array() !== $value ) { + if ( 1 === (int) pods_v( 'unique', $options, 0 ) && '' !== $value && null !== $value && array() !== $value ) { if ( empty( $pod ) ) { return false; } - if ( ! in_array( $type, $tableless_field_types ) ) { + if ( ! in_array( $type, $tableless_field_types, true ) ) { $exclude = ''; if ( ! empty( $id ) ) { @@ -7815,7 +8875,7 @@ public function handle_field_validation( &$value, $field, $object_fields, $field } } - $validate = PodsForm::validate( $options['type'], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params ); + $validate = PodsForm::validate( $options['type'], $value, $field, $options, $fields, $pod, $id, $params ); $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params ); @@ -7837,7 +8897,7 @@ public function handle_field_validation( &$value, $field, $object_fields, $field * * @uses pods_query() */ - public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $pod = null ) { + public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $pod = null, $force_meta = true ) { $related_ids = array(); @@ -7851,31 +8911,45 @@ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $ $idstring = implode( ',', $ids ); - if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) { - // Check cache first, no point in running the same query multiple times - return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ]; + $static_cache = tribe( Static_Cache::class ); + + $cache_key = $pod_id . '|' . $field_id; + + // Check cache first, no point in running the same query multiple times + if ( $pod_id && $field_id ) { + $cache_value = $static_cache->get( $cache_key, __CLASS__ . '/related_item_cache' ) ?: []; + + if ( isset( $cache_value[ $idstring ] ) ) { + return $cache_value[ $idstring ]; + } } $tableless_field_types = PodsForm::tableless_field_types(); $field_type = pods_v( 'type', $field ); - if ( empty( $ids ) || ! in_array( $field_type, $tableless_field_types ) ) { + if ( empty( $ids ) || ! in_array( $field_type, $tableless_field_types, true ) ) { return array(); } $related_pick_limit = 0; if ( empty( $field ) ) { - $field = $this->load_field( array( 'id' => $field_id ) ); + $load_params = array( + 'parent' => $pod_id, + ); + + if ( ! empty( $field_id ) ) { + $load_params['id'] = $field_id; + } + + $field = $this->load_field( $load_params ); } if ( ! empty( $field ) ) { - $options = (array) pods_var_raw( 'options', $field, $field, null, true ); + $related_pick_limit = (int) pods_v( $field_type . '_limit', $field, 0 ); - $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 ); - - if ( 'single' === pods_var_raw( $field_type . '_format_type', $options ) ) { + if ( 'single' === pods_v( $field_type . '_format_type', $field ) ) { $related_pick_limit = 1; } @@ -7900,22 +8974,18 @@ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $ if ( ! is_wp_error( $related ) ) { $related_ids = $related; } - } elseif ( ! pods_tableless() ) { + } elseif ( ! pods_tableless() && pods_podsrel_enabled() ) { $ids = implode( ', ', $ids ); $field_id = (int) $field_id; - $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 ); - - $related_where = " - `field_id` = {$field_id} - AND `item_id` IN ( {$ids} ) - "; + $sister_id = (int) pods_v( 'sister_id', $field, 0 ); $sql = " SELECT item_id, related_item_id, related_field_id FROM `@wp_podsrel` WHERE - {$related_where} + `field_id` = {$field_id} + AND `item_id` IN ( {$ids} ) ORDER BY `weight` "; @@ -7931,8 +9001,8 @@ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $ } } } else { - if ( ! is_array( $pod ) ) { - $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false ); + if ( ! ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) ) { + $pod = $this->load_pod( array( 'id' => $pod_id ), false ); } if ( ! empty( $pod ) && in_array( $pod['type'], array( @@ -7945,7 +9015,7 @@ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $ ) ) ) { $meta_type = $pod['type']; - if ( in_array( $meta_type, array( 'post_type', 'media' ) ) ) { + if ( in_array( $meta_type, array( 'post_type', 'media' ), true ) ) { $meta_type = 'post'; } elseif ( 'taxonomy' === $meta_type ) { $meta_type = 'term'; @@ -7980,7 +9050,7 @@ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $ } } } - } else { + } elseif ( pods_relationship_meta_storage_enabled( $field, $pod ) ) { $related_id = get_metadata( $meta_type, $id, '_pods_' . $field['name'], true ); if ( empty( $related_id ) ) { @@ -8022,9 +9092,14 @@ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $ $related_ids = array_slice( $related_ids, 0, $related_pick_limit ); } } + if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) { // Only cache if $pod_id and $field_id were passed - self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids; + $cache_value = $static_cache->get( $cache_key, __CLASS__ . '/related_item_cache' ) ?: []; + + $cache_value[ $idstring ] = $related_ids; + + $static_cache->set( $cache_key, $cache_value, __CLASS__ . '/related_item_cache' ); } return $related_ids; @@ -8060,33 +9135,31 @@ public function lookup_related_items_from( $field_id, $pod_id, $id, $field = nul $related_pick_limit = 0; if ( ! empty( $field ) ) { - $options = (array) pods_var_raw( 'options', $field, $field, null, true ); - - $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 ); + $related_pick_limit = (int) pods_v( $field['type'] . '_limit', $field, 0 ); - if ( 'single' === pods_var_raw( 'pick_format_type', $options ) ) { + if ( 'single' === pods_v( $field['type'] . '_format_type', $field ) ) { $related_pick_limit = 1; } } if ( ! pods_tableless() ) { $field_id = (int) $field_id; - $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 ); + $sister_id = (int) pods_v( 'sister_id', $field, 0 ); - $related_where = " - `field_id` = {$field_id} - AND `related_item_id` = {$id} - "; + $relationships = array(); - $sql = " - SELECT * - FROM `@wp_podsrel` - WHERE - {$related_where} - ORDER BY `weight` - "; + if ( pods_podsrel_enabled() ) { + $sql = " + SELECT * + FROM `@wp_podsrel` + WHERE + `field_id` = {$field_id} + AND `related_item_id` = {$id} + ORDER BY `weight` + "; - $relationships = pods_query( $sql ); + $relationships = pods_query( $sql ); + } if ( ! empty( $relationships ) ) { $related_ids = array(); @@ -8103,8 +9176,8 @@ public function lookup_related_items_from( $field_id, $pod_id, $id, $field = nul // @todo handle meta-based lookups return false; - if ( ! is_array( $pod ) ) { - $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false ); + if ( ! ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) ) { + $pod = $this->load_pod( array( 'id' => $pod_id ), false ); } if ( ! empty( $pod ) && in_array( $pod['type'], array( @@ -8119,7 +9192,7 @@ public function lookup_related_items_from( $field_id, $pod_id, $id, $field = nul $meta_type = $pod['type']; - if ( in_array( $meta_type, array( 'post_type', 'media' ) ) ) { + if ( in_array( $meta_type, array( 'post_type', 'media' ), true ) ) { $meta_type = 'post'; } elseif ( 'taxonomy' === $meta_type ) { $meta_type = 'term'; @@ -8225,7 +9298,10 @@ public function get_table_info_load( $object_type, $object, $name = null, $pod = $name = $object; } - $pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false ); + $pod = $this->load_pod( [ + 'name' => $name, + 'auto_setup' => true, + ] ); if ( ! empty( $pod ) ) { $object_type = $pod['type']; @@ -8249,7 +9325,10 @@ public function get_table_info_load( $object_type, $object, $name = null, $pod = } if ( ! empty( $name ) ) { - $pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false ); + $pod = $this->load_pod( [ + 'name' => $name, + 'auto_setup' => true, + ] ); if ( ! empty( $pod ) && ( null === $object_type || $object_type == $pod['type'] ) ) { $object_type = $pod['type']; @@ -8279,8 +9358,8 @@ public function get_table_info_load( $object_type, $object, $name = null, $pod = $info['meta_table'] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ); $info['table'] = $info['meta_table']; - if ( is_array( $info['pod'] ) && 'pod' === pods_v( 'type', $info['pod'] ) ) { - $info['meta_field_value'] = pods_v( 'pod_index', $info['pod']['options'], 'id', true ); + if ( ( is_array( $info['pod'] ) || $info['pod'] instanceof Pods\Whatsit ) && 'pod' === pods_v( 'type', $info['pod'] ) ) { + $info['meta_field_value'] = pods_v( 'pod_index', $info['pod'], 'id', true ); $info['pod_field_index'] = $info['meta_field_value']; $info['field_index'] = $info['meta_field_value']; $info['meta_field_index'] = $info['meta_field_value']; @@ -8307,8 +9386,8 @@ public function get_table_info_load( $object_type, $object, $name = null, $pod = $info['field_slug'] = $slug_field->post_name; } - if ( 1 == pods_v( 'hierarchical', $info['pod']['options'], 0 ) ) { - $parent_field = pods_v( 'pod_parent', $info['pod']['options'], 'id', true ); + if ( 1 == pods_v( 'hierarchical', $info['pod'], 0 ) ) { + $parent_field = pods_v( 'pod_parent', $info['pod'], 'id', true ); if ( ! empty( $parent_field ) && isset( $info['pod']['fields'][ $parent_field ] ) ) { $info['object_hierarchical'] = true; @@ -8357,6 +9436,7 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null 'type' => null, 'object_name' => $object, 'object_hierarchical' => false, + 'storage' => null, 'table' => $object, 'meta_table' => $object, @@ -8394,74 +9474,65 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $object = 'post'; } elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ), true ) ) { $object = $object_type; + } elseif ( 'post_type' === $object_type && 'attachment' === $object ) { + $object_type = 'media'; + $object = $object_type; } $pod_name = $pod; - if ( is_array( $pod_name ) ) { - $pod_name = pods_var_raw( 'name', $pod_name, ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $pod_name, JSON_UNESCAPED_UNICODE ) : json_encode( $pod_name ) ), null, true ); + if ( is_array( $pod_name ) || $pod_name instanceof Pods\Whatsit ) { + $pod_name = pods_v( 'name', $pod_name, json_encode( $pod_name, JSON_UNESCAPED_UNICODE ), true ); } else { $pod_name = $object; } $field_name = $field; - if ( is_array( $field_name ) ) { - $field_name = pods_var_raw( 'name', $field_name, ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $pod_name, JSON_UNESCAPED_UNICODE ) : json_encode( $field_name ) ), null, true ); + if ( is_array( $field_name ) || $field_name instanceof Pods\Whatsit ) { + $field_name = pods_v( 'name', $field_name, json_encode( $pod_name, JSON_UNESCAPED_UNICODE ), true ); } - $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name ); - - $current_language = false; - $current_language_t_id = 0; - $current_language_tt_id = 0; - - // Get current language data - $lang_data = pods_i18n()->get_current_language_data(); - - if ( $lang_data ) { - if ( ! empty( $lang_data['language'] ) ) { - $current_language = $lang_data['language']; - } - - if ( ! empty( $lang_data['t_id'] ) ) { - $current_language_t_id = $lang_data['t_id']; - } - - if ( ! empty( $lang_data['tt_id'] ) ) { - $current_language_tt_id = $lang_data['tt_id']; - } - - if ( ! empty( $lang_data['tl_t_id'] ) ) { - $current_language_tl_t_id = $lang_data['tl_t_id']; - } - - if ( ! empty( $lang_data['tl_tt_id'] ) ) { - $current_language_tl_tt_id = $lang_data['tl_tt_id']; - } - } + $cache_key = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name ); + $current_language = pods_i18n()->get_current_language(); if ( ! empty( $current_language ) ) { - $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name ); + $cache_key = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name ); } $_info = false; - $transient_cached = false; - if ( isset( self::$table_info_cache[ $transient ] ) ) { + $static_cache = tribe( Static_Cache::class ); + + $table_info_cache = $static_cache->get( $cache_key, __CLASS__ . '/table_info_cache' ) ?: []; + + if ( $table_info_cache ) { // Prefer info from the object internal cache - $_info = self::$table_info_cache[ $transient ]; + $_info = $table_info_cache; } elseif ( pods_api_cache() ) { - $_info = pods_transient_get( $transient ); - if ( false === $_info && ! did_action( 'init' ) ) { - $_info = pods_transient_get( $transient . '_pre_init' ); + if ( ! did_action( 'init' ) || doing_action( 'init' ) ) { + $_info = pods_transient_get( $cache_key . '_pre_init' ); + } else { + $_info = pods_transient_get( $cache_key ); } - $transient_cached = true; } if ( false !== $_info && is_array( $_info ) ) { // Data was cached, use that $info = $_info; + + /** + * Allow filtering the table information for an object. + * + * @param array $info The table information. + * @param string $object_type The object type. + * @param string $object The object name. + * @param string $name The pod name. + * @param array|Pod $pod The pod config (if found). + * @param array|Field $field The field config (if found). + * @param self $obj The PodsAPI object. + */ + return apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this ); } else { // Data not cached, load it up $_info = $this->get_table_info_load( $object_type, $object, $name, $pod ); @@ -8472,19 +9543,25 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info = array_merge( $info, $_info ); } - if ( 0 === strpos( $object_type, 'post_type' ) || 'media' === $object_type || in_array( pods_var_raw( 'type', $info['pod'] ), array( + if ( + 0 === strpos( $object_type, 'post_type' ) + || 'media' === $object_type + || in_array( pods_v( 'type', $info['pod'] ), [ 'post_type', - 'media' - ) ) ) { + 'media', + ], true ) + ) { + // Post type. $info['table'] = $wpdb->posts; $info['meta_table'] = $wpdb->postmeta; + $info['storage'] = 'meta'; $info['field_id'] = 'ID'; $info['field_index'] = 'post_title'; $info['field_slug'] = 'post_name'; $info['field_type'] = 'post_type'; $info['field_parent'] = 'post_parent'; - $info['field_parent_select'] = '`t`.`' . $info['field_parent'] . '`'; + $info['field_parent_select'] = "`t`.`{$info['field_parent']}`"; $info['meta_field_id'] = 'post_id'; $info['meta_field_index'] = 'meta_key'; @@ -8510,9 +9587,9 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) ); if ( 'attachment' === $post_type || 'media' === $object_type ) { - $info['pod_table'] = $wpdb->prefix . 'pods_media'; + $info['pod_table'] = "{$wpdb->prefix}pods_media"; } else { - $info['pod_table'] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false ); + $info['pod_table'] = "{$wpdb->prefix}pods_" . pods_clean_name( $post_type, true, false ); } $post_type_object = get_post_type_object( $post_type ); @@ -8525,9 +9602,7 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $post_status = array( 'publish' ); // Pick field post_status option - if ( ! empty( $field['options']['pick_post_status'] ) ) { - $post_status = (array) $field['options']['pick_post_status']; - } elseif ( ! empty( $field['pick_post_status'] ) ) { + if ( ! empty( $field['pick_post_status'] ) ) { $post_status = (array) $field['pick_post_status']; } @@ -8548,53 +9623,29 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null */ $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field ); - $info['where'] = array( - //'post_status' => '`t`.`post_status` IN ( "inherit", "publish" )', // @todo Figure out what statuses Attachments can be - 'post_type' => '`t`.`' . $info['field_type'] . '` = "' . $post_type . '"' - ); + $info['where'] = [ + //'post_status' => "`t`.`post_status` IN ( 'inherit', 'publish' )", // @todo Figure out what statuses Attachments can be + 'post_type' => "`t`.`{$info['field_type']}` = '" . pods_sanitize( $post_type ) . "'", + ]; if ( 'post_type' === $object_type ) { - $info['where_default'] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )'; + $info['where_default'] = "`t`.`post_status` IN ( '" . implode( "', '", pods_sanitize( $post_status ) ) . "' )"; } - $info['orderby'] = '`t`.`menu_order`, `t`.`' . $info['field_index'] . '`, `t`.`post_date`'; - - /* - * @todo wpml-comp Check if WPML filters can be applied afterwards - */ - // WPML support - if ( did_action( 'wpml_loaded' ) && ! empty( $current_language ) && apply_filters( 'wpml_is_translated_post_type', false, $post_type ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { - $info['join']['wpml_translations'] = " - LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations` - ON `wpml_translations`.`element_id` = `t`.`ID` - AND `wpml_translations`.`element_type` = 'post_{$post_type}' - AND `wpml_translations`.`language_code` = '{$current_language}' - "; - - $info['join']['wpml_languages'] = " - LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages` - ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1 - "; - - $info['where']['wpml_languages'] = "`wpml_languages`.`code` IS NOT NULL"; - } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && ! empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) { - // Polylang support - $info['join']['polylang_languages'] = " - LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages` - ON `polylang_languages`.`object_id` = `t`.`ID` - AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id} - "; - - $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL"; - } + $info['orderby'] = "`t`.`menu_order`, `t`.`{$info['field_index']}`, `t`.`post_date`"; $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] ); - } elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( + } elseif ( + 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, [ 'nav_menu', - 'post_format' - ) ) || 'taxonomy' === pods_var_raw( 'type', $info['pod'] ) ) { + 'post_format', + ], true ) + || 'taxonomy' === pods_v( 'type', $info['pod'] ) + ) { + // Taxonomy. $info['table'] = $wpdb->terms; $info['meta_table'] = $wpdb->terms; + $info['storage'] = 'meta'; $info['join']['tt'] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`"; $info['join']['tr'] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`"; @@ -8606,7 +9657,7 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['field_slug'] = 'slug'; $info['field_type'] = 'taxonomy'; $info['field_parent'] = 'parent'; - $info['field_parent_select'] = '`tt`.`' . $info['field_parent'] . '`'; + $info['field_parent_select'] = "`tt`.`{$info['field_parent']}`"; if ( ! empty( $wpdb->termmeta ) ) { $info['meta_table'] = $wpdb->termmeta; @@ -8631,13 +9682,13 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null } } - if ( ! in_array( $object_type, array( 'nav_menu', 'post_format' ) ) ) { + if ( ! in_array( $object_type, array( 'nav_menu', 'post_format' ), true ) ) { $object_type = 'taxonomy'; } $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) ); - $info['pod_table'] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false ); + $info['pod_table'] = "{$wpdb->prefix}pods_" . pods_clean_name( $taxonomy, true, false ); $taxonomy_object = get_taxonomy( $taxonomy ); @@ -8645,45 +9696,17 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['object_hierarchical'] = true; } - $info['where'] = array( - 'tt.taxonomy' => '`tt`.`' . $info['field_type'] . '` = "' . $taxonomy . '"' - ); - - /* - * @todo wpml-comp WPML API call for is_translated_taxononomy - * @todo wpml-comp Check if WPML filters can be applied afterwards - */ - // WPML Support - if ( is_object( $sitepress ) && ! empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { - $info['join']['wpml_translations'] = " - LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations` - ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id` - AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}' - AND `wpml_translations`.`language_code` = '{$current_language}' - "; - - $info['join']['wpml_languages'] = " - LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages` - ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1 - "; - - $info['where']['wpml_languages'] = "`wpml_languages`.`code` IS NOT NULL"; - } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && ! empty( $current_language ) && ! empty( $current_language_tl_tt_id ) && function_exists( 'pll_is_translated_taxonomy' ) && pll_is_translated_taxonomy( $taxonomy ) ) { - // Polylang support - $info['join']['polylang_languages'] = " - LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages` - ON `polylang_languages`.`object_id` = `t`.`term_id` - AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id} - "; - - $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL"; - } + $info['where'] = [ + 'tt.taxonomy' => "`tt`.`{$info['field_type']}` = '" . pods_sanitize( $taxonomy ) . "'", + ]; $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] ); - } elseif ( 'user' === $object_type || 'user' === pods_var_raw( 'type', $info['pod'] ) ) { + } elseif ( 'user' === $object_type || 'user' === pods_v( 'type', $info['pod'] ) ) { + // User. $info['table'] = $wpdb->users; $info['meta_table'] = $wpdb->usermeta; $info['pod_table'] = $wpdb->prefix . 'pods_user'; + $info['storage'] = 'meta'; $info['field_id'] = 'ID'; $info['field_index'] = 'display_name'; @@ -8693,17 +9716,15 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['meta_field_index'] = 'meta_key'; $info['meta_field_value'] = 'meta_value'; - $info['where'] = array( - 'user_status' => '`t`.`user_status` = 0' - ); + $info['where'] = []; $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] ); - } elseif ( 'comment' === $object_type || 'comment' === pods_var_raw( 'type', $info['pod'] ) ) { - //$info[ 'object_hierarchical' ] = true; - + } elseif ( 'comment' === $object_type || 'comment' === pods_v( 'type', $info['pod'] ) ) { + // Comment type. $info['table'] = $wpdb->comments; $info['meta_table'] = $wpdb->commentmeta; $info['pod_table'] = $wpdb->prefix . 'pods_comment'; + $info['storage'] = 'meta'; $info['field_id'] = 'comment_ID'; $info['field_index'] = 'comment_date'; @@ -8717,26 +9738,33 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $object = 'comment'; - $comment_type = ( empty( $object ) ? $name : $object ); + $comment_type = empty( $object ) ? $name : $object; - $comment_type_clause = '`t`.`' . $info['field_type'] . '` = "' . $comment_type . '"'; + $comment_type_clause = "`t`.`{$info['field_type']}` = '" . pods_sanitize( $comment_type ) . "'"; if ( 'comment' === $comment_type ) { - $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info['field_type'] . '` = "" )'; + $comment_type_clause = "( {$comment_type_clause} OR `t`.`{$info['field_type']}` = '' )"; } - $info['where'] = array( + $info['where'] = [ 'comment_approved' => '`t`.`comment_approved` = 1', - 'comment_type' => $comment_type_clause - ); + 'comment_type' => $comment_type_clause, + ]; - $info['orderby'] = '`t`.`' . $info['field_index'] . '` DESC, `t`.`' . $info['field_id'] . '`'; - } elseif ( in_array( $object_type, array( + $info['orderby'] = "`t`.`{$info['field_index']}` DESC, `t`.`{$info['field_id']}`"; + + $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] ); + } elseif ( + in_array( $object_type, [ 'option', - 'settings' - ) ) || 'settings' === pods_var_raw( 'type', $info['pod'] ) ) { + 'settings', + ], true ) + || 'settings' === pods_v( 'type', $info['pod'] ) + ) { + // Setting. $info['table'] = $wpdb->options; $info['meta_table'] = $wpdb->options; + $info['storage'] = 'option'; $info['field_id'] = 'option_id'; $info['field_index'] = 'option_name'; @@ -8745,13 +9773,21 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['meta_field_index'] = 'option_name'; $info['meta_field_value'] = 'option_value'; - $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC'; - } elseif ( is_multisite() && ( in_array( $object_type, array( + $info['orderby'] = "`t`.`{$info['field_index']}` ASC"; + } elseif ( + is_multisite() + && ( + in_array( $object_type, [ 'site_option', - 'site_settings' - ) ) || 'site_settings' === pods_var_raw( 'type', $info['pod'] ) ) ) { + 'site_settings', + ], true ) + || 'site_settings' === pods_v( 'type', $info['pod'] ) + ) + ) { + // Site meta. $info['table'] = $wpdb->sitemeta; $info['meta_table'] = $wpdb->sitemeta; + $info['storage'] = 'meta'; $info['field_id'] = 'site_id'; $info['field_index'] = 'meta_key'; @@ -8760,10 +9796,12 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['meta_field_index'] = 'meta_key'; $info['meta_field_value'] = 'meta_value'; - $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC'; - } elseif ( is_multisite() && 'network' === $object_type ) { // Network = Site + $info['orderby'] = "`t`.`{$info['field_index']}` ASC"; + } elseif ( is_multisite() && 'network' === $object_type ) { + // Network = Site. $info['table'] = $wpdb->site; $info['meta_table'] = $wpdb->sitemeta; + $info['storage'] = 'meta'; $info['field_id'] = 'id'; $info['field_index'] = 'domain'; @@ -8772,40 +9810,68 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['meta_field_index'] = 'meta_key'; $info['meta_field_value'] = 'meta_value'; - $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC, `t`.`path` ASC, `t`.`' . $info['field_id'] . '`'; - } elseif ( is_multisite() && 'site' === $object_type ) { // Site = Blog - $info['table'] = $wpdb->blogs; + $info['orderby'] = "`t`.`{$info['field_index']}` ASC, `t`.`path` ASC, `t`.`{$info['field_id']}`"; + } elseif ( is_multisite() && 'site' === $object_type ) { + // Site = Blog. + $info['table'] = $wpdb->blogs; + $info['storage'] = 'none'; $info['field_id'] = 'blog_id'; $info['field_index'] = 'domain'; $info['field_type'] = 'site_id'; - $info['where'] = array( + $info['where'] = [ 'archived' => '`t`.`archived` = 0', 'spam' => '`t`.`spam` = 0', 'deleted' => '`t`.`deleted` = 0', - 'site_id' => '`t`.`' . $info['field_type'] . '` = ' . (int) get_current_site()->id - ); + 'site_id' => "`t`.`{$info['field_type']}` = " . (int) get_current_site()->id, + ]; + + $info['orderby'] = "`t`.`{$info['field_index']}` ASC, `t`.`path` ASC, `t`.`{$info['field_id']}`"; + } elseif ( 'table' === $object_type || 'table' === pods_v( 'type', $info['pod'] ) || ! empty( $info['pod']['table_custom'] ) ) { + // Custom tables. + $info['table'] = pods_v( 'table_custom', $info['pod'], ( empty( $object ) ? $name : $object ), true ); + $info['meta_table'] = pods_v( 'meta_table_custom', $info['pod'], $info['meta_table'], true ); + $info['pod_table'] = pods_v( 'pod_table_custom', $info['pod'], "{$wpdb->prefix}pods_" . $info['table'], true ); + $info['storage'] = 'table'; + + $info['field_id'] = pods_v( 'field_id_custom', $info['pod'], $info['field_id'], true ); + $info['field_index'] = pods_v( 'field_index_custom', $info['pod'], $info['field_index'], true ); + $info['field_slug'] = pods_v( 'field_slug_custom', $info['pod'], $info['field_slug'], true ); + $info['field_type'] = pods_v( 'field_type_custom', $info['pod'], $info['field_type'], true ); + $info['field_parent'] = pods_v( 'field_parent_custom', $info['pod'], $info['field_parent'], true ); + $info['field_parent_select'] = pods_v( 'field_parent_select_custom', $info['pod'], $info['field_parent_select'], true ); - $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC, `t`.`path` ASC, `t`.`' . $info['field_id'] . '`'; - } elseif ( 'table' === $object_type || 'table' === pods_var_raw( 'type', $info['pod'] ) ) { - $info['table'] = ( empty( $object ) ? $name : $object ); - $info['pod_table'] = $wpdb->prefix . 'pods_' . $info['table']; + $info['meta_field_id'] = pods_v( 'meta_field_id_custom', $info['pod'], $info['meta_field_id'], true ); + $info['meta_field_index'] = pods_v( 'meta_field_index_custom', $info['pod'], $info['meta_field_index'], true ); + $info['meta_field_value'] = pods_v( 'meta_field_value_custom', $info['pod'], $info['meta_field_value'], true ); + $info['join'] = (array) pods_v( 'join_custom', $info['pod'], $info['join'], true ); + + $info['orderby'] = pods_v( 'orderby_custom', $info['pod'], $info['orderby'], true ); + + $info['where'] = pods_v( 'where_custom', $info['pod'], $info['where'], true ); + $info['where_default'] = pods_v( 'where_default_custom', $info['pod'], $info['where_default'], true ); if ( ! empty( $field ) ) { - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { if ( is_string( $pod ) ) { $pod = pods( $pod ); } - if ( $pod && ! empty( $pod->fields[ $field ] ) ) { + + if ( is_object( $pod ) && ! empty( $pod->fields[ $field ] ) ) { $field = $pod->fields[ $field ]; } } - if ( is_array( $field ) ) { - $info['table'] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) ); - $info['field_id'] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) ); - $info['meta_field_value'] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) ); + + $is_field_object = $field instanceof Field; + + if ( is_array( $field ) || $is_field_object ) { + $info['table'] = pods_v( 'pick_table', pods_v( 'options', $field, $field ) ); + $info['field_id'] = pods_v( 'pick_table_id', pods_v( 'options', $field, $field ) ); + $info['meta_field_value'] = pods_v( 'pick_table_index', pods_v( 'options', $field, $field ) ); $info['field_index'] = $info['meta_field_value']; $info['meta_field_index'] = $info['meta_field_value']; } @@ -8825,37 +9891,49 @@ public function get_table_info( $object_type, $object, $name = null, $pod = null $info['meta_field_value'] = pods_clean_name( $info['meta_field_value'], false, false ); if ( empty( $info['orderby'] ) ) { - $info['orderby'] = '`t`.`' . $info['field_index'] . '`, `t`.`' . $info['field_id'] . '`'; + $info['orderby'] = "`t`.`{$info['field_index']}`, `t`.`{$info['field_id']}`"; } - if ( 'table' === pods_var_raw( 'storage', $info['pod'] ) && ! in_array( $object_type, array( + if ( + 'table' === pods_v( 'storage', $info['pod'] ) + && ! in_array( $object_type, [ 'pod', - 'table' - ) ) ) { - $info['join']['d'] = 'LEFT JOIN `' . $info['pod_table'] . '` AS `d` ON `d`.`id` = `t`.`' . $info['field_id'] . '`'; - //$info[ 'select' ] .= ', `d`.*'; + 'table', + ], true ) + ) { + $info['join']['d'] = "LEFT JOIN `{$info['pod_table']}` AS `d` ON `d`.`id` = `t`.`{$info['field_id']}`"; } - if ( ! empty( $info['pod'] ) && is_array( $info['pod'] ) ) { + if ( ! empty( $info['pod'] ) && ( is_array( $info['pod'] ) || $info['pod'] instanceof Pods\Whatsit ) ) { $info['recurse'] = true; + $info['storage'] = $info['pod']['storage']; } $info['type'] = $object_type; $info['object_name'] = $object; - if ( pods_api_cache() ) { - if ( ! did_action( 'init' ) ) { - $transient .= '_pre_init'; - } + $static_cache->set( $cache_key, $info, __CLASS__ . '/table_info_cache' ); - if ( !$transient_cached ) { - pods_transient_set( $transient, $info ); + if ( pods_api_cache() ) { + if ( ! did_action( 'init' ) || doing_action( 'init' ) ) { + pods_transient_set( $cache_key . '_pre_init', $info, WEEK_IN_SECONDS ); + } else { + pods_transient_set( $cache_key, $info, WEEK_IN_SECONDS ); } } - self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this ); - - return self::$table_info_cache[ $transient ]; + /** + * Allow filtering the table information for an object. + * + * @param array $info The table information. + * @param string $object_type The object type. + * @param string $object The object name. + * @param string $name The pod name. + * @param array|Pod $pod The pod config (if found). + * @param array|Field $field The field config (if found). + * @param self $obj The PodsAPI object. + */ + return apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this ); } /** @@ -8973,7 +10051,7 @@ public function import( $import_data, $numeric_mode = false, $format = null ) { $import_data = array( $import_data ); } - $pod = $this->load_pod( array( 'name' => $this->pod ) ); + $pod = $this->load_pod( array( 'name' => $this->pod ), false ); if ( false === $pod ) { return pods_error( __( 'Pod not found', 'pods' ), $this ); @@ -9009,7 +10087,7 @@ public function import( $import_data, $numeric_mode = false, $format = null ) { $pick_values = array(); foreach ( $field_values as $pick_value ) { - if ( in_array( $type, PodsForm::file_field_types() ) || 'media' === $pick_object ) { + if ( in_array( $type, PodsForm::file_field_types(), true ) || in_array( $pick_object, [ 'media', 'attachment' ], true ) ) { $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'"; if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode ) { @@ -9027,15 +10105,14 @@ public function import( $import_data, $numeric_mode = false, $format = null ) { if ( 'pod' === $pick_object ) { $related_pod = $this->load_pod( array( - 'name' => $pick_val, - 'table_info' => true + 'name' => $pick_val, ), false ); } if ( empty( $related_pod ) ) { $related_pod = array( 'id' => 0, - 'type' => $pick_object + 'type' => $pick_object, ); } @@ -9053,7 +10130,7 @@ public function import( $import_data, $numeric_mode = false, $format = null ) { } } elseif ( in_array( 'post_type', array( $pick_object, - $related_pod['type'] + $related_pod['type'], ) ) || in_array( 'media', array( $pick_object, $related_pod['type'] ) ) ) { $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'"; @@ -9086,7 +10163,7 @@ public function import( $import_data, $numeric_mode = false, $format = null ) { if ( ! empty( $result ) ) { $pick_values[] = $result[0]->id; } - } elseif ( in_array( $pick_object, $simple_tableless_objects ) ) { + } elseif ( in_array( $pick_object, $simple_tableless_objects, true ) ) { $pick_values[] = $pick_value; } elseif ( ! empty( $related_pod['id'] ) ) { $where = "`" . $related_pod['field_index'] . "` = '" . pods_sanitize( $pick_value ) . "'"; @@ -9203,15 +10280,12 @@ public function cache_flush_pods( $pod = null ) { pods_transient_clear( 'pods' ); pods_transient_clear( 'pods_components' ); + pods_transient_clear( 'pods_core_loader_objects' ); - if ( null !== $pod && is_array( $pod ) ) { + if ( is_array( $pod ) || $pod instanceof Pod ) { pods_transient_clear( 'pods_pod_' . $pod['name'] ); pods_cache_clear( $pod['name'], 'pods-class' ); - foreach ( $pod['fields'] as $field ) { - pods_transient_clear( 'pods_field_' . $pod['name'] . '_' . $field['name'] ); - } - if ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) ) { pods_transient_clear( 'pods_wp_cpt_ct' ); } @@ -9219,6 +10293,11 @@ public function cache_flush_pods( $pod = null ) { pods_transient_clear( 'pods_wp_cpt_ct' ); } + $static_cache = tribe( Static_Cache::class ); + + $static_cache->flush( __CLASS__ . '/table_info_cache' ); + $static_cache->flush( __CLASS__ . '/related_item_cache' ); + // Delete transients in the database $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" ); $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" ); @@ -9228,7 +10307,7 @@ public function cache_flush_pods( $pod = null ) { pods_cache_clear( true ); - pods_transient_set( 'pods_flush_rewrites', 1 ); + pods_transient_set( 'pods_flush_rewrites', 1, WEEK_IN_SECONDS ); do_action( 'pods_cache_flushed' ); } @@ -9251,12 +10330,12 @@ public function process_form( $params, $obj = null, $fields = null, $thank_you = $form = null; - $nonce = pods_var( '_pods_nonce', $params ); - $pod = pods_var( '_pods_pod', $params ); - $id = pods_var( '_pods_id', $params ); - $uri = pods_var( '_pods_uri', $params ); - $form = pods_var( '_pods_form', $params ); - $location = pods_var( '_pods_location', $params ); + $nonce = pods_v_sanitized( '_pods_nonce', $params ); + $pod = pods_v_sanitized( '_pods_pod', $params ); + $id = pods_v_sanitized( '_pods_id', $params ); + $uri = pods_v_sanitized( '_pods_uri', $params ); + $form = pods_v_sanitized( '_pods_form', $params ); + $location = pods_v_sanitized( '_pods_location', $params ); if ( is_object( $obj ) ) { $pod = $obj->pod; @@ -9295,7 +10374,7 @@ public function process_form( $params, $obj = null, $fields = null, $thank_you = $data = array(); foreach ( $fields as $field ) { - $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' ); + $data[ $field ] = pods_v( 'pods_field_' . $field, $params, '' ); } $params = array( @@ -9346,7 +10425,11 @@ private function do_hook() { } /** - * Handle variables that have been deprecated + * Handle variables that have been deprecated and PodsData vars + * + * @param string $name Property name. + * + * @return mixed * * @since 2.0.0 */ @@ -9354,43 +10437,22 @@ public function __get( $name ) { $name = (string) $name; - if ( ! isset( $this->deprecated ) ) { - require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' ); - $this->deprecated = new PodsAPI_Deprecated( $this ); - } - - $var = null; - - if ( isset( $this->deprecated->{$name} ) ) { - pods_deprecated( "PodsAPI->{$name}", '2.0' ); - - $var = $this->deprecated->{$name}; - } else { - pods_deprecated( "PodsAPI->{$name}", '2.0' ); - } - - return $var; - } - - /** - * Handle methods that have been deprecated - * - * @since 2.0.0 - */ - public function __call( $name, $args ) { + // Handle alias Pods\Whatsit\Pod properties. + $supported_pods_object = array( + 'pod' => 'name', + 'pod_id' => 'id', + 'fields' => 'fields', + ); - $name = (string) $name; + if ( isset( $supported_pods_object[ $name ] ) ) { + if ( ! is_object( $this->pod_data ) ) { + return null; + } - if ( ! isset( $this->deprecated ) ) { - require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' ); - $this->deprecated = new PodsAPI_Deprecated( $this ); + return $this->pod_data->get_arg( $supported_pods_object[ $name ] ); } - if ( method_exists( $this->deprecated, $name ) ) { - return call_user_func_array( array( $this->deprecated, $name ), $args ); - } else { - pods_deprecated( "PodsAPI::{$name}", '2.0' ); - } + return null; } /** @@ -9427,4 +10489,357 @@ private function array_filter_walker( $values = array() ) { } + /** + * Get default object storage type to use in Pods Object requests. + * + * @return string + */ + public function get_default_object_storage_type() { + /** + * Filter the storage type to use for Pods Object requests. + * + * @param string $storage_type Storage type. + * + * @since 2.8.0 + */ + return apply_filters( 'pods_api_object_storage_type', 'post_type' ); + } + + /** + * Get Pods Object from WP_Post. + * + * @param WP_Post|array|int $post Post object, array, or ID. + * + * @return false|Pods\Whatsit Object or false if the post does not exist. + * + * @since 2.8.0 + */ + public function get_pods_object_from_wp_post( $post ) { + if ( ! $post instanceof WP_Post ) { + $post = get_post( $post ); + } + + if ( ! $post || is_wp_error( $post ) ) { + return false; + } + + $object_collection = Pods\Whatsit\Store::get_instance(); + + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() ); + + return $post_type_storage->to_object( $post ); + } + + /** + * Load an object. + * + * @param array $params { + * An associative array of parameters. + * + * @type string $object_type The object type. + * @type string $id The ID. + * @type string $name The name. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @param boolean $strict Whether to require a field exist or not when loading the info. + * + * @return Pods\Whatsit|false Object or false if not found. + * + * @throws Exception + * + * @since 2.8.0 + */ + public function _load_object( array $params, $strict = false ) { + if ( empty( $params['object_type'] ) ) { + return false; + } + + if ( is_array( $params['object_type'] ) ) { + $params['object_type'] = reset( $params['object_type'] ); + } + + $object = false; + + if ( isset( $params['title'] ) ) { + $object = pods_by_title( $params['title'], ARRAY_A, '_pods_' . $params['object_type'], 'publish', 'id' ); + + // Normalize the response as Whatsit. + if ( 0 < $object ) { + $params['id'] = $object; + + unset( $params['title'] ); + + $object = $this->_load_object( $params, $strict ); + } + } else { + $params['limit'] = 1; + + $loaded = $this->_load_objects( $params ); + + if ( $loaded ) { + $object = reset( $loaded ); + } + } + + if ( $object ) { + return $object; + } + + if ( $strict ) { + return pods_error( __( 'Object not found', 'pods' ), $this ); + } + + return false; + } + + /** + * Load objects. + * + * @param array $params { + * An associative array of parameters. + * + * @type string|array $object_type The object type(s). + * @type string|array $id The ID(s). + * @type string|array $name The name(s). + * @type string|array $type The type(s). + * @type array $args Arg(s) key=>value to filter by. + * @type boolean $count Return only a count of fields. + * @type boolean $names Return only an array of name => label. + * @type boolean $ids Return only an array of ID => label. + * @type boolean $bypass_cache Bypass the cache when getting data. + * } + * + * @return Pods\Whatsit[]|int List of objects or count. + * + * @since 2.8.0 + */ + public function _load_objects( array $params ) { + if ( empty( $params['object_type'] ) ) { + return array(); + } + + // Check if we need to bypass cache automatically. + if ( ! isset( $params['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); + + if ( ! $api_cache ) { + $params['bypass_cache'] = true; + } + } + + if ( isset( $params['options'] ) ) { + $params['args'] = $params['options']; + + unset( $params['options'] ); + } + + if ( isset( $params['where'] ) ) { + $where = $params['where']; + + unset( $params['where'] ); + + if ( ! isset( $params['args'] ) ) { + $params['args'] = array(); + } + + foreach ( $where as $arg ) { + if ( ! isset( $arg['key'], $arg['value'] ) ) { + continue; + } + + $params['args'][ $arg['key'] ] = $arg['value']; + } + } + + if ( ! empty( $params['return_type'] ) ) { + $return_type = $params['return_type']; + + if ( 'names' === $return_type ) { + $params['names'] = true; + } elseif ( 'names_ids' === $return_type ) { + $params['names_ids'] = true; + } elseif ( 'ids' === $return_type ) { + $params['ids'] = true; + } elseif ( 'count' === $return_type ) { + $params['count'] = true; + } + } + + $storage_type = ! empty( $params['storage_type'] ) ? $params['storage_type'] : $this->get_default_object_storage_type(); + + $object_collection = Pods\Whatsit\Store::get_instance(); + + /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */ + $post_type_storage = $object_collection->get_storage_object( $storage_type ); + + $objects = $post_type_storage->find( $params ); + + if ( ! empty( $params['auto_setup'] ) && ! $objects ) { + $type = pods_v( 'type', $params, null ); + + $whatsit_args = null; + + if ( 'user' === $params['name'] ) { + // Detect user. + $type = 'user'; + + // Setup the pod and return the request again. + $whatsit_args = [ + 'object_type' => 'pod', + 'type' => $type, + 'name' => $type, + 'label' => __( 'User', 'pods' ), + 'storage' => 'meta', + ]; + } elseif ( 'comment' === $params['name'] ) { + // Detect comment. + $type = 'comment'; + + $whatsit_args = [ + 'object_type' => 'pod', + 'type' => $type, + 'name' => $type, + 'label' => __( 'Comment', 'pods' ), + 'storage' => 'meta', + ]; + } elseif ( 'media' === $params['name'] || 'attachment' === $params['name'] ) { + // Detect media. + $type = 'media'; + + $whatsit_args = [ + 'object_type' => 'pod', + 'type' => $type, + 'name' => $type, + 'label' => __( 'Media', 'pods' ), + 'storage' => 'meta', + ]; + } + + // Detect a post type. + if ( 'post_type' === $type || null === $type ) { + $post_type = get_post_type_object( $params['name'] ); + + if ( $post_type ) { + $type = 'post_type'; + + $whatsit_args = [ + 'object_type' => 'pod', + 'type' => $type, + 'name' => $post_type->name, + 'label' => $post_type->label, + 'description' => $post_type->description, + 'storage' => 'meta', + ]; + } + } + + // Detect a taxonomy. + if ( 'taxonomy' === $type || null === $type ) { + $taxonomy = get_taxonomy( $params['name'] ); + + if ( $taxonomy ) { + $type = 'taxonomy'; + + $whatsit_args = [ + 'object_type' => 'pod', + 'type' => $type, + 'name' => $taxonomy->name, + 'label' => $taxonomy->label, + 'description' => $taxonomy->description, + 'storage' => 'meta', + ]; + } + } + + // Setup the pod and return the request again. + if ( null !== $whatsit_args ) { + // Set up the params for the next call. + $params['auto_setup'] = false; + $params['storage_type'] = 'collection'; + + $pod = new Pod( $whatsit_args ); + + $object_collection->register_object( $pod ); + + return $this->_load_objects( $params ); + } + } + + if ( ! empty( $params['count'] ) ) { + return count( $objects ); + } + + if ( ! empty( $params['names'] ) ) { + return wp_list_pluck( $objects, 'name' ); + } + + if ( ! empty( $params['names_ids'] ) ) { + return wp_list_pluck( $objects, 'name', 'id' ); + } + + if ( ! empty( $params['ids'] ) ) { + return wp_list_pluck( $objects, 'id' ); + } + + return $objects; + } + + /** + * Get the list of Pod types. + * + * @since 2.8.0 + * + * @return string[] The list of pod types and their labels. + */ + public function get_pod_types() { + $pod_types = [ + 'post_type' => _x( 'Post Type (extended)', 'pod type label', 'pods' ), + 'taxonomy' => _x( 'Taxonomy (extended)', 'pod type label', 'pods' ), + 'cpt' => _x( 'Custom Post Type', 'pod type label', 'pods' ), + 'ct' => _x( 'Custom Taxonomy', 'pod type label', 'pods' ), + 'user' => _x( 'User (extended)', 'pod type label', 'pods' ), + 'media' => _x( 'Media (extended)', 'pod type label', 'pods' ), + 'comment' => _x( 'Comments (extended)', 'pod type label', 'pods' ), + 'pod' => _x( 'Advanced Content Type', 'pod type label', 'pods' ), + 'settings' => _x( 'Custom Settings Page', 'pod type label', 'pods' ), + 'internal' => _x( 'Pods Internal', 'pod type label', 'pods' ), + ]; + + /** + * Allow filtering the list of pod types and their labels. + * + * @since 2.8.0 + * + * @param string[] $pod_types The list of pod types and their labels. + */ + return apply_filters( 'pods_api_pod_types', $pod_types ); + } + + /** + * Get the list of Pod types. + * + * @since 2.8.0 + * + * @return string[] The list of storage types and their labels. + */ + public function get_storage_types() { + $storage_types = [ + 'none' => _x( 'None (No Fields)', 'storage type label', 'pods' ), + 'options' => _x( 'Options', 'storage type label', 'pods' ), + 'meta' => _x( 'Meta', 'storage type label', 'pods' ), + 'table' => _x( 'Table', 'storage type label', 'pods' ), + ]; + + /** + * Allow filtering the list of pod types and their labels. + * + * @since 2.8.0 + * + * @param string[] $storage_types The list of storage types and their labels. + */ + return apply_filters( 'pods_api_storage_types', $storage_types ); + } + } diff --git a/classes/PodsAdmin.php b/classes/PodsAdmin.php index 818c10b183..293aec333c 100644 --- a/classes/PodsAdmin.php +++ b/classes/PodsAdmin.php @@ -1,5 +1,8 @@ rest_admin(); } @@ -122,16 +128,23 @@ public function admin_head() { wp_register_script( 'pods-migrate', PODS_URL . 'ui/js/jquery.pods.migrate.js', array(), PODS_VERSION ); + $load_pods_assets = false; + // @codingStandardsIgnoreLine if ( isset( $_GET['page'] ) ) { // @codingStandardsIgnoreLine $page = $_GET['page']; if ( 'pods' === $page || ( false !== strpos( $page, 'pods-' ) && 0 === strpos( $page, 'pods-' ) ) ) { + $load_pods_assets = true; + ?> - load_pods( array( 'count' => true ) ); - if ( ! PodsInit::$upgrade_needed || ( pods_is_admin() && 1 === (int) pods_v( 'pods_upgrade_bypass' ) ) ) { $submenu_items = array(); @@ -217,7 +231,7 @@ public function admin_menu() { $pods_pages = 0; foreach ( (array) $advanced_content_types as $pod ) { - if ( ! isset( $pod['name'] ) || ! isset( $pod['options'] ) || empty( $pod['fields'] ) ) { + if ( ! $pod instanceof Pod ) { continue; } elseif ( ! pods_is_admin( array( @@ -574,19 +588,6 @@ public function admin_menu() { ), ); - if ( empty( $all_pods ) ) { - unset( $admin_menus['pods'] ); - - if ( 'pods' === pods_v( 'page', 'get' ) ) { - // Replace `pods` page param with first existing pod page and redirect. - $url = add_query_arg( 'page', key( $admin_menus ) ); - $url = get_site_url( null, $url ); - - wp_safe_redirect( $url ); - die(); - } - } - add_filter( 'parent_file', array( $this, 'parent_file' ) ); } else { $admin_menus = array( @@ -742,6 +743,11 @@ public function admin_content() { $pod = pods( $pod_name, pods_v( 'id', 'get', null, true ) ); + if ( ! $pod->pod_data->has_fields() ) { + pods_message( 'error', __( 'This Pod does not have any fields defined.', 'pods' ) ); + return; + } + // @codingStandardsIgnoreLine if ( false !== strpos( $_GET['page'], 'pods-add-new-' ) ) { // @codingStandardsIgnoreLine @@ -876,8 +882,9 @@ public function mce_popup() { * Handle main Pods Setup area for managing Pods and Fields */ public function admin_setup() { + $api = pods_api(); - $pods = pods_api()->load_pods( array( 'fields' => false ) ); + $pods = $api->load_pods( array( 'fields' => false ) ); $view = pods_v( 'view', 'get', 'all', true ); @@ -887,16 +894,20 @@ public function admin_setup() { $_GET['action'] = 'add'; } + if ( 'pods' === $_GET['page'] && empty( $pods ) ) { + pods_ui_message( __( 'You do not have any Pods set up yet. You can set up your very first Pod below.', 'pods ' ) ); + } + // @codingStandardsIgnoreLine - if ( 'pods-add-new' === $_GET['page'] ) { + if ( 'pods-add-new' === $_GET['page'] || empty( $pods ) ) { // @codingStandardsIgnoreLine if ( isset( $_GET['action'] ) && 'add' !== $_GET['action'] ) { pods_redirect( pods_query_arg( array( - 'page' => 'pods', + 'page' => 'pods', // @codingStandardsIgnoreLine - 'action' => $_GET['action'], + 'action' => $_GET['action'], ) ) ); @@ -909,84 +920,120 @@ public function admin_setup() { pods_redirect( pods_query_arg( array( - 'page' => 'pods-add-new', - 'action' => '', + 'page' => 'pods-add-new', + 'action' => '', + 'id' => '', + 'do' => '', + '_wpnonce' => '', ) ) ); }//end if - $types = array( - 'post_type' => __( 'Post Type (extended)', 'pods' ), - 'taxonomy' => __( 'Taxonomy (extended)', 'pods' ), - 'cpt' => __( 'Custom Post Type', 'pods' ), - 'ct' => __( 'Custom Taxonomy', 'pods' ), - 'user' => __( 'User (extended)', 'pods' ), - 'media' => __( 'Media (extended)', 'pods' ), - 'comment' => __( 'Comments (extended)', 'pods' ), - 'pod' => __( 'Advanced Content Type', 'pods' ), - 'settings' => __( 'Custom Settings Page', 'pods' ), - ); + $pod_types = $api->get_pod_types(); + $storage_types = $api->get_storage_types(); $row = false; $pod_types_found = array(); - $fields = array( - 'label' => array( 'label' => __( 'Label', 'pods' ) ), - 'name' => array( 'label' => __( 'Name', 'pods' ) ), - 'type' => array( 'label' => __( 'Type', 'pods' ) ), - 'storage' => array( + $fields = [ + 'label' => [ 'label' => __( 'Label', 'pods' ) ], + 'name' => [ 'label' => __( 'Name', 'pods' ) ], + 'type' => [ 'label' => __( 'Type', 'pods' ) ], + 'storage' => [ 'label' => __( 'Storage Type', 'pods' ), 'width' => '10%', - ), - 'field_count' => array( - 'label' => __( 'Number of Fields', 'pods' ), + ], + 'group_count' => [ + 'label' => __( 'Groups', 'pods' ), 'width' => '8%', - ), - ); + ], + 'field_count' => [ + 'label' => __( 'Fields', 'pods' ), + 'width' => '8%', + ], + ]; + $total_groups = 0; $total_fields = 0; + /** + * Filters whether to extend internal Pods. + * + * @since 2.8.0 + * + * @param bool $extend_internal Whether to extend internal Pods. + */ + $extend_internal = apply_filters( 'pods_admin_setup_extend_pods_internal', false ); + + $pod_list = array(); + foreach ( $pods as $k => $pod ) { - if ( isset( $types[ $pod['type'] ] ) ) { - if ( in_array( - $pod['type'], array( + $pod_type = $pod['type']; + $pod_type_label = null; + $pod_storage = $pod['storage']; + + if ( ! empty( $pod['internal'] ) ) { + // Don't show internal if we aren't extending them. + if ( ! $extend_internal ) { + continue; + } + + $pod_type = 'internal'; + $pod_storage = 'meta'; + } + + if ( 'settings' === $pod_type ) { + $pod_storage = 'options'; + } + + if ( isset( $pod_types[ $pod_type ] ) ) { + $pod_type_label = $pod_types[ $pod_type ]; + } + + $pod_real_type = $pod_type; + + $storage_type_label = ucwords( $pod_storage ); + + if ( isset( $storage_types[ $pod_type ] ) ) { + $storage_type_label = $storage_types[ $pod_type ]; + } + + if ( null !== $pod_type_label ) { + if ( empty( $pod['object'] ) && in_array( $pod_type, array( 'post_type', 'taxonomy', - ), true - ) ) { - if ( empty( $pod['object'] ) ) { - if ( 'post_type' === $pod['type'] ) { - $pod['type'] = 'cpt'; - } else { - $pod['type'] = 'ct'; - } + ), true ) ) { + if ( 'post_type' === $pod_type ) { + $pod_type = 'cpt'; + } else { + $pod_type = 'ct'; + } + + if ( isset( $pod_types[ $pod_type ] ) ) { + $pod_type_label = $pod_types[ $pod_type ]; } } - if ( ! isset( $pod_types_found[ $pod['type'] ] ) ) { - $pod_types_found[ $pod['type'] ] = 1; + if ( ! isset( $pod_types_found[ $pod_type ] ) ) { + $pod_types_found[ $pod_type ] = 1; } else { - $pod_types_found[ $pod['type'] ] ++; + $pod_types_found[ $pod_type ] ++; } - if ( 'all' !== $view && $view !== $pod['type'] ) { - unset( $pods[ $k ] ); - + if ( 'all' !== $view && $view !== $pod_type ) { continue; } - $pod['real_type'] = $pod['type']; - $pod['type'] = $types[ $pod['type'] ]; + $pod_real_type = $pod_type; + $pod_type = $pod_type_label; } elseif ( 'all' !== $view ) { continue; }//end if - $pod['storage'] = ucwords( $pod['storage'] ); - // @codingStandardsIgnoreLine - if ( $pod['id'] == pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) { + if ( 'delete' !== pods_v( 'action' ) && $pod['id'] === (int) pods_v( 'id' ) ) { $row = $pod; } @@ -994,16 +1041,18 @@ public function admin_setup() { 'id' => $pod['id'], 'label' => pods_v( 'label', $pod ), 'name' => pods_v( 'name', $pod ), - 'object' => pods_v( 'object', $pod ), - 'type' => pods_v( 'type', $pod ), - 'real_type' => pods_v( 'real_type', $pod ), - 'storage' => pods_v( 'storage', $pod ), - 'field_count' => count( $pod['fields'] ), + 'object' => pods_v( 'object', $pod, '' ), + 'type' => $pod_type, + 'real_type' => $pod_real_type, + 'storage' => $storage_type_label, + 'group_count' => $pod->count_groups(), + 'field_count' => $pod->count_fields(), ); + $total_groups += $pod['group_count']; $total_fields += $pod['field_count']; - $pods[ $k ] = $pod; + $pod_list[] = $pod; }//end foreach if ( false === $row && 0 < pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) { @@ -1013,60 +1062,74 @@ public function admin_setup() { unset( $_GET['id'], $_GET['action'] ); } - $ui = array( - 'data' => $pods, + $total_pods = count( $pod_list ); + + $ui = [ + 'data' => $pod_list, 'row' => $row, - 'total' => count( $pods ), - 'total_found' => count( $pods ), + 'total' => $total_pods, + 'total_found' => $total_pods, 'items' => 'Pods', 'item' => 'Pod', - 'fields' => array( + 'fields' => [ 'manage' => $fields, - ), - 'actions_disabled' => array( 'view', 'export' ), - 'actions_custom' => array( - 'add' => array( $this, 'admin_setup_add' ), - 'edit' => array( $this, 'admin_setup_edit' ), - 'duplicate' => array( - 'callback' => array( $this, 'admin_setup_duplicate' ), - 'restrict_callback' => array( $this, 'admin_setup_duplicate_restrict' ), - ), - 'reset' => array( + ], + 'sql' => [ + 'field_id' => 'id', + 'field_index' => 'label', + ], + 'actions_disabled' => [ 'view', 'export', 'delete' ], + 'actions_custom' => [ + 'add' => [ $this, 'admin_setup_add' ], + 'edit' => [ $this, 'admin_setup_edit' ], + 'duplicate' => [ + 'callback' => [ $this, 'admin_setup_duplicate' ], + 'restrict_callback' => [ $this, 'admin_setup_duplicate_restrict' ], + ], + 'reset' => [ 'label' => __( 'Delete All Items', 'pods' ), 'confirm' => __( 'Are you sure you want to delete all items from this Pod? If this is an extended Pod, it will remove the original items extended too.', 'pods' ), - 'callback' => array( $this, 'admin_setup_reset' ), - 'restrict_callback' => array( $this, 'admin_setup_reset_restrict' ), + 'callback' => [ $this, 'admin_setup_reset' ], + 'restrict_callback' => [ $this, 'admin_setup_reset_restrict' ], 'nonce' => true, - ), - 'delete' => array( $this, 'admin_setup_delete' ), - ), - 'action_links' => array( - 'add' => pods_query_arg( - array( - 'page' => 'pods-add-new', - 'action' => '', - 'id' => '', - 'do' => '', - ) - ), - ), + 'span_class' => 'delete', + ], + 'delete_pod' => [ + 'label' => __( 'Delete', 'pods' ), + 'confirm' => __( 'Are you sure you want to delete this Pod? All of the content and items will remain in the database, you may want to Delete All Items first.', 'pods' ), + 'callback' => [ $this, 'admin_setup_delete' ], + 'nonce' => true, + 'span_class' => 'delete', + ], + ], + 'action_links' => [ + 'add' => pods_query_arg( [ + 'page' => 'pods-add-new', + 'action' => '', + 'id' => '', + 'do' => '', + '_wpnonce' => '', + ] ), + ], 'search' => false, 'searchable' => false, 'sortable' => true, 'pagination' => false, - 'extra' => array( - 'total' => ', ' . number_format_i18n( $total_fields ) . ' ' . _n( 'field', 'fields', $total_fields, 'pods' ), - ), - ); + 'extra' => [ + 'total' => + ', ' . number_format_i18n( $total_groups ) . ' ' . _n( 'group', 'groups', $total_groups, 'pods' ) + . ', ' . number_format_i18n( $total_fields ) . ' ' . _n( 'field', 'fields', $total_fields, 'pods' ), + ], + ]; if ( 1 < count( $pod_types_found ) ) { - $ui['views'] = array( 'all' => __( 'All', 'pods' ) ); + $ui['views'] = [ 'all' => __( 'All', 'pods' ) . ' (' . $total_pods . ')' ]; $ui['view'] = $view; - $ui['heading'] = array( 'views' => __( 'Type', 'pods' ) ); + $ui['heading'] = [ 'views' => __( 'Type', 'pods' ) ]; $ui['filters_enhanced'] = true; foreach ( $pod_types_found as $pod_type => $number_found ) { - $ui['views'][ $pod_type ] = $types[ $pod_type ]; + $ui['views'][ $pod_type ] = $pod_types[ $pod_type ] . ' (' . $number_found . ')'; } } @@ -1099,12 +1162,12 @@ public function get_callouts() { if ( ! $callouts ) { $callouts = array( - 'friends_2021' => 1, + 'friends_2021_29' => 1, ); } // Handle Friends of Pods 2021 callout logic. - $callouts['friends_2021'] = ! isset( $callouts['friends_2021'] ) || $callouts['friends_2021'] || $force_callouts ? 1 : 0; + $callouts['friends_2021_29'] = ! isset( $callouts['friends_2021_29'] ) || $callouts['friends_2021_29'] || $force_callouts ? 1 : 0; /** * Allow hooking into whether or not the specific callouts should show. @@ -1132,7 +1195,7 @@ public function handle_callouts_updates() { $disable_pods = pods_v( 'pods_callout_dismiss' ); - // Disable Friends of Pods 2020 callout. + // Disable Friends of Pods 2021 callout. if ( 'friends_2021' === $disable_pods ) { $callouts['friends_2021'] = 0; @@ -1182,68 +1245,8 @@ public function admin_manage_callouts() { $callouts = $this->get_callouts(); - if ( ! empty( $callouts['friends_2021'] ) ) { - $donor_count = 140; - $donor_goal = 200; - $progress_width = ( $donor_count / $donor_goal ) * 100; -?> -
- - - - - -
- Friends of Pods Logo -
-
-

- ', - '' - ); - ?> -

-

- -

-

- %s: %s', - esc_html__( 'Goal Progress', 'pods' ), - // translators: %1$d: is the number of donors we have; %2$d: the number of donors for our goal. - sprintf( - esc_html__( '%1$d of %2$d donors', 'pods' ), - $donor_count, - $donor_goal - ) - ); - ?> -

-
-
- % -
-
-

Pods Pro by SKCDEV' - ); - ?>

-
- - -
-
-
-load_pod( [ 'id' => $obj->id ] ); - /** - * Get list of Pod option tabs - * - * @param array $pod Pod options. - * - * @return array - */ - public function admin_setup_edit_tabs( $pod ) { - - $fields = true; - $labels = false; - $admin_ui = false; - $advanced = false; - - if ( 'post_type' === pods_v( 'type', $pod ) && '' === pods_v( 'object', $pod ) ) { - $labels = true; - $admin_ui = true; - $advanced = true; - } elseif ( 'taxonomy' === pods_v( 'type', $pod ) && '' === pods_v( 'object', $pod ) ) { - $labels = true; - $admin_ui = true; - $advanced = true; - } elseif ( 'pod' === pods_v( 'type', $pod ) ) { - $labels = true; - $admin_ui = true; - $advanced = true; - } elseif ( 'settings' === pods_v( 'type', $pod ) ) { - $labels = true; - $admin_ui = true; + if ( ! $pod instanceof Pod ) { + $obj->id = null; + $obj->row = []; + $obj->action = 'manage'; + + $obj->error( __( 'Invalid Pod configuration detected.' ) ); + $obj->manage(); + + return null; } - if ( ! function_exists( 'get_term_meta' ) && 'none' === pods_v( 'storage', $pod, 'none', true ) && 'taxonomy' === pods_v( 'type', $pod ) ) { - $fields = false; + if ( 1 !== (int) $pod->get_arg( '_migrated_28' ) ) { + $pod = $this->maybe_migrate_pod_fields_into_group( $pod ); } - $tabs = array(); + // Check again in case the pod migrated wrong. + if ( ! $pod instanceof Pod ) { + $obj->id = null; + $obj->row = []; + $obj->action = 'manage'; - if ( $fields ) { - $tabs['manage-fields'] = __( 'Manage Fields', 'pods' ); - } + $obj->error( __( 'Invalid Pod configuration detected.' ) ); + $obj->manage(); - if ( $labels ) { - $tabs['labels'] = __( 'Labels', 'pods' ); + return null; } - if ( $admin_ui ) { - $tabs['admin-ui'] = __( 'Admin UI', 'pods' ); + $config = [ + 'currentPod' => $pod->export( [ + 'include_groups' => true, + 'include_group_fields' => true, + 'include_fields' => false, + ] ), + 'global' => $this->get_global_config( $pod ), + 'fieldTypes' => PodsForm::field_types(), + 'relatedObjects' => $this->get_field_related_objects(), + 'podTypes' => $api->get_pod_types(), + 'storageTypes' => $api->get_storage_types(), + // @todo SKC: Remove these below and replace any references to podsDFVConfig + 'wp_locale' => $GLOBALS['wp_locale'], + 'currencies' => PodsField_Currency::$currencies, + 'datetime' => [ + 'start_of_week' => (int) get_option( 'start_of_week', 0 ), + 'gmt_offset' => (int) get_option( 'gmt_offset', 0 ), + ], + ]; + + $config['currentPod']['podType'] = [ + 'name' => $config['currentPod']['type'], + ]; + + $config['currentPod']['storageType'] = [ + 'name' => $config['currentPod']['storage'], + ]; + + if ( ! empty( $config['currentPod']['internal'] ) ) { + $config['currentPod']['podType']['name'] = 'internal'; + } elseif ( empty( $config['currentPod']['object'] ) ) { + if ( 'post_type' === $config['currentPod']['type'] ) { + $config['currentPod']['podType']['name'] = 'cpt'; + } elseif ( 'taxonomy' === $config['currentPod']['type'] ) { + $config['currentPod']['podType']['name'] = 'ct'; + } } - if ( $advanced ) { - $tabs['advanced'] = __( 'Advanced Options', 'pods' ); + $config['currentPod']['podType']['label'] = ucwords( str_replace( '_', ' ', $config['currentPod']['podType']['name'] ) ); + + if ( ! empty( $config['podTypes'][ $config['currentPod']['podType']['name'] ] ) ) { + $config['currentPod']['podType']['label'] = $config['podTypes'][ $config['currentPod']['podType']['name'] ]; } - if ( 'taxonomy' === pods_v( 'type', $pod ) && ! $fields ) { - $tabs['extra-fields'] = __( 'Extra Fields', 'pods' ); + if ( 'settings' === $config['currentPod']['type'] ) { + $config['currentPod']['storageType']['name'] = 'options'; } - $addtl_args = compact( array( 'fields', 'labels', 'admin_ui', 'advanced' ) ); + $config['currentPod']['storageType']['label'] = ucwords( $config['currentPod']['storageType']['name'] ); - $pod_type = $pod['type']; - $pod_name = $pod['name']; + if ( ! empty( $config['storageTypes'][ $config['currentPod']['storageType']['name'] ] ) ) { + $config['currentPod']['storageType']['label'] = $config['storageTypes'][ $config['currentPod']['storageType']['name'] ]; + } /** - * Add or modify tabs in Pods editor for a specific Pod + * Allow filtering the admin config data. * - * @param array $tabs Tabs to set. - * @param object $pod Current Pods object. - * @param array $addtl_args Additional args. + * @since 2.8.0 * - * @since unknown + * @param array $config The admin config data. + * @param Pod $pod The pod object. + * @param PodsUI $obj The PodsUI object. */ - $tabs = apply_filters( "pods_admin_setup_edit_tabs_{$pod_type}_{$pod_name}", $tabs, $pod, $addtl_args ); + $config = apply_filters( 'pods_admin_setup_edit_pod_config', $config, $pod, $obj ); - /** - * Add or modify tabs for any Pod in Pods editor of a specific post type. - */ - $tabs = apply_filters( "pods_admin_setup_edit_tabs_{$pod_type}", $tabs, $pod, $addtl_args ); + wp_localize_script( 'pods-dfv', 'podsAdminConfig', $config ); - /** - * Add or modify tabs in Pods editor for all pods. - */ - $tabs = apply_filters( 'pods_admin_setup_edit_tabs', $tabs, $pod, $addtl_args ); + pods_view( PODS_DIR . 'ui/admin/setup-edit.php', compact( array_keys( get_defined_vars() ) ) ); + } - return $tabs; + /** + * Get list of field related objects. + * + * @since 2.8.0 + * + * @return array List of field related objects. + */ + protected function get_field_related_objects() { + $related_object_groups = PodsForm::field_method( 'pick', 'related_objects', true ); + + $related_objects = []; + + foreach ( $related_object_groups as $group => $group_objects ) { + foreach ( $group_objects as $name => $label ) { + $related_objects[ $name ] = [ + 'name' => $name, + 'label' => $label, + ]; + } + } + + return $related_objects; } /** - * Get list of Pod options + * Maybe migrate pod fields into a group (if they have no group). * - * @param array $pod Pod options. + * @since 2.8.0 * - * @return array + * @param Pod $pod The pod object. + * + * @return Pod The pod object. */ - public function admin_setup_edit_options( $pod ) { - - $options = array(); - - if ( '' === pods_v( 'object', $pod ) && 'settings' !== pods_v( 'type', $pod ) ) { - $labels = array( - 'label' => array( - 'label' => __( 'Label', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => str_replace( '_', ' ', pods_v( 'name', $pod ) ), - 'text_max_length' => 30, - ), - 'label_singular' => array( - 'label' => __( 'Singular Label', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ), - 'text_max_length' => 30, - ), - 'label_add_new' => array( - 'label' => __( 'Add New', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type', 'pod' ), - ), - 'label_add_new_item' => array( - 'label' => __( 'Add new Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_new_item' => array( - 'label' => __( 'New Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type', 'pod' ), - ), - 'label_new_item_name' => array( - 'label' => __( 'New Item Name', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - 'label_edit' => array( - 'label' => __( 'Edit', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_edit_item' => array( - 'label' => __( 'Edit Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_update_item' => array( - 'label' => __( 'Update Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy', 'pod' ), - ), - 'label_duplicate' => array( - 'label' => __( 'Duplicate', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_duplicate_item' => array( - 'label' => __( 'Duplicate Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_delete_item' => array( - 'label' => __( 'Delete Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_view' => array( - 'label' => __( 'View', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_view_item' => array( - 'label' => __( 'View Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_view_items' => array( - 'label' => __( 'View Items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_back_to_manage' => array( - 'label' => __( 'Back to Manage', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_manage' => array( - 'label' => __( 'Manage', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_manage_items' => array( - 'label' => __( 'Manage Items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_reorder' => array( - 'label' => __( 'Reorder', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_reorder_items' => array( - 'label' => __( 'Reorder Items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_all_items' => array( - 'label' => __( 'All Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_search' => array( - 'label' => __( 'Search', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_search_items' => array( - 'label' => __( 'Search Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_popular_items' => array( - 'label' => __( 'Popular Items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - // @todo Why was label_parent added previously? Can't find it in WP - 'label_parent' => array( - 'label' => __( 'Parent Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type', 'pod' ), - ), - 'label_parent_item' => array( - 'label' => __( 'Parent Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - 'label_parent_item_colon' => array( - 'label' => __( 'Parent Item:', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_not_found' => array( - 'label' => __( 'Not Found', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'label_no_items_found' => array( - 'label' => __( 'No Item Found', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'pod' ), - ), - 'label_not_found_in_trash' => array( - 'label' => __( 'Not Found in Trash', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type', 'pod' ), - ), - 'label_archives' => array( - 'label' => __( 'Item Archives', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_attributes' => array( - 'label' => __( 'Item Attributes', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_insert_into_item' => array( - 'label' => __( 'Insert into Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_uploaded_to_this_item' => array( - 'label' => __( 'Uploaded to this Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_featured_image' => array( - 'label' => __( 'Featured Image', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working - 'object_type' => array( 'post_type' ), - ), - 'label_set_featured_image' => array( - 'label' => __( 'Set featured Image', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working - 'object_type' => array( 'post_type' ), - ), - 'label_remove_featured_image' => array( - 'label' => __( 'Remove featured Image', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working - 'object_type' => array( 'post_type' ), - ), - 'label_use_featured_image' => array( - 'label' => __( 'Use as featured Image', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working - 'object_type' => array( 'post_type' ), - ), - 'label_filter_items_list' => array( - 'label' => __( 'Filter Items lists', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_items_list_navigation' => array( - 'label' => __( 'Items list navigation', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type', 'taxonomy' ), - ), - 'label_items_list' => array( - 'label' => __( 'Items list', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type', 'taxonomy' ), - ), - 'label_separate_items_with_commas' => array( - 'label' => __( 'Separate items with commas', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - 'label_add_or_remove_items' => array( - 'label' => __( 'Add or remove items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - 'label_choose_from_the_most_used' => array( - 'label' => __( 'Choose from the most used items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - 'label_no_terms' => array( - 'label' => __( 'No items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - 'label_item_published' => array( - 'label' => __( 'Item Published.', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_item_published_privately' => array( - 'label' => __( 'Item published privately.', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_item_reverted_to_draft' => array( - 'label' => __( 'Item reverted to draft.', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_item_scheduled' => array( - 'label' => __( 'Item scheduled.', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'label_item_updated' => array( - 'label' => __( 'Item updated.', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'filter_by_date' => array( - 'label' => __( 'Filter by date', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'post_type' ), - ), - 'filter_by_item' => array( - 'label' => __( 'Filter by Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'object_type' => array( 'taxonomy' ), - ), - ); + public function maybe_migrate_pod_fields_into_group( $pod ) { + $groups = $pod->get_groups( [ + 'fallback_mode' => false, + ] ); - $options['labels'] = array(); + $check_orphan_fields = ! $groups; - /** - * Filter through all labels if they have an object_type set and match it against the current object type - */ - foreach ( $labels as $label => $labeldata ) { - if ( array_key_exists( 'object_type', $labeldata ) ) { - if ( in_array( pods_v( 'type', $pod ), $labeldata['object_type'], true ) ) { - // Do not add the object_type to the actual label data - unset( $labeldata['object_type'] ); - $options['labels'][ $label ] = $labeldata; - } - } else { - $options['labels'][ $label ] = $labeldata; + $api = pods_api(); + + $group_id = null; + + // Only migrate if there are no groups or orphan fields. + if ( ! $check_orphan_fields ) { + $has_orphan_fields = $pod->has_fields( [ + 'fallback_mode' => false, + 'group' => null, + ] ); + + if ( ! $has_orphan_fields ) { + $pod->set_arg( '_migrated_28', 1 ); + + try { + $api->save_pod( $pod ); + } catch ( Exception $exception ) { + // Nothing to do for now. } - } - } elseif ( 'settings' === pods_v( 'type', $pod ) ) { - - $options['labels'] = array( - 'label' => array( - 'label' => __( 'Page Title', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => str_replace( '_', ' ', pods_v( 'name', $pod ) ), - 'text_max_length' => 30, - ), - 'menu_name' => array( - 'label' => __( 'Menu Name', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ), - 'text_max_length' => 30, - ), - ); - }//end if - if ( 'post_type' === $pod['type'] ) { - $options['admin-ui'] = array( - 'description' => array( - 'label' => __( 'Post Type Description', 'pods' ), - 'help' => __( 'A short descriptive summary of what the post type is.', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'show_ui' => array( - 'label' => __( 'Show Admin UI', 'pods' ), - 'help' => __( 'Whether to generate a default UI for managing this post type in the admin.', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'public', $pod, true ), - 'boolean_yes_label' => '', - ), - 'show_in_menu' => array( - 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ), - 'help' => __( 'Whether to show the post type in the admin menu.', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'public', $pod, true ), - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'menu_location_custom' => array( - 'label' => __( 'Parent Menu ID (optional)', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'menu_name' => array( - 'label' => __( 'Menu Name', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'menu_position' => array( - 'label' => __( 'Menu Position', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'number', - 'number_decimals' => 2, - 'number_format' => '9999.99', - 'number_format_soft' => 1, - 'default' => 0, - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'menu_icon' => array( - 'label' => __( 'Menu Icon', 'pods' ), - 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the site tag type special magic tags. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a Dashicon. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'show_in_nav_menus' => array( - 'label' => __( 'Show in Navigation Menus', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - ), - 'show_in_admin_bar' => array( - 'label' => __( 'Show in Admin Bar "New" Menu', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'name_admin_bar' => array( - 'label' => __( 'Admin bar name', 'pods' ), - 'help' => __( 'Defaults to singular name', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'show_in_admin_bar' => true ), - ), - ); + $pod->flush(); - $post_type_name = pods_v( 'name', $pod, 'post_type', true ); + return $pod; + } - $options['advanced'] = array( - 'public' => array( - 'label' => __( 'Public', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - ), - 'publicly_queryable' => array( - 'label' => __( 'Publicly Queryable', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'public', $pod, true ), - 'boolean_yes_label' => '', - ), - 'exclude_from_search' => array( - 'label' => __( 'Exclude from Search', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => ! pods_v( 'public', $pod, true ), - 'boolean_yes_label' => '', - ), - 'capability_type' => array( - 'label' => __( 'User Capability', 'pods' ), - 'help' => __( 'Uses these capabilties for access to this post type: edit_{capability}, read_{capability}, and delete_{capability}', 'pods' ), - 'type' => 'pick', - 'default' => 'post', - 'data' => array( - 'post' => 'post', - 'page' => 'page', - 'custom' => __( 'Custom Capability', 'pods' ), - ), - 'dependency' => true, - ), - 'capability_type_custom' => array( - 'label' => __( 'Custom User Capability', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => pods_v( 'name', $pod ), - 'depends-on' => array( 'capability_type' => 'custom' ), - ), - 'capability_type_extra' => array( - 'label' => __( 'Additional User Capabilities', 'pods' ), - 'help' => __( 'Enables additional capabilities for this Post Type including: delete_{capability}s, delete_private_{capability}s, delete_published_{capability}s, delete_others_{capability}s, edit_private_{capability}s, and edit_published_{capability}s', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - ), - 'has_archive' => array( - 'label' => __( 'Enable Archive Page', 'pods' ), - 'help' => __( 'If enabled, creates an archive page with list of of items in this custom post type. Functions like a category page for posts. Can be controlled with a template in your theme called "archive-{$post-type}.php".', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'has_archive_slug' => array( - 'label' => __( 'Archive Page Slug Override', 'pods' ), - 'help' => __( 'If archive page is enabled, you can override the slug used by WordPress, which defaults to the name of the post type.', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'has_archive' => true ), - ), - 'hierarchical' => array( - 'label' => __( 'Hierarchical', 'pods' ), - 'help' => __( 'Allows for parent/ child relationships between items, just like with Pages. Note: To edit relationships in the post editor, you must enable "Page Attributes" in the "Supports" section below.', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'label_parent_item_colon' => array( - 'label' => __( 'Label: Parent Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'hierarchical' => true ), - ), - 'label_parent' => array( - 'label' => __( 'Label: Parent', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'hierarchical' => true ), - ), - 'rewrite' => array( - 'label' => __( 'Rewrite', 'pods' ), - 'help' => __( 'Allows you to use pretty permalinks, if set in WordPress Settings->Permalinks. If not enabled, your links will be in the form of "example.com/?pod_name=post_slug" regardless of your permalink settings.', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'rewrite_custom_slug' => array( - 'label' => __( 'Custom Rewrite Slug', 'pods' ), - 'help' => __( 'Changes the first segment of the URL, which by default is the name of the Pod. For example, if your Pod is called "foo", if this field is left blank, your link will be "example.com/foo/post_slug", but if you were to enter "bar" your link will be "example.com/bar/post_slug".', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'rewrite' => true ), - ), - 'rewrite_with_front' => array( - 'label' => __( 'Rewrite with Front', 'pods' ), - 'help' => __( 'Allows permalinks to be prepended with your front base (example: if your permalink structure is /blog/, then your links will be: Unchecked->/news/, Checked->/blog/news/)', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'depends-on' => array( 'rewrite' => true ), - 'boolean_yes_label' => '', - ), - 'rewrite_feeds' => array( - 'label' => __( 'Rewrite Feeds', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'depends-on' => array( 'rewrite' => true ), - 'boolean_yes_label' => '', - ), - 'rewrite_pages' => array( - 'label' => __( 'Rewrite Pages', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'depends-on' => array( 'rewrite' => true ), - 'boolean_yes_label' => '', - ), - 'query_var' => array( - 'label' => __( 'Query Var', 'pods' ), - 'help' => __( 'The Query Var is used in the URL and underneath the WordPress Rewrite API to tell WordPress what page or post type you are on. For a list of reserved Query Vars, read WordPress Query Vars from the WordPress Codex.', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - ), - 'can_export' => array( - 'label' => __( 'Exportable', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - ), - 'default_status' => array( - 'label' => __( 'Default Status', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'pick_object' => 'post-status', - 'default' => apply_filters( "pods_api_default_status_{$post_type_name}", 'draft', $pod ), - ), - ); - } elseif ( 'taxonomy' === $pod['type'] ) { - $options['admin-ui'] = array( - 'description' => array( - 'label' => __( 'Taxonomy Description', 'pods' ), - 'help' => __( 'A short descriptive summary of what the taxonomy is.', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'show_ui' => array( - 'label' => __( 'Show Admin UI', 'pods' ), - 'help' => __( 'Whether to generate a default UI for managing this taxonomy.', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'public', $pod, true ), - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'show_in_menu' => array( - 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ), - 'help' => __( 'Whether to show the taxonomy in the admin menu.', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'public', $pod, true ), - 'dependency' => true, - 'depends-on' => array( 'show_ui' => true ), - 'boolean_yes_label' => '', - ), - 'menu_name' => array( - 'label' => __( 'Menu Name', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'show_ui' => true ), - ), - 'menu_location' => array( - 'label' => __( 'Menu Location', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => 'default', - 'depends-on' => array( 'show_ui' => true ), - 'data' => array( - 'default' => __( 'Default - Add to associated Post Type(s) menus', 'pods' ), - 'settings' => __( 'Add a submenu item to Settings menu', 'pods' ), - 'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ), - 'submenu' => __( 'Add a submenu item to another menu', 'pods' ), - 'objects' => __( 'Make a new menu item', 'pods' ), - 'top' => __( 'Make a new menu item below Settings', 'pods' ), - ), - 'dependency' => true, - ), - 'menu_location_custom' => array( - 'label' => __( 'Custom Menu Location', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'depends-on' => array( 'menu_location' => 'submenu' ), - ), - 'menu_position' => array( - 'label' => __( 'Menu Position', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'number', - 'number_decimals' => 2, - 'number_format' => '9999.99', - 'number_format_soft' => 1, - 'default' => 0, - 'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) ), - ), - 'menu_icon' => array( - 'label' => __( 'Menu Icon URL', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) ), - ), - 'show_in_nav_menus' => array( - 'label' => __( 'Show in Navigation Menus', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'public', $pod, true ), - 'boolean_yes_label' => '', - ), - 'show_tagcloud' => array( - 'label' => __( 'Allow in Tagcloud Widget', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ), - 'boolean_yes_label' => '', - ), - // @todo check https://core.trac.wordpress.org/ticket/36964 - 'show_tagcloud_in_edit' => array( - 'label' => __( 'Allow Tagcloud on term edit pages', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'show_ui', $pod, pods_v( 'show_tagcloud', $pod, true ) ), - 'boolean_yes_label' => '', - ), - 'show_in_quick_edit' => array( - 'label' => __( 'Allow in quick/bulk edit panel', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ), - 'boolean_yes_label' => '', - ), - ); + $groups = wp_list_pluck( $groups, 'id' ); + $groups = array_filter( $groups ); - $options['admin-ui']['show_admin_column'] = array( - 'label' => __( 'Show Taxonomy column on Post Types', 'pods' ), - 'help' => __( 'Whether to add a column for this taxonomy on the associated post types manage screens', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'boolean_yes_label' => '', - ); + if ( ! empty( $groups ) ) { + $group_id = reset( $groups ); + } + } - // Integration for Single Value Taxonomy UI - if ( function_exists( 'tax_single_value_meta_box' ) ) { - $options['admin-ui']['single_value'] = array( - 'label' => __( 'Single Value Taxonomy', 'pods' ), - 'help' => __( 'Use a drop-down for the input instead of the WordPress default', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'boolean_yes_label' => '', - ); + $fields = $pod->get_fields( [ + 'fallback_mode' => false, + 'group' => null, + ] ); - $options['admin-ui']['single_value_required'] = array( - 'label' => __( 'Single Value Taxonomy - Required', 'pods' ), - 'help' => __( 'A term will be selected by default in the Post Editor, not optional', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'boolean_yes_label' => '', - ); + if ( empty( $group_id ) ) { + $label = __( 'Details', 'pods' ); + + if ( in_array( $pod->get_type(), [ 'post_type', 'taxonomy', 'user', 'comment', 'media' ], true ) ) { + $label = __( 'More Fields', 'pods' ); } - $options['advanced'] = array( - 'public' => array( - 'label' => __( 'Public', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - ), - 'hierarchical' => array( - 'label' => __( 'Hierarchical', 'pods' ), - 'help' => __( 'Hierarchical taxonomies will have a list with checkboxes to select an existing category in the taxonomy admin box on the post edit page (like default post categories). Non-hierarchical taxonomies will just have an empty text field to type-in taxonomy terms to associate with the post (like default post tags).', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'label_parent_item_colon' => array( - 'label' => __( 'Label: Parent Item', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'hierarchical' => true ), - ), - 'label_parent' => array( - 'label' => __( 'Label: Parent', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'hierarchical' => true ), - ), - 'label_no_terms' => array( - 'label' => __( 'Label: No Items', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'hierarchical' => true ), - ), - 'rewrite' => array( - 'label' => __( 'Rewrite', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'rewrite_custom_slug' => array( - 'label' => __( 'Custom Rewrite Slug', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'rewrite' => true ), - ), - 'rewrite_with_front' => array( - 'label' => __( 'Rewrite with Front', 'pods' ), - 'help' => __( 'Allows permalinks to be prepended with your front base (example: if your permalink structure is /blog/, then your links will be: Unchecked->/news/, Checked->/blog/news/)', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - 'depends-on' => array( 'rewrite' => true ), - ), - 'rewrite_hierarchical' => array( - 'label' => __( 'Hierarchical Permalinks', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => true, - 'boolean_yes_label' => '', - 'depends-on' => array( 'rewrite' => true ), - ), - 'capability_type' => array( - 'label' => __( 'User Capability', 'pods' ), - 'help' => __( 'Uses WordPress term capabilities by default', 'pods' ), - 'type' => 'pick', - 'default' => 'default', - 'data' => array( - 'default' => 'Default', - 'custom' => __( 'Custom Capability', 'pods' ), - ), - 'dependency' => true, - ), - 'capability_type_custom' => array( - 'label' => __( 'Custom User Capability', 'pods' ), - 'help' => __( 'Enables additional capabilities for this Taxonomy including: manage_{capability}_terms, edit_{capability}_terms, assign_{capability}_terms, and delete_{capability}_terms', 'pods' ), - 'type' => 'text', - 'default' => pods_v( 'name', $pod ), - 'depends-on' => array( 'capability_type' => 'custom' ), - ), - 'query_var' => array( - 'label' => __( 'Query Var', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'dependency' => true, - 'boolean_yes_label' => '', - ), - 'query_var_string' => array( - 'label' => __( 'Custom Query Var Name', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'query_var' => true ), - ), - 'sort' => array( - 'label' => __( 'Remember order saved on Post Types', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'boolean_yes_label' => '', - ), - 'update_count_callback' => array( - 'label' => __( 'Function to call when updating counts', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - ); - } elseif ( 'settings' === $pod['type'] ) { - $options['admin-ui'] = array( - 'ui_style' => array( - 'label' => __( 'Admin UI Style', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => 'settings', - 'data' => array( - 'settings' => __( 'Normal Settings Form', 'pods' ), - 'post_type' => __( 'Post Type UI', 'pods' ), - 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ), - ), - 'dependency' => true, - ), - 'menu_location' => array( - 'label' => __( 'Menu Location', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => 'settings', - 'data' => array( - 'settings' => __( 'Add a submenu item to Settings menu', 'pods' ), - 'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ), - 'submenu' => __( 'Add a submenu item to another menu', 'pods' ), - 'top' => __( 'Make a new menu item below Settings', 'pods' ), - ), - 'dependency' => true, - ), - 'menu_location_custom' => array( - 'label' => __( 'Custom Menu Location', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'depends-on' => array( 'menu_location' => 'submenu' ), - ), - 'menu_position' => array( - 'label' => __( 'Menu Position', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'number', - 'number_decimals' => 2, - 'number_format' => '9999.99', - 'number_format_soft' => 1, - 'default' => 0, - 'depends-on' => array( 'menu_location' => 'top' ), - ), - 'menu_icon' => array( - 'label' => __( 'Menu Icon URL', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'menu_location' => 'top' ), - ), - ); - - // @todo fill this in - $options['advanced'] = array( - 'temporary' => 'This type has the fields hardcoded', - // :( - ); - } elseif ( 'pod' === $pod['type'] ) { - $actions_enabled = array( - 'add', - 'edit', - 'duplicate', - 'delete', - ); - - if ( 1 === (int) pods_v( 'ui_export', $pod ) ) { - $actions_enabled = array( - 'add', - 'edit', - 'duplicate', - 'delete', - 'export', - ); - } - - $options['admin-ui'] = array( - 'ui_style' => array( - 'label' => __( 'Admin UI Style', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => 'settings', - 'data' => array( - 'post_type' => __( 'Normal (Looks like the Post Type UI)', 'pods' ), - 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ), - ), - 'dependency' => true, - ), - 'show_in_menu' => array( - 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'boolean', - 'default' => false, - 'boolean_yes_label' => '', - 'dependency' => true, - ), - 'menu_location_custom' => array( - 'label' => __( 'Parent Menu ID (optional)', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'menu_position' => array( - 'label' => __( 'Menu Position', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'number', - 'number_decimals' => 2, - 'number_format' => '9999.99', - 'number_format_soft' => 1, - 'default' => 0, - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'menu_icon' => array( - 'label' => __( 'Menu Icon URL', 'pods' ), - 'help' => __( 'This is the icon shown to the left of the menu text for this content type.', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'ui_icon' => array( - 'label' => __( 'Header Icon', 'pods' ), - 'help' => __( 'This is the icon shown to the left of the heading text at the top of the manage pages for this content type.', 'pods' ), - 'type' => 'file', - 'default' => '', - 'file_edit_title' => 0, - 'depends-on' => array( 'show_in_menu' => true ), - ), - 'ui_actions_enabled' => array( - 'label' => __( 'Actions Available', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => $actions_enabled, - 'data' => array( - 'add' => __( 'Add New', 'pods' ), - 'edit' => __( 'Edit', 'pods' ), - 'duplicate' => __( 'Duplicate', 'pods' ), - 'delete' => __( 'Delete', 'pods' ), - 'reorder' => __( 'Reorder', 'pods' ), - 'export' => __( 'Export', 'pods' ), - ), - 'pick_format_type' => 'multi', - 'dependency' => true, - ), - 'ui_reorder_field' => array( - 'label' => __( 'Reorder Field', 'pods' ), - 'help' => __( 'This is the field that will be reordered on, it should be numeric.', 'pods' ), - 'type' => 'text', - 'default' => 'menu_order', - 'depends-on' => array( 'ui_actions_enabled' => 'reorder' ), - ), - 'ui_fields_manage' => array( - 'label' => __( 'Admin Table Columns', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => array(), - 'data' => array(), - 'pick_format_type' => 'multi', - ), - 'ui_filters' => array( - 'label' => __( 'Search Filters', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => array(), - 'data' => array(), - 'pick_format_type' => 'multi', - ), - ); - - if ( ! empty( $pod['fields'] ) ) { - if ( isset( $pod['fields'][ pods_v( 'pod_index', $pod, 'name' ) ] ) ) { - $options['admin-ui']['ui_fields_manage']['default'][] = pods_v( 'pod_index', $pod, 'name' ); - } - - if ( isset( $pod['fields']['modified'] ) ) { - $options['admin-ui']['ui_fields_manage']['default'][] = 'modified'; - } - - foreach ( $pod['fields'] as $field ) { - $type = ''; - - if ( isset( $field_types[ $field['type'] ] ) ) { - $type = ' (' . $field_types[ $field['type'] ]['label'] . ')'; - } + /** + * Filter the title of the Pods Metabox used in the post editor. + * + * @since unknown + * + * @param string $title The title to use, default is 'More Fields'. + * @param obj|Pod $pod Current Pods Object. + * @param array $fields Array of fields that will go in the metabox. + * @param string $type The type of Pod. + * @param string $name Name of the Pod. + */ + $label = apply_filters( 'pods_meta_default_box_title', $label, $pod, $fields, $pod->get_type(), $pod->get_name() ); + $name = sanitize_key( pods_js_name( sanitize_title( $label ) ) ); + + // Setup first group. + $group_id = $api->save_group( [ + 'pod' => $pod, + 'name' => $name, + 'label' => $label, + ] ); + } - $options['admin-ui']['ui_fields_manage']['data'][ $field['name'] ] = $field['label'] . $type; - $options['admin-ui']['ui_filters']['data'][ $field['name'] ] = $field['label'] . $type; - } + foreach ( $fields as $field ) { + $api->save_field( [ + 'id' => $field->get_id(), + 'pod_data' => $pod, + 'field' => $field, + 'new_group_id' => $group_id, + ], false ); - $options['admin-ui']['ui_fields_manage']['data']['id'] = 'ID'; - } else { - unset( $options['admin-ui']['ui_fields_manage'] ); - unset( $options['admin-ui']['ui_filters'] ); - }//end if + $field->set_arg( 'group_id', $group_id ); + } - // @todo fill this in - $options['advanced'] = array( - 'temporary' => 'This type has the fields hardcoded', - // :( - ); - }//end if + $pod->set_arg( '_migrated_28', 1 ); - $pod_type = $pod['type']; - $pod_name = $pod['name']; + $api->save_pod( $pod ); - /** - * Add admin fields to the Pods editor for a specific Pod - * - * @param array $options The Options fields. - * @param object $pod Current Pods object. - * - * @since unkown - */ - $options = apply_filters( "pods_admin_setup_edit_options_{$pod_type}_{$pod_name}", $options, $pod ); + $pod->flush(); - /** - * Add admin fields to the Pods editor for any Pod of a specific content type. - * - * @param array $options The Options fields. - * @param object $pod Current Pods object. - */ - $options = apply_filters( "pods_admin_setup_edit_options_{$pod_type}", $options, $pod ); + $api->cache_flush_pods( $pod ); - /** - * Add admin fields to the Pods editor for all Pods - * - * @param array $options The Options fields. - * @param object $pod Current Pods object. - */ - $options = apply_filters( 'pods_admin_setup_edit_options', $options, $pod ); + // Refresh pod object. + $pod->flush(); - return $options; + return $pod; } /** - * Get list of Pod field option tabs + * Get the global config for Pods admin. * - * @param array $pod Pod options. + * @since 2.8.0 * - * @return array + * @param null|\Pods\Whatsit $pod + * + * @return array Global config array. */ - public function admin_setup_edit_field_tabs( $pod ) { - - $core_tabs = array( - 'basic' => __( 'Basic', 'pods' ), - 'additional-field' => __( 'Additional Field Options', 'pods' ), - 'advanced' => __( 'Advanced', 'pods' ), - ); + public function get_global_config( $pod = null ) { + $config_pod = tribe( \Pods\Admin\Config\Pod::class ); + $config_group = tribe( \Pods\Admin\Config\Group::class ); + $config_field = tribe( \Pods\Admin\Config\Field::class ); + + // Pod: Backwards compatible configs and hooks. + $pod_tabs = $config_pod->get_tabs( $pod ); + $pod_tab_options = $config_pod->get_fields( $pod, $pod_tabs ); + + $this->backcompat_convert_tabs_to_groups( $pod_tabs, $pod_tab_options, 'pod/_pods_pod' ); + + // Group: Backwards compatible methods and hooks. + $group_tabs = $config_group->get_tabs( $pod ); + $group_tab_options = $config_group->get_fields( $pod, $group_tabs ); + + $this->backcompat_convert_tabs_to_groups( $group_tabs, $group_tab_options, 'pod/_pods_group' ); + + // Field: Backwards compatible methods and hooks. + $field_tabs = $config_field->get_tabs( $pod ); + $field_tab_options = $config_field->get_fields( $pod, $field_tabs ); + + $this->backcompat_convert_tabs_to_groups( $field_tabs, $field_tab_options, 'pod/_pods_field' ); + + $object_collection = Pods\Whatsit\Store::get_instance(); + + /** @var Pods\Whatsit\Storage $storage */ + $storage = $object_collection->get_storage_object( 'collection' ); + + // Get objects from storage. + $pod_object = $storage->get( [ + 'object_type' => 'pod', + 'name' => '_pods_pod', + ] ); + + $group_object = $storage->get( [ + 'object_type' => 'pod', + 'name' => '_pods_group', + ] ); + + $field_object = $storage->get( [ + 'object_type' => 'pod', + 'name' => '_pods_field', + ] ); + + $pod = [ + 'pod' => $pod_object->export( [ + 'include_groups' => true, + 'include_group_fields' => true, + 'include_fields' => false, + 'include_field_data' => true, + ] ), + 'group' => $group_object->export( [ + 'include_groups' => true, + 'include_group_fields' => true, + 'include_fields' => false, + 'include_field_data' => true, + ] ), + 'field' => $field_object->export( [ + 'include_groups' => true, + 'include_group_fields' => true, + 'include_fields' => false, + 'include_field_data' => true, + ] ), + ]; /** - * Field option tabs + * Allow hooking into the global config setup for a Pod. * - * Use to add new tabs, default tabs are added after this filter (IE you can't remove/modify them with this, kthanksbye). - * - * @since unknown - * - * @param array $tabs Tabs to add, starts empty. - * @param object|Pod $pod Current Pods object. + * @param null|\Pods\Whatsit $pod The Pod object. */ - $tabs = apply_filters( 'pods_admin_setup_edit_field_tabs', array(), $pod ); - - $tabs = array_merge( $core_tabs, $tabs ); + $pod = apply_filters( 'pods_admin_setup_global_config', $pod ); - return $tabs; + return $pod; } /** - * Get list of Pod field options + * Convert the tabs and their options to groups/fields in the collection storage. * - * @param array $pod Pod options. + * @since 2.8.0 * - * @return array + * @param array $tabs List of registered tabs. + * @param array $options List of tab options. + * @param string $parent The parent object to register to. + * + * @return array Global config array. */ - public function admin_setup_edit_field_options( $pod ) { + protected function backcompat_convert_tabs_to_groups( array $tabs, array $options, $parent ) { + $object_collection = Pods\Whatsit\Store::get_instance(); - $options = array(); + /** @var Pods\Whatsit\Storage\Collection $storage */ + $storage = $object_collection->get_storage_object( 'collection' ); - $options['additional-field'] = array(); + $groups = []; + $fields = []; - $field_types = PodsForm::field_types(); + foreach ( $tabs as $group_name => $group_label ) { + if ( empty( $options[ $group_name ] ) ) { + continue; + } - foreach ( $field_types as $type => $field_type_data ) { - /** - * @var $field_type PodsField - */ - $field_type = PodsForm::field_loader( $type, $field_type_data['file'] ); + if ( is_array( $group_label ) ) { + $group_args = $group_label; + } else { + $group_args = [ + 'name' => $group_name, + 'label' => $group_label, + ]; + } + + $group_args['parent'] = $parent; - $field_type_vars = get_class_vars( get_class( $field_type ) ); + $group = new \Pods\Whatsit\Group( $group_args ); - if ( ! isset( $field_type_vars['pod_types'] ) ) { - $field_type_vars['pod_types'] = true; + $groups[] = $storage->add( $group ); + + $group_fields = $options[ $group_name ]; + + $sections = false; + + foreach ( $group_fields as $field_name => $field_options ) { + // Support sections. + if ( ! isset( $field_options['label'] ) ) { + $sections = true; + } + + break; } - $options['additional-field'][ $type ] = array(); + $group_sections = $group_fields; - // Only show supported field types - if ( true !== $field_type_vars['pod_types'] ) { - if ( empty( $field_type_vars['pod_types'] ) ) { - continue; - } elseif ( is_array( $field_type_vars['pod_types'] ) && ! in_array( pods_v( 'type', $pod ), $field_type_vars['pod_types'], true ) ) { - continue; - } elseif ( ! is_array( $field_type_vars['pod_types'] ) && pods_v( 'type', $pod ) !== $field_type_vars['pod_types'] ) { + // Store the same whether it's a section or not. + if ( ! $sections ) { + $group_sections = [ + $group_fields, + ]; + } + + foreach ( $group_sections as $section_label => $section_fields ) { + // Add section field (maybe). + if ( ! is_int( $section_label ) ) { + $field_args = [ + 'name' => sanitize_title( $section_label ), + 'label' => $section_label, + 'type' => 'heading', + 'parent' => $parent, + 'group' => 'group/' . $parent . '/' . $group_name, + ]; + + $field = new \Pods\Whatsit\Field( $field_args ); + + $fields[] = $storage->add( $field ); + } + + if ( ! is_array( $section_fields ) ) { continue; } - } - $options['additional-field'][ $type ] = PodsForm::ui_options( $type ); + // Add fields for section. + foreach ( $section_fields as $field_name => $field_options ) { + $boolean_group = []; - /** - * Modify Additional Field Options tab - * - * @since 2.7.0 - * - * @param array $options Additional field type options, - * @param string $type Field type, - * @param array $options Tabs, indexed by label, - * @param object|Pods $pod Pods object for the Pod this UI is for. - */ - $options['additional-field'][ $type ] = apply_filters( "pods_admin_setup_edit_{$type}_additional_field_options", $options['additional-field'][ $type ], $type, $options, $pod ); - $options['additional-field'][ $type ] = apply_filters( 'pods_admin_setup_edit_additional_field_options', $options['additional-field'][ $type ], $type, $options, $pod ); - }//end foreach + // Handle auto-formatting from shorthand. + if ( ! empty( $field_options['boolean_group'] ) ) { + $boolean_group = $field_options['boolean_group']; - $input_helpers = array( - '' => '-- Select --', - ); + foreach ( $boolean_group as $bgf_key => $boolean_group_field ) { + // Make sure each field has a field name. + if ( is_string( $bgf_key ) ) { + $boolean_group[ $bgf_key ]['name'] = $bgf_key; + } + } + + $boolean_group = array_values( $boolean_group ); - if ( class_exists( 'Pods_Helpers' ) ) { - $helpers = pods_api()->load_helpers( array( 'options' => array( 'helper_type' => 'input' ) ) ); + $field_options['boolean_group'] = $boolean_group; + } - foreach ( $helpers as $helper ) { - $input_helpers[ $helper['name'] ] = $helper['name']; + if ( empty( $field_options['type'] ) ) { + continue; + } + + // Set a unique field name for boolean group headings. + if ( ! empty( $boolean_group ) ) { + $field_options['name'] = $field_name . '_' . md5( json_encode( $boolean_group ) ); + } + + $field = $this->backcompat_convert_tabs_to_groups_setup_field( [ + 'field_name' => $field_name, + 'field_options' => $field_options, + 'parent' => $parent, + 'group_name' => $group_name, + ] ); + + $fields[] = $storage->add( $field ); + } } } - $options['advanced'] = array( - __( 'Visual', 'pods' ) => array( - 'class' => array( - 'name' => 'class', - 'label' => __( 'Additional CSS Classes', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'input_helper' => array( - 'name' => 'input_helper', - 'label' => __( 'Input Helper', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'default' => '', - 'data' => $input_helpers, - ), - ), - __( 'Values', 'pods' ) => array( - 'default_value' => array( - 'name' => 'default_value', - 'label' => __( 'Default Value', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'options' => array( - 'text_max_length' => - 1, - ), - ), - 'default_value_parameter' => array( - 'name' => 'default_value_parameter', - 'label' => __( 'Set Default Value via Parameter', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - ), - __( 'Visibility', 'pods' ) => array( - 'restrict_access' => array( - 'name' => 'restrict_access', - 'label' => __( 'Restrict Access', 'pods' ), - 'group' => array( - 'admin_only' => array( - 'name' => 'admin_only', - 'label' => __( 'Restrict access to Admins?', 'pods' ), - 'default' => 0, - 'type' => 'boolean', - 'dependency' => true, - 'help' => __( 'This field will only be able to be edited by users with the ability to manage_options or delete_users, or super admins of a WordPress Multisite network', 'pods' ), - ), - 'restrict_role' => array( - 'name' => 'restrict_role', - 'label' => __( 'Restrict access by Role?', 'pods' ), - 'default' => 0, - 'type' => 'boolean', - 'dependency' => true, - ), - 'restrict_capability' => array( - 'name' => 'restrict_capability', - 'label' => __( 'Restrict access by Capability?', 'pods' ), - 'default' => 0, - 'type' => 'boolean', - 'dependency' => true, - ), - 'hidden' => array( - 'name' => 'hidden', - 'label' => __( 'Hide field from UI', 'pods' ), - 'default' => 0, - 'type' => 'boolean', - 'help' => __( 'This option is overriden by access restrictions. If the user does not have access to edit this field, it will be hidden. If no access restrictions are set, this field will always be hidden.', 'pods' ), - ), - 'read_only' => array( - 'name' => 'read_only', - 'label' => __( 'Make field "Read Only" in UI', 'pods' ), - 'default' => 0, - 'type' => 'boolean', - 'help' => __( 'This option is overriden by access restrictions. If the user does not have access to edit this field, it will be read only. If no access restrictions are set, this field will always be read only.', 'pods' ), - 'depends-on' => array( - 'type' => array( - 'boolean', - 'color', - 'currency', - 'date', - 'datetime', - 'email', - 'number', - 'paragraph', - 'password', - 'phone', - 'slug', - 'text', - 'time', - 'website', - ), - ), - ), - ), - ), - 'roles_allowed' => array( - 'name' => 'roles_allowed', - 'label' => __( 'Role(s) Allowed', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'pick', - 'pick_object' => 'role', - 'pick_format_type' => 'multi', - 'default' => 'administrator', - 'depends-on' => array( - 'restrict_role' => true, - ), - ), - 'capability_allowed' => array( - 'name' => 'capability_allowed', - 'label' => __( 'Capability Allowed', 'pods' ), - 'help' => __( 'Comma-separated list of cababilities, for example add_podname_item, please see the Roles and Capabilities component for the complete list and a way to add your own.', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( - 'restrict_capability' => true, - ), - ), - ), - ); + return compact( 'groups', 'fields' ); + } - /* - $options['advanced'][ __( 'Visibility', 'pods' ) ]['search'] = array( - 'label' => __( 'Include in searches', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'default' => 1, - 'type' => 'boolean', - ); - */ - - /* - $options['advanced'][ __( 'Validation', 'pods' ) ] = array( - 'regex_validation' => array( - 'label' => __( 'RegEx Validation', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'message_regex' => array( - 'label' => __( 'Message if field does not pass RegEx', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - ), - 'message_required' => array( - 'label' => __( 'Message if field is blank', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'required' => true ), - ), - 'message_unique' => array( - 'label' => __( 'Message if field is not unique', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'unique' => true ), - ), - ); - */ + /** + * Setup field for backwards compatibility tabs to groups layer. + * + * @since 2.8.0 + * + * @param array $args { + * The field arguments. + * + * @type string $field_name The field name. + * @type array $field_options The field options. + * @type string|int $parent The parent group. + * @type string $group_name The group name. + * } + * + * @return \Pods\Whatsit\Field The field object. + */ + public function backcompat_convert_tabs_to_groups_setup_field( $args ) { + $field_name = $args['field_name']; + $field_options = $args['field_options']; + $parent = $args['parent']; + $group_name = $args['group_name']; + + $field_args = $field_options; - if ( ! class_exists( 'Pods_Helpers' ) ) { - unset( $options['advanced']['input_helper'] ); + if ( ! isset( $field_args['name'] ) ) { + $field_args['name'] = $field_name; } - /** - * Modify tabs and their contents for field options - * - * @since unknown - * - * @param array $options Tabs, indexed by label. - * @param object|Pods $pod Pods object for the Pod this UI is for. - */ - $options = apply_filters( 'pods_admin_setup_edit_field_options', $options, $pod ); + $field_args['parent'] = $parent; + $field_args['group'] = 'group/' . $parent . '/' . $group_name; + + $dfv_args = (object) [ + 'id' => 0, + 'name' => $field_args['name'], + 'value' => '', + 'pod' => null, + 'type' => pods_v( 'type', $field_args ), + 'options' => array_merge( [ + 'id' => 0, + ], $field_args ) + ]; + + if ( ! empty( $dfv_args->type ) ) { + $field_args = PodsForm::field_method( $dfv_args->type, 'build_dfv_field_options', $field_args, $dfv_args ); + } - return $options; + return new \Pods\Whatsit\Field( $field_args ); } /** @@ -2754,7 +1764,6 @@ public function admin_setup_edit_field_options( $pod ) { * @param PodsUI $obj PodsUI object. */ public function admin_setup_duplicate( $obj ) { - $new_id = pods_api()->duplicate_pod( array( 'id' => $obj->id ) ); if ( 0 < $new_id ) { @@ -2767,7 +1776,11 @@ public function admin_setup_duplicate( $obj ) { ) ) ); + + return; } + + $obj->error( __( 'An error occurred, the Pod was not duplicated.', 'pods' ) ); } /** @@ -2851,12 +1864,12 @@ public function admin_setup_reset_restrict( $restricted, $restrict, $action, $ro /** * Delete a pod * - * @param int|string $id Item ID. * @param PodsUI $obj PodsUI object. + * @param int|string $id Item ID. * * @return mixed */ - public function admin_setup_delete( $id, $obj ) { + public function admin_setup_delete( $obj, $id ) { $pod = pods_api()->load_pod( array( 'id' => $id ), false ); @@ -2866,12 +1879,18 @@ public function admin_setup_delete( $id, $obj ) { pods_api()->delete_pod( array( 'id' => $id ) ); - unset( $obj->data[ $pod['id'] ] ); + foreach ( $obj->data as $key => $data_pod ) { + if ( (int) $id === (int) $data_pod['id'] ) { + unset( $obj->data[ $key ] ); + } + } $obj->total = count( $obj->data ); $obj->total_found = count( $obj->data ); $obj->message( __( 'Pod deleted successfully.', 'pods' ) ); + + $obj->manage(); } /** @@ -2886,6 +1905,12 @@ public function admin_advanced() { * Get settings administration view */ public function admin_settings() { + /** + * Allow hooking into our settings page to set up hooks. + * + * @since 2.8.0 + */ + do_action( 'pods_admin_settings_init' ); // Add our custom callouts. add_action( 'pods_admin_after_settings', array( $this, 'admin_manage_callouts' ) ); @@ -3015,6 +2040,9 @@ public function admin_components() { }//end foreach $ui = array( + 'sql' => array( + 'field_id' => 'id', + ), 'data' => $components, 'total' => count( $components ), 'total_found' => count( $components ), @@ -3249,23 +2277,20 @@ public function admin_capabilities( $capabilities ) { $pods = pods_api()->load_pods( array( - 'type' => array( + 'type' => array( 'settings', 'post_type', 'taxonomy', ), - 'fields' => false, - 'table_info' => false, ) ); $other_pods = pods_api()->load_pods( array( - 'type' => array( + 'type' => array( 'pod', 'table', ), - 'table_info' => false, ) ); @@ -3322,14 +2347,16 @@ public function admin_capabilities( $capabilities ) { } else { $capabilities[] = 'pods_add_' . $pod['name']; $capabilities[] = 'pods_edit_' . $pod['name']; + $capabilities[] = 'pods_delete_' . $pod['name']; - if ( isset( $pod['fields']['author'] ) && 'pick' === $pod['fields']['author']['type'] && 'user' === $pod['fields']['author']['pick_object'] ) { - $capabilities[] = 'pods_edit_others_' . $pod['name']; + if ( $pod instanceof Pod ) { + $author_field = $pod->get_field( 'author', null, false ); + } else { + $author_field = pods_v( 'author', $pod['fields'] ); } - $capabilities[] = 'pods_delete_' . $pod['name']; - - if ( isset( $pod['fields']['author'] ) && 'pick' === $pod['fields']['author']['type'] && 'user' === $pod['fields']['author']['pick_object'] ) { + if ( $author_field && 'pick' === $author_field['type'] && 'user' === $author_field['pick_object'] ) { + $capabilities[] = 'pods_edit_others_' . $pod['name']; $capabilities[] = 'pods_delete_others_' . $pod['name']; } @@ -3536,8 +2563,10 @@ public function admin_ajax() { * @return array * * @since 2.7.0 + * @deprecated 2.8.0 */ public function configuration( $pod = null, $full_field_info = false ) { + pods_deprecated( 'PodsAdmin::configuration', '2.8' ); $api = pods_api(); @@ -3612,7 +2641,7 @@ protected function rest_admin() { 'add_rest_fields_to_field_editor', ), 12, 2 ); - add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'add_rest_field_tab' ), 12 ); + add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'add_rest_field_tab' ), 12, 2 ); } add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'add_rest_settings_tab' ), 12, 2 ); @@ -3657,6 +2686,9 @@ protected function restable_pod( $pod ) { * @return array */ public function add_rest_settings_tab( $tabs, $pod ) { + if ( ! $this->restable_pod( $pod ) ) { + return $tabs; + } $tabs['rest-api'] = __( 'REST API', 'pods' ); @@ -3675,62 +2707,43 @@ public function add_rest_settings_tab( $tabs, $pod ) { * @return array */ public function add_rest_settings_tab_fields( $options, $pod ) { + if ( ! $this->restable_pod( $pod ) ) { + return $options; + } - if ( ! function_exists( 'register_rest_field' ) ) { - $options['rest-api'] = array( - 'no_dependencies' => array( - 'label' => sprintf( __( 'Pods REST API support requires WordPress 4.3.1 or later and the %s or later.', 'pods' ), 'WordPress REST API 2.0-beta9' ), - 'help' => sprintf( __( 'See %s for more information.', 'pods' ), 'https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/' ), - 'type' => 'html', - ), - ); - } elseif ( $this->restable_pod( $pod ) ) { - $options['rest-api'] = array( - 'rest_enable' => array( - 'label' => __( 'Enable', 'pods' ), - 'help' => __( 'Add REST API support for this Pod.', 'pods' ), - 'type' => 'boolean', - 'default' => '', - 'dependency' => true, - ), - 'rest_base' => array( - 'label' => __( 'REST Base (if any)', 'pods' ), - 'help' => __( 'This will form the url for the route. Default / empty value here will use the pod name.', 'pods' ), - 'type' => 'text', - 'default' => '', - 'depends-on' => array( 'rest_enable' => true ), - ), - 'read_all' => array( - 'label' => __( 'Show All Fields (read-only)', 'pods' ), - 'help' => __( 'Show all fields in REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ), - 'type' => 'boolean', - 'default' => '', - 'depends-on' => array( 'rest_enable' => true ), - ), - 'write_all' => array( - 'label' => __( 'Allow All Fields To Be Updated', 'pods' ), - 'help' => __( 'Allow all fields to be updated via the REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ), - 'type' => 'boolean', - 'default' => pods_v( 'name', $pod ), - 'boolean_yes_label' => '', - 'depends-on' => array( 'rest_enable' => true ), - ), - - ); - - } else { - $options['rest-api'] = array( - 'not_restable' => array( - 'label' => __( 'Pods REST API support covers post type, taxonomy and user Pods.', 'pods' ), - 'help' => sprintf( __( 'See %s for more information.', 'pods' ), 'https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/"' ), - 'type' => 'html', - ), - ); - - }//end if + $options['rest-api'] = [ + 'rest_enable' => [ + 'label' => __( 'Enable', 'pods' ), + 'help' => __( 'Add REST API support for this Pod.', 'pods' ), + 'type' => 'boolean', + 'default' => '', + 'dependency' => true, + ], + 'rest_base' => [ + 'label' => __( 'REST Base (if any)', 'pods' ), + 'help' => __( 'This will form the url for the route. Default / empty value here will use the pod name.', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'rest_enable' => true ], + ], + 'read_all' => [ + 'label' => __( 'Show All Fields (read-only)', 'pods' ), + 'help' => __( 'Show all fields in REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ), + 'type' => 'boolean', + 'default' => '', + 'depends-on' => [ 'rest_enable' => true ], + ], + 'write_all' => [ + 'label' => __( 'Allow All Fields To Be Updated', 'pods' ), + 'help' => __( 'Allow all fields to be updated via the REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'name', $pod ), + 'boolean_yes_label' => '', + 'depends-on' => [ 'rest_enable' => true ], + ], + ]; return $options; - } /** @@ -3744,64 +2757,72 @@ public function add_rest_settings_tab_fields( $options, $pod ) { * @return array */ public function add_rest_fields_to_field_editor( $options, $pod ) { + if ( ! $this->restable_pod( $pod ) ) { + return $options; + } - if ( $this->restable_pod( $pod ) ) { - $options['rest'][ __( 'Read/ Write', 'pods' ) ] = array( - 'rest_read' => array( - 'label' => __( 'Read via REST API?', 'pods' ), - 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ), - 'type' => 'boolean', - 'default' => '', - ), - 'rest_write' => array( - 'label' => __( 'Write via REST API?', 'pods' ), - 'help' => __( 'Should this field be writeable via the REST API? You must enable REST API support for this Pod. For relationship and file fields, you will always pass the ID of the related item/file. If this is a non-ID based relationship field, you will pass the related value (not label).', 'pods' ), - 'type' => 'boolean', - 'default' => '', - ), - ); - $options['rest'][ __( 'Relationship Field Options', 'pods' ) ] = array( - 'rest_pick_response' => array( - 'label' => __( 'Response Type', 'pods' ), - 'help' => __( 'This will determine what amount of data for the related items will be returned.', 'pods' ), - 'type' => 'pick', - 'default' => 'array', - 'depends-on' => array( 'type' => 'pick' ), - 'dependency' => true, - 'data' => array( - 'array' => __( 'All fields', 'pods' ), - 'id' => __( 'ID only', 'pods' ), - 'name' => __( 'Name only', 'pods' ), - 'custom' => __( 'Custom return (specify field to return)', 'pods' ), - ), - ), - 'rest_pick_depth' => array( - 'label' => __( 'Depth', 'pods' ), - 'help' => __( 'How far to traverse relationships in response. 1 will get you all of the fields on the related item. 2 will get you all of those fields plus related items and their fields. The higher the depth, the more data will be returned and the slower performance the REST API calls will be. Updates to this field do NOT take depth into account, so you will always send the ID of the related item when saving.', 'pods' ), - 'type' => 'number', - 'default' => '1', - 'depends-on' => array( - 'type' => 'pick', - 'rest_pick_response' => 'array', - ), - ), - 'rest_pick_custom' => array( - 'label' => __( 'Custom return', 'pods' ), - 'help' => __( 'Specify the field to use following the established this_field_name.ID traversal pattern. You must include this field name in the selector for this to work properly.', 'pods' ), - 'type' => 'text', - 'default' => '', - 'placeholder' => 'this_field_name.ID', - 'depends-on' => array( - 'type' => 'pick', - 'rest_pick_response' => 'custom', - ), - ), - ); - - }//end if + $options['rest'][ __( 'Read/ Write', 'pods' ) ] = [ + 'rest_read' => [ + 'label' => __( 'Read via REST API', 'pods' ), + 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ), + 'type' => 'boolean', + 'default' => '', + ], + 'rest_write' => [ + 'label' => __( 'Write via REST API', 'pods' ), + 'help' => __( 'Should this field be writeable via the REST API? You must enable REST API support for this Pod.', 'pods' ), + 'type' => 'boolean', + 'default' => '', + ], + ]; + + $options['rest'][ __( 'Relationship Field Options', 'pods' ) ] = [ + 'rest_pick_response' => [ + 'label' => __( 'Response Type', 'pods' ), + 'help' => __( 'This will determine what amount of data for the related items will be returned.', 'pods' ), + 'type' => 'pick', + 'default' => 'array', + 'depends-on' => [ + 'type' => 'pick', + ], + 'dependency' => true, + 'data' => [ + 'array' => __( 'All fields', 'pods' ), + 'id' => __( 'ID only', 'pods' ), + 'name' => __( 'Name only', 'pods' ), + 'custom' => __( 'Custom return (specify field to return)', 'pods' ), + ], + ], + 'rest_pick_depth' => [ + 'label' => __( 'Depth', 'pods' ), + 'help' => __( 'How far to traverse relationships in response. 1 will get you all of the fields on the related item. 2 will get you all of those fields plus related items and their fields. The higher the depth, the more data will be returned and the slower performance the REST API calls will be. Updates to this field do NOT take depth into account, so you will always send the ID of the related item when saving.', 'pods' ), + 'type' => 'number', + 'default' => '1', + 'depends-on' => [ + 'type' => 'pick', + 'rest_pick_response' => 'array', + ], + ], + 'rest_pick_custom' => [ + 'label' => __( 'Custom return', 'pods' ), + 'help' => __( 'Specify the field to use following the established this_field_name.ID traversal pattern. You must include this field name in the selector for this to work properly.', 'pods' ), + 'type' => 'text', + 'default' => '', + 'placeholder' => 'this_field_name.ID', + 'depends-on' => [ + 'type' => 'pick', + 'rest_pick_response' => 'custom', + ], + ], + 'rest_pick_notice' => [ + 'label' => 'Relationship Options', + 'type' => 'html', + 'html_content' => __( 'If you have a relationship field, you will see additional options to customize here.', 'pods' ), + 'excludes-on' => [ 'type' => 'pick' ], + ], + ]; return $options; - } /** @@ -3810,10 +2831,14 @@ public function add_rest_fields_to_field_editor( $options, $pod ) { * @since 2.5.6 * * @param array $tabs Tab list. + * @param array $pod The ood object. * * @return array */ - public function add_rest_field_tab( $tabs ) { + public function add_rest_field_tab( $tabs, $pod ) { + if ( ! $this->restable_pod( $pod ) ) { + return $tabs; + } $tabs['rest'] = __( 'REST API', 'pods' ); @@ -3830,118 +2855,211 @@ public function add_rest_field_tab( $tabs ) { * @return array Debug info with Pods-specific debug info added. */ public function add_debug_information( $info ) { - $info['pods'] = array( + $auto_start = pods_session_auto_start(); + + if ( 'auto' !== $auto_start ) { + // Turn boolean into 0/1. + $auto_start = (int) $auto_start; + } + + // Turn into a string. + $auto_start = (string) $auto_start; + + $settings = tribe( Settings::class ); + + $fields = $settings->get_setting_fields(); + + $auto_start = pods_v( $auto_start, $fields['session_auto_start']['data'], __( 'Unknown', 'pods' ) ); + + $info['pods'] = [ 'label' => 'Pods', 'description' => __( 'Debug information for Pods installations.', 'pods' ), - 'fields' => array( - 'pods-server-software' => array( + 'fields' => [ + 'pods-server-software' => [ 'label' => __( 'Server Software', 'pods' ), 'value' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : 'N/A', - ), - 'pods-user-agent' => array( + ], + 'pods-user-agent' => [ 'label' => __( 'Your User Agent', 'pods' ), 'value' => ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : 'N/A', - ), - 'pods-session-save-path' => array( + ], + 'pods-session-save-path' => [ 'label' => __( 'Session Save Path', 'pods' ), 'value' => session_save_path(), - ), - 'pods-session-save-path-exists' => array( + ], + 'pods-session-save-path-exists' => [ 'label' => __( 'Session Save Path Exists', 'pods' ), 'value' => file_exists( session_save_path() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-session-save-path-writable' => array( + ], + 'pods-session-save-path-writable' => [ 'label' => __( 'Session Save Path Writeable', 'pods' ), 'value' => is_writable( session_save_path() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-session-max-lifetime' => array( + ], + 'pods-session-max-lifetime' => [ 'label' => __( 'Session Max Lifetime', 'pods' ), 'value' => ini_get( 'session.gc_maxlifetime' ), - ), - 'pods-opcode-cache-apc' => array( + ], + 'pods-opcode-cache-apc' => [ 'label' => __( 'Opcode Cache: Apc', 'pods' ), 'value' => function_exists( 'apc_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-opcode-cache-memcached' => array( + ], + 'pods-opcode-cache-memcached' => [ 'label' => __( 'Opcode Cache: Memcached', 'pods' ), 'value' => class_exists( 'eaccelerator_put' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-opcode-cache-opcache' => array( + ], + 'pods-opcode-cache-opcache' => [ 'label' => __( 'Opcode Cache: OPcache', 'pods' ), 'value' => function_exists( 'opcache_get_status' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-opcode-cache-redis' => array( + ], + 'pods-opcode-cache-redis' => [ 'label' => __( 'Opcode Cache: Redis', 'pods' ), 'value' => class_exists( 'xcache_set' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-object-cache-apc' => array( + ], + 'pods-object-cache-apc' => [ 'label' => __( 'Object Cache: APC', 'pods' ), 'value' => function_exists( 'apc_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-object-cache-apcu' => array( + ], + 'pods-object-cache-apcu' => [ 'label' => __( 'Object Cache: APCu', 'pods' ), 'value' => function_exists( 'apcu_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-object-cache-memcache' => array( + ], + 'pods-object-cache-memcache' => [ 'label' => __( 'Object Cache: Memcache', 'pods' ), 'value' => class_exists( 'Memcache' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-object-cache-memcached' => array( + ], + 'pods-object-cache-memcached' => [ 'label' => __( 'Object Cache: Memcached', 'pods' ), 'value' => class_exists( 'Memcached' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-object-cache-redis' => array( + ], + 'pods-object-cache-redis' => [ 'label' => __( 'Object Cache: Redis', 'pods' ), 'value' => class_exists( 'Redis' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-memory-current-usage' => array( + ], + 'pods-memory-current-usage' => [ 'label' => __( 'Current Memory Usage', 'pods' ), 'value' => number_format_i18n( memory_get_usage() / 1024 / 1024, 3 ) . 'M', - ), - 'pods-memory-current-usage-real' => array( + ], + 'pods-memory-current-usage-real' => [ 'label' => __( 'Current Memory Usage (real)', 'pods' ), 'value' => number_format_i18n( memory_get_usage( true ) / 1024 / 1024, 3 ) . 'M', - ), - 'pods-network-wide' => array( + ], + 'pods-network-wide' => [ 'label' => __( 'Pods Network-Wide Activated', 'pods' ), 'value' => is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-install-location' => array( + ], + 'pods-install-location' => [ 'label' => __( 'Pods Install Location', 'pods' ), 'value' => PODS_DIR, - ), - 'pods-developer' => array( + ], + 'pods-developer' => [ 'label' => __( 'Pods Developer Activated' ), 'value' => ( pods_developer() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-tableless-mode' => array( + ], + 'pods-tableless-mode' => [ 'label' => __( 'Pods Tableless Mode Activated', 'pods' ), 'value' => ( pods_tableless() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-light-mode' => array( + ], + 'pods-relationship-table-enabled' => [ + 'label' => __( 'Pods Relationship Table Enabled', 'pods' ), + 'value' => ( pods_podsrel_enabled() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), + ], + 'pods-light-mode' => [ 'label' => __( 'Pods Light Mode Activated', 'pods' ), 'value' => ( pods_light() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-strict' => array( + ], + 'pods-strict' => [ 'label' => __( 'Pods Strict Activated' ), - 'value' => ( pods_strict() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-allow-deprecated' => array( + 'value' => ( pods_strict( false ) ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), + ], + 'pods-allow-deprecated' => [ 'label' => __( 'Pods Allow Deprecated' ), 'value' => ( pods_allow_deprecated() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-api-cache' => array( + ], + 'pods-api-cache' => [ 'label' => __( 'Pods API Cache Activated' ), 'value' => ( pods_api_cache() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - 'pods-shortcode-allow-evaluate-tags' => array( + ], + 'pods-shortcode-allow-evaluate-tags' => [ 'label' => __( 'Pods Shortcode Allow Evaluate Tags' ), 'value' => ( pods_shortcode_allow_evaluate_tags() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), - ), - ), - ); + ], + 'pods-sessions' => [ + 'label' => __( 'Pods Sessions' ), + 'value' => $auto_start, + ], + 'pods-can-use-sessions' => [ + 'label' => __( 'Pods Can Use Sessions' ), + 'value' => ( pods_can_use_sessions( true ) ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ), + ], + ], + ]; return $info; } + /** + * Add our site status tests. + * + * @since 2.8.0 + * + * @param array $tests The list of status tests. + * + * @return array The list of status tests. + */ + public function site_status_tests( $tests ) { + $plugin_search_url = 'plugin-install.php?tab=search&type=term&s='; + + if ( is_multisite() && ! is_network_admin() ) { + $plugin_search_url = network_admin_url( $plugin_search_url ); + } else { + $plugin_search_url = self_admin_url( $plugin_search_url ); + } + + if ( ! is_pods_alternative_cache_activated() ) { + $tests['direct']['pods_alternative_cache'] = [ + 'label' => __( 'Pods Alternative Cache', 'pods' ), + 'test' => static function () use ( $plugin_search_url ) { + return [ + 'label' => __( 'The Pods Team recommends you install the Pods Alternative Cache plugin', 'pods' ), + 'status' => 'recommended', + 'badge' => [ + 'label' => __( 'Performance', 'pods' ), + 'color' => 'blue', + ], + 'description' => sprintf( '

%s

', __( 'Pods Alternative Cache is usually useful for Pods installs that use Shared Hosting with limited Object Cache capabilities or limits.', 'pods' ) ), + 'actions' => sprintf( '

%s

', esc_url( $plugin_search_url . urlencode( 'Pods Alternative Cache' ) ), __( 'Install Pods Alternative Cache', 'pods' ) ), + 'test' => 'pods_alternative_cache', + ]; + }, + ]; + } + + // Check if any of the Pods Pro Page Builder Toolkit plugins are active. + $bb_active = defined( 'FL_BUILDER_VERSION' ); + $divi_active = defined( 'ET_BUILDER_PRODUCT_VERSION' ); + $oxygen_active = defined( 'CT_VERSION' ); + $pods_pro_pbtk_active = class_exists( '\Pods_Pro\Page_Builder_Toolkit\Plugin' ); + + if ( ! $pods_pro_pbtk_active && ( $bb_active || $divi_active || $oxygen_active ) ) { + $tests['direct']['pods_pro_page_builder_toolkit'] = [ + 'label' => __( 'Pods Pro Page Builder Toolkit', 'pods' ), + 'test' => static function () { + return [ + 'label' => __( 'The Pods Team recommends you use the Pods Pro Page Builder Toolkit by SKCDEV', 'pods' ), + 'status' => 'recommended', + 'badge' => [ + 'label' => __( 'Page Builder', 'pods' ), + 'color' => 'blue', + ], + 'description' => sprintf( '

%s

', __( 'Pods Pro Page Builder Toolkit by SKCDEV integrates Pods directly with Beaver Builder Themer, Divi, and Oxygen Builder.', 'pods' ) ), + 'actions' => sprintf( '

%s

', esc_url( 'https://pods-pro.skc.dev/?utm_source=pods_plugin_site_health_callout&utm_medium=link&utm_campaign=friends_of_pods_2021' ), __( 'Get Pods Pro by SKCDEV', 'pods' ) ), + 'test' => 'pods_pro_page_builder_toolkit', + ]; + }, + ]; + } + + return $tests; + } + } diff --git a/classes/PodsComponents.php b/classes/PodsComponents.php index cdb1697238..1c440f6764 100644 --- a/classes/PodsComponents.php +++ b/classes/PodsComponents.php @@ -496,9 +496,9 @@ public function get_components() { ksort( $components ); - pods_transient_set( 'pods_components_refresh', 1, ( 60 * 60 * 12 ) ); + pods_transient_set( 'pods_components_refresh', 1, HOUR_IN_SECONDS * 12 ); - pods_transient_set( 'pods_components', $components ); + pods_transient_set( 'pods_components', $components, WEEK_IN_SECONDS ); }//end if if ( 1 === (int) pods_v( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) { diff --git a/classes/PodsData.php b/classes/PodsData.php index 8d706e12c1..da1517224c 100644 --- a/classes/PodsData.php +++ b/classes/PodsData.php @@ -1,7 +1,31 @@ pod_data. + * + * @since 2.8.0 + * * @var array */ - public $where_default = array(); - - /** - * @var string - */ - public $orderby = ''; + public $table_info = null; /** - * @var array + * @var int */ - public $fields = array(); + public $id = 0; /** * @var array */ public $aliases = array(); - /** - * @var - */ - public $detail_page; - /** * @var int */ @@ -113,7 +86,7 @@ class PodsData { /** * @var */ - public $data; + public $rows; /** * @var @@ -155,6 +128,11 @@ class PodsData { */ public $limit = 15; + /** + * @var int + */ + public $offset = 0; + /** * @var bool */ @@ -197,6 +175,11 @@ class PodsData { */ public $filters = array(); + /** + * @var array + */ + public $params = array(); + /** * Holds Traversal information about Pods * @@ -228,19 +211,29 @@ class PodsData { /** * Singleton handling for a basic pods_data() request * - * @param string $pod Pod name. - * @param integer $id Pod Item ID. - * @param bool $strict If true throws an error if a pod is not found. + * @param string|null $pod Pod name. + * @param int|string $id Pod Item ID. + * @param bool $strict If true throws an error if a pod is not found. + * + * @return PodsData|false * - * @return \PodsData + * @throws Exception * * @since 2.3.5 */ - public static function init( $pod = null, $id = 0, $strict = true ) { + public static function init( $pod = null, $id = null, $strict = true ) { + + if ( ! in_array( $pod, array( null, false ), true ) || ! in_array( $id, array( null, 0 ), true ) ) { + $object = new PodsData( $pod, $id ); + + if ( empty( $object->pod_data ) && true === $strict ) { + return pods_error( 'Pod not found', $object ); + } - if ( ( true !== $pod && null !== $pod ) || 0 != $id ) { - return new PodsData( $pod, $id, $strict ); - } elseif ( ! is_object( self::$instance ) ) { + return $object; + } + + if ( ! is_object( self::$instance ) ) { self::$instance = new PodsData(); } else { $vars = get_class_vars( __CLASS__ ); @@ -260,93 +253,83 @@ public static function init( $pod = null, $id = 0, $strict = true ) { /** * Data Abstraction Class for Pods * - * @param string $pod Pod name. - * @param integer $id Pod Item ID. - * @param bool $strict If true throws an error if a pod is not found. - * - * @return \PodsData + * @param string|null $pod Pod name. + * @param int|string $id Pod Item ID. * * @license http://www.gnu.org/licenses/gpl-2.0.html * @since 2.0.0 */ - public function __construct( $pod = null, $id = 0, $strict = true ) { + public function __construct( $pod = null, $id = 0 ) { global $wpdb; - if ( is_object( $pod ) && 'PodsAPI' === get_class( $pod ) ) { - $this->api = $pod; - $pod = $this->api->pod; - } else { - $this->api = pods_api( $pod ); - } - + $this->api = pods_api(); $this->api->display_errors =& self::$display_errors; - if ( ! empty( $pod ) ) { - $this->pod_data =& $this->api->pod_data; - - if ( false === $this->pod_data ) { - if ( true === $strict ) { - return pods_error( __( 'Pod not found', 'pods' ), $this ); - } else { - return $this; - } - } - - $this->pod_id = $this->pod_data['id']; - $this->pod = $this->pod_data['name']; - $this->fields = $this->pod_data['fields']; - - if ( isset( $this->pod_data['options']['detail_url'] ) ) { - $this->detail_page = $this->pod_data['options']['detail_url']; - } - - if ( isset( $this->pod_data['select'] ) ) { - $this->select = $this->pod_data['select']; - } - - if ( isset( $this->pod_data['table'] ) ) { - $this->table = $this->pod_data['table']; - } + if ( empty( $pod ) ) { + return; + } - if ( isset( $this->pod_data['join'] ) ) { - $this->join = $this->pod_data['join']; - } + if ( $pod instanceof Pod ) { + $this->pod_data = $pod; + } elseif ( $pod instanceof Pods ) { + $this->pod_data = $pod->pod_data; + } else { + $this->pod_data = $this->api->load_pod( [ + 'name' => $pod, + 'auto_setup' => true, + ], false ); + } - if ( isset( $this->pod_data['field_id'] ) ) { - $this->field_id = $this->pod_data['field_id']; - } + // Set up page variable. + if ( pods_strict( false ) ) { + $this->page = 1; + $this->pagination = false; + $this->search = false; + } else { + // Get the page variable. + $this->page = pods_v( $this->page_var, 'get', 1, true ); - if ( isset( $this->pod_data['field_index'] ) ) { - $this->field_index = $this->pod_data['field_index']; + if ( ! empty( $this->page ) ) { + $this->page = max( 1, pods_absint( $this->page ) ); } + } - if ( isset( $this->pod_data['field_slug'] ) ) { - $this->field_slug = $this->pod_data['field_slug']; + // Set default pagination handling to on/off. + if ( defined( 'PODS_GLOBAL_POD_PAGINATION' ) ) { + if ( ! PODS_GLOBAL_POD_PAGINATION ) { + $this->page = 1; + $this->pagination = false; + } else { + $this->pagination = true; } + } - if ( isset( $this->pod_data['where'] ) ) { - $this->where = $this->pod_data['where']; + // Set default search to on/off. + if ( defined( 'PODS_GLOBAL_POD_SEARCH' ) ) { + if ( PODS_GLOBAL_POD_SEARCH ) { + $this->search = true; + } else { + $this->search = false; } + } - if ( isset( $this->pod_data['where_default'] ) ) { - $this->where_default = $this->pod_data['where_default']; - } + // Set default search mode. + $allowed_search_modes = array( 'int', 'text', 'text_like' ); - if ( isset( $this->pod_data['orderby'] ) ) { - $this->orderby = $this->pod_data['orderby']; - } + if ( defined( 'PODS_GLOBAL_POD_SEARCH_MODE' ) && in_array( PODS_GLOBAL_POD_SEARCH_MODE, $allowed_search_modes, true ) ) { + $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE; + } - if ( 'settings' === $this->pod_data['type'] ) { - $this->id = $this->pod_data['id']; + if ( $this->pod_data && 'settings' === $this->pod_data['type'] ) { + $this->id = $this->pod_data['id']; - $this->fetch( $this->id ); - } elseif ( null !== $id && ! is_array( $id ) && ! is_object( $id ) ) { - $this->id = $id; + $this->fetch( $this->id ); + } elseif ( null !== $id && ! is_array( $id ) && ! is_object( $id ) ) { + $this->id = $id; - $this->fetch( $this->id ); - } - }//end if + $this->fetch( $this->id ); + } } /** @@ -356,83 +339,61 @@ public function __construct( $pod = null, $id = 0, $strict = true ) { * @param string $object */ public function table( $table, $object = '' ) { - global $wpdb; - if ( ! is_array( $table ) ) { + if ( is_string( $table ) ) { $object_type = ''; - if ( $wpdb->users === $table ) { - $object_type = 'user'; - } elseif ( $wpdb->posts === $table ) { + if ( $wpdb->posts === $table ) { $object_type = 'post_type'; } elseif ( $wpdb->terms === $table ) { $object_type = 'taxonomy'; + } elseif ( $wpdb->users === $table ) { + $object_type = 'user'; + } elseif ( $wpdb->comments === $table ) { + $object_type = 'comment'; } elseif ( $wpdb->options === $table ) { $object_type = 'settings'; } - } - - if ( ! empty( $object_type ) ) { - $table = $this->api->get_table_info( $object_type, $object ); - } - - if ( ! empty( $table ) && is_array( $table ) ) { - $table['id'] = pods_v( 'id', $table['pod'], 0, true ); - $table['name'] = pods_v( 'name', $table['pod'], $table['object_type'], true ); - $table['type'] = pods_v( 'type', $table['pod'], $table['object_type'], true ); - - $default_storage = 'meta'; - - if ( 'taxonomy' === $table['type'] && ! function_exists( 'get_term_meta' ) ) { - $default_storage = 'none'; - } - - $table['storage'] = pods_v( 'storage', $table['pod'], $default_storage, true ); - $table['fields'] = pods_v( 'fields', $table['pod'], array() ); - $table['object_fields'] = pods_v( 'object_fields', $table['pod'], $this->api->get_wp_object_fields( $table['object_type'] ), true ); - - $this->pod_data = $table; - $this->pod_id = $this->pod_data['id']; - $this->pod = $this->pod_data['name']; - $this->fields = $this->pod_data['fields']; - - if ( isset( $this->pod_data['select'] ) ) { - $this->select = $this->pod_data['select']; - } - - if ( isset( $this->pod_data['table'] ) ) { - $this->table = $this->pod_data['table']; - } - - if ( isset( $this->pod_data['join'] ) ) { - $this->join = $this->pod_data['join']; - } - if ( isset( $this->pod_data['field_id'] ) ) { - $this->field_id = $this->pod_data['field_id']; - } - - if ( isset( $this->pod_data['field_index'] ) ) { - $this->field_index = $this->pod_data['field_index']; + if ( ! empty( $object_type ) ) { + $table = $this->api->get_table_info( $object_type, $object ); } + } - if ( isset( $this->pod_data['field_slug'] ) ) { - $this->field_slug = $this->pod_data['field_slug']; - } + // Check if we received a pod object itself. + if ( $table instanceof Pod ) { + $table = [ + 'pod' => $table, + ]; + } elseif ( $table instanceof Pods ) { + $table = [ + 'pod' => $table->pod_data, + ]; + } - if ( isset( $this->pod_data['where'] ) ) { - $this->where = $this->pod_data['where']; - } + // No pod set. + if ( empty( $table['pod'] ) ) { + // No pod name to try to use. + if ( ! empty( $table['name'] ) ) { + $pod_data = $this->api->load_pod( [ + 'name' => $table['name'], + 'auto_setup' => true, + ] ); - if ( isset( $this->pod_data['where_default'] ) ) { - $this->where_default = $this->pod_data['where_default']; + // No pod data found. + if ( $pod_data ) { + $table['pod'] = $pod_data; + } } + } - if ( isset( $this->pod_data['orderby'] ) ) { - $this->orderby = $this->pod_data['orderby']; - } - }//end if + // Check for pod object. + if ( $table['pod'] instanceof Pod ) { + $this->pod_data = $table['pod']; + } else { + $this->table_info = $table; + } } /** @@ -715,7 +676,11 @@ public function select( $params ) { // Debug purposes. if ( ( 1 === (int) pods_v( 'pods_debug_sql', 'get', 0 ) || 1 === (int) pods_v( 'pods_debug_sql_all', 'get', 0 ) ) && pods_is_admin( array( 'pods' ) ) ) { - echo ''; + if ( function_exists( 'codecept_debug' ) ) { + pods_debug( $this->get_sql() ); + } else { + echo ''; + } } if ( empty( $this->sql ) ) { @@ -742,32 +707,17 @@ public function select( $params ) { */ $results = apply_filters( 'pods_data_select', $results, $params, $this ); - $this->data = $results; + $this->rows = $results; $this->row_number = - 1; $this->row = null; - // Fill in empty field data (if none provided). - if ( ( ! isset( $this->fields ) || empty( $this->fields ) ) && ! empty( $this->data ) ) { - $this->fields = array(); - $data = (array) @current( $this->data ); - - foreach ( $data as $data_key => $data_value ) { - $this->fields[ $data_key ] = array( 'label' => ucwords( str_replace( '-', ' ', str_replace( '_', ' ', $data_key ) ) ) ); - if ( isset( $this->pod_data['object_fields'][ $data_key ] ) ) { - $this->fields[ $data_key ] = $this->pod_data['object_fields'][ $data_key ]; - } - } - - $this->fields = PodsForm::fields_setup( $this->fields ); - } - $this->total_found_calculated = false; $this->total = 0; - if ( ! empty( $this->data ) ) { - $this->total = count( (array) $this->data ); + if ( ! empty( $this->rows ) ) { + $this->total = count( (array) $this->rows ); } /** @@ -784,7 +734,7 @@ public function select( $params ) { $this->calculate_totals(); } - return $this->data; + return $this->rows; } /** @@ -877,8 +827,10 @@ public function build( $params ) { $pod = false; - if ( is_array( $this->pod_data ) ) { + if ( $this->pod_data instanceof Pod ) { $pod = $this->pod_data; + } elseif ( $this->table_info ) { + $pod = $this->table_info; } // Validate. @@ -913,17 +865,45 @@ public function build( $params ) { $merge_object_fields = false; - if ( ( empty( $params->fields ) || ! is_array( $params->fields ) ) && ! empty( $pod ) && isset( $this->fields ) && ! empty( $this->fields ) ) { + if ( + $pod + && ( + empty( $params->fields ) + || ! is_array( $params->fields ) + ) + ) { $params->fields = $this->fields; + if ( null === $params->fields ) { + $params->fields = []; + } + $merge_object_fields = true; } - if ( ( empty( $params->object_fields ) || ! is_array( $params->object_fields ) ) && ! empty( $pod ) && isset( $pod['object_fields'] ) && ! empty( $pod['object_fields'] ) ) { - $params->object_fields = $pod['object_fields']; + if ( + $pod + && ( + empty( $params->object_fields ) + || ! is_array( $params->object_fields ) + ) + ) { + $params->object_fields = $this->object_fields; + + if ( null === $params->object_fields ) { + $params->object_fields = []; + } if ( $merge_object_fields ) { - $params->fields = array_merge( $params->object_fields, $params->fields ); + if ( $pod instanceof Pod ) { + $params->fields = $pod->get_all_fields(); + } elseif ( $params->object_fields ) { + if ( $params->fields ) { + $params->fields = array_merge( $params->fields, $params->object_fields ); + } else { + $params->fields = $params->object_fields; + } + } } } @@ -941,7 +921,7 @@ public function build( $params ) { $params->id = $this->field_id; } - if ( empty( $params->table ) && ! empty( $pod ) && isset( $this->table ) && ! empty( $this->table ) ) { + if ( $pod && empty( $params->table ) ) { $params->table = $this->table; } @@ -949,23 +929,30 @@ public function build( $params ) { $params->pod_table_prefix = 't'; } - if ( ! empty( $pod ) && ! in_array( - $pod['type'], array( - 'pod', - 'table', - ), true - ) && 'table' === $pod['storage'] ) { + if ( + 'table' === $this->storage + && ! in_array( $this->type, [ + 'pod', + 'table', + ], true ) + ) { $params->pod_table_prefix = 'd'; } $params->meta_fields = false; - if ( ! empty( $pod ) && ! in_array( - $pod['type'], array( + $is_pod_meta_storage = 'meta' === $this->storage; + + if ( + ( + $is_pod_meta_storage + || 'none' === $this->storage + ) + && ! in_array( $this->type, [ 'pod', 'table', - ), true - ) && ( 'meta' === $pod['storage'] || ( 'none' === $pod['storage'] && function_exists( 'get_term_meta' ) ) ) ) { + ], true ) + ) { $params->meta_fields = true; } @@ -1029,8 +1016,7 @@ public function build( $params ) { } if ( ! empty( $params->orderby ) ) { - if ( ! empty( $pod ) && 'post_type' === $pod['type'] && 'meta' === $pod['storage'] && is_array( $params->orderby ) ) { - + if ( $is_pod_meta_storage && is_array( $params->orderby ) ) { foreach ( $params->orderby as $i => $orderby ) { if ( strpos( $orderby, '.meta_value_num' ) ) { $params->orderby[ $i ] = 'CAST(' . str_replace( '.meta_value_num', '.meta_value', $orderby ) . ' AS DECIMAL)'; @@ -1126,118 +1112,136 @@ public function build( $params ) { // Search. if ( ! empty( $params->search ) && ! empty( $params->fields ) ) { if ( false !== $params->search_query && 0 < strlen( $params->search_query ) ) { - $where = array(); - $having = array(); + $where = []; + $having = []; + $fields_to_search = []; + + $excluded_field_types_from_search = [ + 'date', + 'time', + 'datetime', + 'number', + 'decimal', + 'currency', + 'phone', + 'password', + 'boolean', + 'comment', + 'taxonomy', + ]; if ( false !== $params->search_across ) { - foreach ( $params->fields as $key => $field ) { - if ( is_array( $field ) ) { - $attributes = $field; - $field = pods_v( 'name', $field, $key, true ); - } else { - $attributes = array( - 'type' => '', - 'options' => array(), - ); - } + // Search all fields. + $fields_to_search = $params->fields; + } elseif ( ! empty( $params->index ) ) { + $index_field = null; - if ( isset( $attributes['options']['search'] ) && ! $attributes['options']['search'] ) { - continue; - } + // Search just the index field if we can find it. + if ( isset( $params->fields[ $params->index ] ) ) { + $index_field = $params->fields[ $params->index ]; + } elseif ( isset( $params->object_fields[ $params->index ] ) ) { + $index_field = $params->object_fields[ $params->index ]; + } - if ( in_array( - $attributes['type'], array( - 'date', - 'time', - 'datetime', - 'number', - 'decimal', - 'currency', - 'phone', - 'password', - 'boolean', - 'comment', - 'taxonomy', - ), true - ) ) { - continue; - } + if ( $index_field ) { + $fields_to_search = [ + $params->index => $index_field, + ]; + } + } - $fieldfield = '`' . $field . '`'; + foreach ( $fields_to_search as $key => $field ) { + $is_field_object = $field instanceof Field; - $is_object_field = isset( $params->object_fields[ $field ] ); + if ( is_array( $field ) || $is_field_object ) { + $attributes = $field; + $field = pods_v( 'name', $field, $key, true ); + } else { + $attributes = [ + 'type' => '', + 'options' => [], + ]; + } - if ( in_array( $attributes['type'], $pick_field_types, true ) && ! in_array( pods_v( 'pick_object', $attributes ), $simple_tableless_objects, true ) ) { - if ( false === $params->search_across_picks ) { - continue; - } else { - if ( empty( $attributes['table_info'] ) ) { - $attributes['table_info'] = $this->api->get_table_info( pods_v( 'pick_object', $attributes ), pods_v( 'pick_val', $attributes ) ); - } + if ( isset( $attributes['search'] ) && ! $attributes['search'] ) { + continue; + } - if ( empty( $attributes['table_info']['field_index'] ) ) { - continue; - } + // Exclude certain field types from search. + if ( in_array( $attributes['type'], $excluded_field_types_from_search, true ) ) { + continue; + } - $fieldfield = $fieldfield . '.`' . $attributes['table_info']['field_index'] . '`'; - } - } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) { - if ( false === $params->search_across_files ) { - continue; - } else { - $fieldfield = $fieldfield . '.`post_title`'; - } - } elseif ( isset( $params->fields[ $field ] ) && ! $is_object_field ) { - if ( $params->meta_fields ) { - $fieldfield = $fieldfield . '.`meta_value`'; - } else { - $fieldfield = '`' . $params->pod_table_prefix . '`.' . $fieldfield; - } - } elseif ( ( empty( $params->object_fields ) || ! $is_object_field ) && 'meta' === $pod['storage'] ) { - $fieldfield = $fieldfield . '.`meta_value`'; - } else { - $fieldfield = '`t`.' . $fieldfield; - }//end if + $db_field_name = '`' . $field . '`'; - if ( isset( $this->aliases[ $field ] ) ) { - $fieldfield = '`' . $this->aliases[ $field ] . '`'; - } + $is_object_field = ( + isset( $params->object_fields[ $field ] ) + || $attributes instanceof Object_Field + ); + $is_custom_field = ( + ! $is_object_field + && ! isset( $params->fields[ $field ] ) + ); + + $pick_object = pods_v( $attributes['type'] . '_object', $attributes ); + $pick_val = pods_v( $attributes['type'] . '_val', $attributes ); - if ( ! empty( $attributes['real_name'] ) ) { - $fieldfield = $attributes['real_name']; + if ( in_array( $attributes['type'], $pick_field_types, true ) && ! in_array( $pick_object, $simple_tableless_objects, true ) ) { + // Search relationship fields. + if ( false !== $params->search_across && false === $params->search_across_picks ) { + // Skip if we are searching but not searching across relationship fields. + continue; + } elseif ( empty( $attributes['table_info'] ) ) { + $attributes['table_info'] = $this->api->get_table_info( $pick_object, $pick_val ); } - if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) { - $having[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'"; - } else { - $where[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'"; + // Check if we have index column information about the related table. + if ( empty( $attributes['table_info']['field_index'] ) ) { + continue; } - }//end foreach - } elseif ( ! empty( $params->index ) ) { - $attributes = array(); - $fieldfield = '`t`.`' . $params->index . '`'; + $db_field_name .= '.`' . $attributes['table_info']['field_index'] . '`'; + } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) { + // Search file fields. + if ( false !== $params->search_across && false === $params->search_across_files ) { + // Skip if we are searching but not searching across file fields. + continue; + } - if ( isset( $params->fields[ $params->index ] ) ) { - if ( $params->meta_fields && ! isset( $params->object_fields[ $params->index ] ) ) { - $fieldfield = '`' . $params->index . '`.`meta_value`'; + $db_field_name .= '.`post_title`'; + } elseif ( $is_custom_field ) { + // Search custom fields (they are not a defined field or an object field). + if ( $params->meta_fields ) { + // If meta is enabled, this must be a meta field. + $db_field_name .= '.`meta_value`'; } else { - $fieldfield = '`' . $params->pod_table_prefix . '`.`' . $params->index . '`'; + // Maybe this is just a field we don't know about on the table. + $db_field_name = '`' . $params->pod_table_prefix . '`.' . $db_field_name; } - } elseif ( ! empty( $params->object_fields ) && ! isset( $params->object_fields[ $params->index ] ) && 'meta' === $pod['storage'] ) { - $fieldfield = '`' . $params->index . '`.`meta_value`'; + } elseif ( ! $is_object_field && $is_pod_meta_storage ) { + // Search meta fields. + $db_field_name .= '.`meta_value`'; + } else { + // Search object fields. + $db_field_name = '`t`.' . $db_field_name; + }//end if + + if ( isset( $this->aliases[ $field ] ) ) { + $db_field_name = '`' . $this->aliases[ $field ] . '`'; } - if ( isset( $attributes['real_name'] ) && false !== $attributes['real_name'] && ! empty( $attributes['real_name'] ) ) { - $fieldfield = $attributes['real_name']; + if ( ! empty( $attributes['real_name'] ) ) { + $db_field_name = $attributes['real_name']; } + $filter_clause = "{$db_field_name} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'"; + if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) { - $having[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'"; + $having[] = $filter_clause; } else { - $where[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'"; + $where[] = $filter_clause; } - }//end if + }//end foreach if ( ! empty( $where ) ) { $params->where[] = '( ' . implode( ' OR ', $where ) . ' )'; @@ -1284,13 +1288,13 @@ public function build( $params ) { $filterfield = $filterfield . '.`term_id`'; } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) { $filterfield = $filterfield . '.`post_title`'; - } elseif ( isset( $params->fields[ $field ] ) ) { - if ( $params->meta_fields && 'meta' === $pod['storage'] ) { + } elseif ( isset( $params->fields[ $field ] ) && $params->fields[ $field ] instanceof Object_Field ) { + if ( $params->meta_fields && $is_pod_meta_storage ) { $filterfield = $filterfield . '.`meta_value`'; } else { $filterfield = '`' . $params->pod_table_prefix . '`.' . $filterfield; } - } elseif ( ! empty( $params->object_fields ) && ! isset( $params->object_fields[ $field ] ) && 'meta' === $pod['storage'] ) { + } elseif ( ! isset( $params->fields[ $field ] ) && $is_pod_meta_storage ) { $filterfield = $filterfield . '.`meta_value`'; } else { $filterfield = '`t`.' . $filterfield; @@ -1332,9 +1336,9 @@ public function build( $params ) { $filterfield = '`' . $field . '`.`' . $attributes['table_info']['field_id'] . '`'; if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) { - $having[] = "{$filterfield} = " . $filter_v; + $having[] = "{$filterfield} = {$filter_v}"; } else { - $where[] = "{$filterfield} = " . $filter_v; + $where[] = "{$filterfield} = {$filter_v}"; } }//end if }//end foreach @@ -1407,7 +1411,7 @@ public function build( $params ) { }//end if // Traverse the Rabbit Hole. - if ( ! empty( $this->pod ) ) { + if ( $this->pod_data || $this->table_info ) { $haystack = implode( ' ', (array) $params->select ) . ' ' . implode( ' ', (array) $params->where ) . ' ' . implode( ' ', (array) $params->groupby ) . ' ' . implode( ' ', (array) $params->having ) . ' ' . implode( ' ', (array) $params->orderby ); $haystack = preg_replace( '/\s/', ' ', $haystack ); $haystack = preg_replace( '/\w\(/', ' ', $haystack ); @@ -1975,35 +1979,28 @@ public function fetch( $row = null, $explicit_set = true ) { $this->row = false; - if ( isset( $this->data[ $this->row_number ] ) ) { - $this->row = get_object_vars( $this->data[ $this->row_number ] ); + if ( isset( $this->rows[ $this->row_number ] ) ) { + $this->row = $this->rows[ $this->row_number ]; + + if ( is_object( $this->row ) ) { + $this->row = get_object_vars( $this->row ); + } $current_row_id = false; - if ( in_array( - $this->pod_data['type'], array( - 'post_type', - 'media', - ), true - ) ) { - $current_row_id = pods_v( 'ID', $this->row ); - } elseif ( 'taxonomy' === $this->pod_data['type'] ) { - $current_row_id = pods_v( 'term_id', $this->row ); - } elseif ( 'user' === $this->pod_data['type'] ) { - $current_row_id = pods_v( 'ID', $this->row ); - } elseif ( 'comment' === $this->pod_data['type'] ) { - $current_row_id = pods_v( 'comment_ID', $this->row ); - } elseif ( 'settings' === $this->pod_data['type'] ) { + if ( $this->pod_data && 'settings' === $this->pod_data['type'] ) { $current_row_id = $this->pod_data['id']; + } else { + $current_row_id = pods_v( $this->field_id, $this->row ); } - if ( 0 < $current_row_id ) { + if ( ! in_array( $current_row_id, [ '', '0', 0, null, false ], true ) ) { $row = $current_row_id; } }//end if }//end if - if ( null !== $row || 'settings' === $this->pod_data['type'] ) { + if ( null !== $row || ( $this->pod_data && 'settings' === $this->pod_data['type'] ) ) { if ( $explicit_set ) { $this->row_number = - 1; } @@ -2011,7 +2008,7 @@ public function fetch( $row = null, $explicit_set = true ) { $mode = 'id'; $id = pods_absint( $row ); - if ( ! is_numeric( $row ) || 0 === strpos( $row, '0' ) || $row != preg_replace( '/[^0-9]/', '', $row ) ) { + if ( ! is_numeric( $row ) || 0 === strpos( $row, '0' ) || (string) $row !== (string) preg_replace( '/[^0-9]/', '', $row ) ) { if ( $this->id && is_numeric( $this->id ) ) { $id = $this->id; } else { @@ -2024,8 +2021,11 @@ public function fetch( $row = null, $explicit_set = true ) { if ( ! empty( $this->pod ) ) { $row = pods_cache_get( $id, 'pods_items_' . $this->pod ); - if ( false !== $row ) { + + if ( is_array( $row ) ) { $already_cached = true; + } else { + $row = false; } } @@ -2034,56 +2034,60 @@ public function fetch( $row = null, $explicit_set = true ) { $old_row = $this->row; - if ( false !== $row && is_array( $row ) ) { + $pod_type = $this->type; + + if ( $already_cached ) { $this->row = $row; } elseif ( in_array( - $this->pod_data['type'], array( + $pod_type, array( 'post_type', 'media', ), true ) ) { - if ( 'post_type' === $this->pod_data['type'] ) { - if ( empty( $this->pod_data['object'] ) ) { - $post_type = $this->pod_data['name']; - } else { + if ( 'post_type' === $pod_type ) { + $post_type = $this->pod; + + if ( $this->pod_data && ! empty( $this->pod_data['object'] ) ) { $post_type = $this->pod_data['object']; } } else { $post_type = 'attachment'; } + $this->row = []; + if ( 'id' === $mode ) { $this->row = get_post( $id, ARRAY_A ); - if ( is_array( $this->row ) && $this->row['post_type'] != $post_type ) { + if ( is_array( $this->row ) && $this->row['post_type'] !== $post_type ) { $this->row = false; } } else { - $args = array( - 'post_type' => $post_type, - 'name' => $id, - 'numberposts' => 5, - ); + $args = [ + 'post_type' => $post_type, + 'name' => $id, + 'posts_per_page' => 5, + ]; $find = get_posts( $args ); if ( ! empty( $find ) ) { - $this->row = get_object_vars( $find[0] ); + $this->row = get_object_vars( reset( $find ) ); } } - if ( is_wp_error( $this->row ) || empty( $this->row ) ) { + if ( empty( $this->row ) || is_wp_error( $this->row ) ) { $this->row = false; } else { $current_row_id = $this->row['ID']; } $get_table_data = true; - } elseif ( 'taxonomy' === $this->pod_data['type'] ) { - $taxonomy = $this->pod_data['object']; + } elseif ( 'taxonomy' === $pod_type ) { + $taxonomy = $this->pod; - if ( empty( $taxonomy ) ) { - $taxonomy = $this->pod_data['name']; + if ( $this->pod_data && ! empty( $this->pod_data['object'] ) ) { + $taxonomy = $this->pod_data['object']; } // Taxonomies are registered during init, so they aren't available before then. @@ -2112,6 +2116,8 @@ public function fetch( $row = null, $explicit_set = true ) { $_term = apply_filters( "get_$taxonomy", $_term, $taxonomy ); $_term = sanitize_term( $_term, $taxonomy, $filter ); + $this->row = []; + if ( is_object( $_term ) ) { $this->row = get_object_vars( $_term ); } @@ -2121,21 +2127,21 @@ public function fetch( $row = null, $explicit_set = true ) { $this->row = get_term_by( 'slug', $id, $taxonomy, ARRAY_A ); }//end if - if ( is_wp_error( $this->row ) || empty( $this->row ) ) { + if ( empty( $this->row ) || is_wp_error( $this->row ) ) { $this->row = false; } else { $current_row_id = $this->row['term_id']; } $get_table_data = true; - } elseif ( 'user' === $this->pod_data['type'] ) { + } elseif ( 'user' === $pod_type ) { if ( 'id' === $mode ) { $this->row = get_userdata( $id ); } else { $this->row = get_user_by( 'slug', $id ); } - if ( is_wp_error( $this->row ) || empty( $this->row ) ) { + if ( empty( $this->row ) || is_wp_error( $this->row ) ) { $this->row = false; } else { // Get other vars. @@ -2156,21 +2162,21 @@ public function fetch( $row = null, $explicit_set = true ) { } $get_table_data = true; - } elseif ( 'comment' === $this->pod_data['type'] ) { + } elseif ( 'comment' === $pod_type ) { $this->row = get_comment( $id, ARRAY_A ); // No slug handling here. - if ( is_wp_error( $this->row ) || empty( $this->row ) ) { + if ( empty( $this->row ) || is_wp_error( $this->row ) ) { $this->row = false; } else { $current_row_id = $this->row['comment_ID']; } $get_table_data = true; - } elseif ( 'settings' === $this->pod_data['type'] ) { - $this->row = array(); + } elseif ( 'settings' === $pod_type ) { + $this->row = []; - if ( empty( $this->fields ) ) { + if ( empty( $this->fields ) || ! $this->pod_data ) { $this->row = false; } else { foreach ( $this->fields as $field ) { @@ -2198,7 +2204,9 @@ public function fetch( $row = null, $explicit_set = true ) { $params['where'] = "`t`.`{$this->field_slug}` = '{$id}'"; } - $this->row = pods_data()->select( $params ); + $new_data = new PodsData(); + + $this->row = $new_data->select( $params ); if ( empty( $this->row ) ) { $this->row = false; @@ -2212,7 +2220,7 @@ public function fetch( $row = null, $explicit_set = true ) { $this->row = array_merge( $old_row, $this->row ); } - if ( 'table' === $this->pod_data['storage'] && false !== $get_table_data && is_numeric( $current_row_id ) ) { + if ( false !== $get_table_data && is_numeric( $current_row_id ) && $this->pod_data && 'table' === $this->pod_data['storage'] ) { $params = array( 'table' => self::get_pods_prefix(), 'where' => "`t`.`id` = {$current_row_id}", @@ -2223,13 +2231,17 @@ public function fetch( $row = null, $explicit_set = true ) { 'strict' => true, ); - if ( empty( $this->pod_data['object'] ) ) { - $params['table'] .= $this->pod_data['name']; - } else { - $params['table'] .= $this->pod_data['object']; + $table_name = $this->pod; + + if ( $this->pod_data && ! empty( $this->pod_data['object'] ) ) { + $table_name = $this->pod_data['object']; } - $row = pods_data()->select( $params ); + $params['table'] .= $table_name; + + $new_data = new PodsData(); + + $row = $new_data->select( $params ); if ( ! empty( $row ) ) { $current_row = (array) $row; @@ -2244,12 +2256,17 @@ public function fetch( $row = null, $explicit_set = true ) { }//end if if ( ! empty( $this->pod ) && ! $already_cached ) { - pods_cache_set( $id, $this->row, 'pods_items_' . $this->pod, 0 ); + pods_cache_set( $id, $this->row, 'pods_items_' . $this->pod, WEEK_IN_SECONDS ); } }//end if $this->row = apply_filters( 'pods_data_fetch', $this->row, $id, $this->row_number, $this ); + // Set the ID if the row was found. + if ( $explicit_set && $this->row ) { + $this->id = $id; + } + return $this->row; } @@ -2268,8 +2285,12 @@ public function reset( $row = null ) { $this->row = false; - if ( isset( $this->data[ $row ] ) ) { - $this->row = get_object_vars( $this->data[ $row ] ); + if ( isset( $this->rows[ $row ] ) ) { + $this->row = $this->rows[ $row ]; + + if ( is_object( $this->row ) ) { + $this->row = get_object_vars( $this->row ); + } } if ( empty( $row ) ) { @@ -2511,9 +2532,9 @@ public static function prepare( $sql, $data ) { /** * Get the string to use in a query for WHERE/HAVING, uses WP_Query meta_query arguments * - * @param array $fields Array of field matches for querying. - * @param array $pod Related Pod. - * @param object $params Parameters passed from select(). + * @param array $fields Array of field matches for querying. + * @param array|Pod $pod Related Pod. + * @param object $params Parameters passed from select(). * * @return string|null Query string for WHERE/HAVING * @@ -2578,7 +2599,7 @@ public static function query_fields( $fields, $pod = null, &$params = null ) { if ( ! empty( $query_fields ) ) { // If post_status not sent, detect it. - if ( ! empty( $pod ) && 'post_type' === $pod['type'] && 1 === $current_level && ! $params->where_defaulted && ! empty( $params->where_default ) ) { + if ( $pod && 'post_type' === $pod['type'] && 1 === $current_level && ! $params->where_defaulted && ! empty( $params->where_default ) ) { $post_status_found = false; if ( ! $params->query_field_syntax ) { @@ -2587,20 +2608,24 @@ public static function query_fields( $fields, $pod = null, &$params = null ) { $haystack = preg_replace( '/\w\(/', ' ', $haystack ); $haystack = str_replace( array( '(', ')', ' ', '\\\'', '\\"' ), ' ', $haystack ); + // Find xyz.some_field and `xyz`.`some_field` variations. preg_match_all( '/`?[\w\-]+`?(?:\\.`?[\w\-]+`?)+(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found, PREG_PATTERN_ORDER ); - $found = (array) @current( $found ); + // Find `some_field` variations but leave out some_field without backticks. + preg_match_all( '/(?:`?[\w\-]+`?)+(?!\.)(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found2, PREG_PATTERN_ORDER ); - foreach ( $found as $value ) { - $value = str_replace( '`', '', $value ); - $value = explode( '.', $value ); + $found = (array) @current( $found ); + $found = array_merge( $found, (array) @current( $found2 ) ); + $found = array_unique( $found ); - if ( ( 'post_status' === $value[0] && 1 === count( $value ) ) || ( 2 === count( $value ) && 't' === $value[0] && 'post_status' === $value[1] ) ) { - $post_status_found = true; + $post_status_patterns = [ + '`t`.`post_status`', + 't.post_status', + '`post_status`', + 'post_status', + ]; - break; - } - } + $post_status_found = 0 < count( array_intersect( $found, $post_status_patterns ) ); } elseif ( ! empty( $params->query_fields ) && in_array( 'post_status', $params->query_fields, true ) ) { $post_status_found = true; }//end if @@ -2632,7 +2657,7 @@ public static function query_fields( $fields, $pod = null, &$params = null ) { * * @param string|int $field Field name or array index. * @param array|string $q Query array (meta_query) or string for matching. - * @param array $pod Related Pod. + * @param array|Pod $pod Related Pod. * @param object $params Parameters passed from select(). * * @return string|null Query field string @@ -2713,25 +2738,37 @@ public static function query_field( $field, $q, $pod = null, &$params = null ) { $field_type = 'CHAR'; } + $is_pod_meta_storage = 'meta' === $pod['storage']; + // Alias / Casting. if ( empty( $field_cast ) ) { // Setup field casting from field name. if ( false === strpos( $field_name, '`' ) && false === strpos( $field_name, '(' ) && false === strpos( $field_name, ' ' ) ) { // Handle field naming if Pod-based. - if ( ! empty( $pod ) && false === strpos( $field_name, '.' ) ) { + if ( $pod && false === strpos( $field_name, '.' ) ) { $field_cast = ''; + $the_field = null; + + if ( $pod instanceof Pod ) { + $the_field = $pod->get_field( $field_name ); + } elseif ( isset( $pod[ $field_name ] ) ) { + $the_field = $pod[ $field_name ]; + } + $tableless_field_types = PodsForm::tableless_field_types(); - if ( isset( $pod['fields'][ $field_name ] ) && in_array( $pod['fields'][ $field_name ]['type'], $tableless_field_types, true ) ) { - if ( in_array( $pod['fields'][ $field_name ]['pick_object'], $simple_tableless_objects, true ) ) { - if ( 'meta' === $pod['storage'] ) { + if ( $the_field && in_array( $the_field['type'], $tableless_field_types, true ) ) { + $related_object_type = $the_field->get_related_object_type(); + + if ( in_array( $related_object_type, $simple_tableless_objects, true ) ) { + if ( $is_pod_meta_storage ) { $field_cast = "`{$field_name}`.`meta_value`"; } else { $field_cast = "`t`.`{$field_name}`"; } } else { - $table = pods_api()->get_table_info( $pod['fields'][ $field_name ]['pick_object'], $pod['fields'][ $field_name ]['pick_val'] ); + $table = $the_field->get_table_info(); if ( ! empty( $table ) ) { $field_cast = "`{$field_name}`.`" . $table['field_index'] . '`'; @@ -2740,39 +2777,29 @@ public static function query_field( $field, $q, $pod = null, &$params = null ) { } if ( empty( $field_cast ) ) { - if ( ! in_array( - $pod['type'], array( - 'pod', - 'table', - ), true - ) ) { - if ( isset( $pod['object_fields'][ $field_name ] ) ) { - $field_cast = "`t`.`{$field_name}`"; - } elseif ( isset( $pod['fields'][ $field_name ] ) ) { - if ( 'meta' === $pod['storage'] ) { + if ( $the_field ) { + if ( ! in_array( + $pod['type'], array( + 'pod', + 'table', + ), true + ) ) { + if ( $the_field instanceof Object_Field ) { + $field_cast = "`t`.`{$field_name}`"; + } elseif ( $is_pod_meta_storage ) { $field_cast = "`{$field_name}`.`meta_value`"; } else { $field_cast = "`d`.`{$field_name}`"; } - } else { - foreach ( $pod['object_fields'] as $object_field => $object_field_opt ) { - if ( $object_field === $field_name || in_array( $field_name, $object_field_opt['alias'], true ) ) { - $field_cast = "`t`.`{$object_field}`"; - - break; - } - } - } - } elseif ( isset( $pod['fields'][ $field_name ] ) ) { - if ( 'meta' === $pod['storage'] ) { + } elseif ( $is_pod_meta_storage ) { $field_cast = "`{$field_name}`.`meta_value`"; } else { $field_cast = "`t`.`{$field_name}`"; - } + }//end if }//end if if ( empty( $field_cast ) ) { - if ( 'meta' === $pod['storage'] ) { + if ( $is_pod_meta_storage ) { $field_cast = "`{$field_name}`.`meta_value`"; } else { $field_cast = "`t`.`{$field_name}`"; @@ -2918,74 +2945,77 @@ public static function query_field( $field, $q, $pod = null, &$params = null ) { ); // Make the query. - if ( in_array( - $field_compare, array( - '=', - '!=', - '>', - '>=', - '<', - '<=', - 'REGEXP', - 'NOT REGEXP', - 'RLIKE', - ), true - ) ) { + if ( in_array( $field_compare, [ + '=', + '!=', + '>', + '>=', + '<', + '<=', + 'REGEXP', + 'NOT REGEXP', + 'RLIKE', + ], true ) ) { if ( $field_sanitize ) { - $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ' . $field_sanitize_format, $field_value ); + $field_query = "{$field_cast} {$field_compare} {$field_sanitize_format}"; + $field_query = $wpdb->prepare( $field_query, $field_value ); } else { - $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value . '"'; + $field_query = "{$field_cast} {$field_compare} '{$field_value}'"; } - } elseif ( in_array( - $field_compare, array( - 'LIKE', - 'NOT LIKE', - ), true - ) ) { + } elseif ( in_array( $field_compare, [ + 'LIKE', + 'NOT LIKE', + ], true ) ) { if ( $field_sanitize ) { - $field_query = $field_cast . ' ' . $field_compare . ' "%' . pods_sanitize_like( $field_value ) . '%"'; + $field_query = "{$field_cast} {$field_compare} '%" . pods_sanitize_like( $field_value ) . "%'"; } else { - $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value . '"'; + $field_query = "{$field_cast} {$field_compare} '{$field_value}'"; } - } elseif ( in_array( - $field_compare, array( - 'IN', - 'NOT IN', - 'ALL', - ), true - ) ) { + } elseif ( in_array( $field_compare, [ + 'IN', + 'NOT IN', + 'ALL', + ], true ) ) { + $field_value = (array) $field_value; + if ( 'ALL' === $field_compare ) { $field_compare = 'IN'; - if ( ! empty( $pod ) ) { + if ( $pod ) { $params->having[] = 'COUNT( DISTINCT ' . $field_cast . ' ) = ' . count( $field_value ); - if ( empty( $params->groupby ) || ( ! in_array( '`t`.`' . $pod['field_id'] . '`', $params->groupby, true ) && ! in_array( 't.' . $pod['field_id'] . '', $params->groupby, true ) ) ) { - $params->groupby[] = '`t`.`' . $pod['field_id'] . '`'; + if ( + empty( $params->groupby ) + || ( + ! in_array( "`t`.`{$pod['field_id']}`", $params->groupby, true ) + && ! in_array( "t.{$pod['field_id']}", $params->groupby, true ) + ) + ) { + $params->groupby[] = "`t`.`{$pod['field_id']}`"; } } } if ( $field_sanitize ) { - $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ( ' . substr( str_repeat( ', ' . $field_sanitize_format, count( $field_value ) ), 1 ) . ' )', $field_value ); + $field_query = "{$field_cast} {$field_compare} ( " . substr( str_repeat( ', ' . $field_sanitize_format, count( $field_value ) ), 1 ) . " )"; + $field_query = $wpdb->prepare( $field_query, $field_value ); } else { - $field_query = $field_cast . ' ' . $field_compare . ' ( "' . implode( '", "', $field_value ) . '" )'; + $field_query = "{$field_cast} {$field_compare} ( '" . implode( "', '", $field_value ) . "' )"; } - } elseif ( in_array( - $field_compare, array( - 'BETWEEN', - 'NOT BETWEEN', - ), true - ) ) { + } elseif ( in_array( $field_compare, [ + 'BETWEEN', + 'NOT BETWEEN', + ], true ) ) { if ( $field_sanitize ) { - $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ' . $field_sanitize_format . ' AND ' . $field_sanitize_format, $field_value ); + $field_query = "{$field_cast} {$field_compare} {$field_sanitize_format} AND {$field_sanitize_format}"; + $field_query = $wpdb->prepare( $field_query, $field_value ); } else { - $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value[0] . '" AND "' . $field_value[1] . '"'; + $field_query = "{$field_cast} {$field_compare} '{$field_value[0]}' AND '{$field_value[1]}'"; } } elseif ( 'EXISTS' === $field_compare ) { - $field_query = $field_cast . ' IS NOT NULL'; + $field_query = "{$field_cast} IS NOT NULL"; } elseif ( 'NOT EXISTS' === $field_compare ) { - $field_query = $field_cast . ' IS NULL'; + $field_query = "{$field_cast} IS NULL"; }//end if $field_query = apply_filters( 'pods_data_field_query', $field_query, $q ); @@ -3041,35 +3071,28 @@ public function traverse_build( $fields = null, $params = null ) { * @since 2.0.0 */ public function traverse_recurse( $traverse_recurse ) { - global $wpdb; - $defaults = array( + $defaults = [ 'pod' => null, - 'fields' => array(), + 'fields' => [], 'joined' => 't', 'depth' => 0, 'joined_id' => 'id', 'joined_index' => 'id', 'params' => new stdClass(), - 'last_table_info' => array(), - ); + 'last_table_info' => [], + ]; $traverse_recurse = array_merge( $defaults, $traverse_recurse ); - $joins = array(); + $joins = []; if ( 0 === $traverse_recurse['depth'] && ! empty( $traverse_recurse['pod'] ) && ! empty( $traverse_recurse ['last_table_info'] ) && isset( $traverse_recurse ['last_table_info']['id'] ) ) { - $pod_data = $traverse_recurse ['last_table_info']; + $pod_data = $traverse_recurse['last_table_info']; } elseif ( empty( $traverse_recurse['pod'] ) ) { - if ( - ! empty( $traverse_recurse['params'] ) - && ! empty( $traverse_recurse['params']->table ) - && ( - ! $wpdb->prefix // Make sure there is a prefix. - || 0 === strpos( $traverse_recurse['params']->table, $wpdb->prefix ) - ) - ) { + if ( ! empty( $traverse_recurse['params'] ) && ! empty( $traverse_recurse['params']->table ) && ( ! $wpdb->prefix // Make sure there is a prefix. + || 0 === strpos( $traverse_recurse['params']->table, $wpdb->prefix ) ) ) { if ( $wpdb->posts === $traverse_recurse['params']->table ) { $traverse_recurse['pod'] = 'post_type'; } elseif ( $wpdb->terms === $traverse_recurse['params']->table ) { @@ -3082,43 +3105,42 @@ public function traverse_recurse( $traverse_recurse ) { return $joins; } - $pod_data = array(); + $pod_data = []; - if ( in_array( - $traverse_recurse['pod'], array( - 'user', - 'comment', - ), true - ) ) { - $pod = $this->api->load_pod( - array( - 'name' => $traverse_recurse['pod'], - 'table_info' => true, - ) - ); - - if ( ! empty( $pod ) && $pod['type'] === $pod ) { - $pod_data = $pod; + if ( in_array( $traverse_recurse['pod'], [ + 'user', + 'comment', + ], true ) ) { + $new_pod = $this->api->load_pod( [ + 'name' => $traverse_recurse['pod'], + 'auto_setup' => true, + ] ); + + if ( $new_pod && $new_pod['type'] === $traverse_recurse['pod'] ) { + $pod_data = $new_pod; } } if ( empty( $pod_data ) ) { + // @todo This logic is problematic with the new object based Pod configs. $default_storage = 'meta'; if ( 'taxonomy' === $traverse_recurse['pod'] && ! function_exists( 'get_term_meta' ) ) { $default_storage = 'none'; } - $pod_data = array( + $pod_data = [ 'id' => 0, 'name' => '_table_' . $traverse_recurse['pod'], 'type' => $traverse_recurse['pod'], 'storage' => $default_storage, - 'fields' => array(), - 'object_fields' => $this->api->get_wp_object_fields( $traverse_recurse['pod'] ), - ); + 'fields' => $this->api->get_wp_object_fields( $traverse_recurse['pod'] ), + 'object_fields' => [], + ]; - $pod_data = array_merge( $this->api->get_table_info( $traverse_recurse['pod'], '' ), $pod_data ); + $pod_data['object_fields'] = $pod_data['fields']; + + $pod_data = pods_config_merge_data( $this->api->get_table_info( $traverse_recurse['pod'], '' ), $pod_data ); } elseif ( 'taxonomy' === $pod_data['type'] && 'none' === $pod_data['storage'] && function_exists( 'get_term_meta' ) ) { $pod_data['storage'] = 'meta'; } @@ -3128,28 +3150,22 @@ public function traverse_recurse( $traverse_recurse ) { return $joins; }//end if } else { - $pod_data = $this->api->load_pod( - array( - 'name' => $traverse_recurse['pod'], - 'table_info' => true, - ), false - ); + $pod_data = $this->api->load_pod( [ + 'name' => $traverse_recurse['pod'], + 'auto_setup' => true, + ] ); if ( empty( $pod_data ) ) { return $joins; } }//end if - if ( isset( $pod_data['object_fields'] ) ) { - $pod_data['fields'] = array_merge( $pod_data['fields'], $pod_data['object_fields'] ); - } - $tableless_field_types = PodsForm::tableless_field_types(); $simple_tableless_objects = PodsForm::simple_tableless_objects(); $file_field_types = PodsForm::file_field_types(); if ( ! isset( $this->traversal[ $traverse_recurse['pod'] ] ) ) { - $this->traversal[ $traverse_recurse['pod'] ] = array(); + $this->traversal[ $traverse_recurse['pod'] ] = []; } if ( ( empty( $pod_data['meta_table'] ) || $pod_data['meta_table'] === $pod_data['table'] ) && ( empty( $traverse_recurse['fields'] ) || empty( $traverse_recurse['fields'][ $traverse_recurse['depth'] ] ) ) ) { @@ -3158,12 +3174,17 @@ public function traverse_recurse( $traverse_recurse ) { $field = $traverse_recurse['fields'][ $traverse_recurse['depth'] ]; - $ignore_aliases = array( - 'wpml_languages', - 'polylang_languages', - ); - - $ignore_aliases = apply_filters( 'pods_data_traverse_recurse_ignore_aliases', $ignore_aliases, $field, $traverse_recurse, $this ); + /** + * Prevent aliases from being used in traversals. + * + * @since 2.3.0 + * + * @param array $ignore_aliases Aliases to be ignored. + * @param array $field Field data. + * @param array $traverse_recurse Traverse params. + * @param \PodsData $pods_data PodsData instance. + */ + $ignore_aliases = apply_filters( 'pods_data_traverse_recurse_ignore_aliases', [], $field, $traverse_recurse, $this ); if ( in_array( $field, $ignore_aliases, true ) ) { return $joins; @@ -3182,69 +3203,82 @@ public function traverse_recurse( $traverse_recurse ) { $field_type = $traverse_recurse['last_table_info']['pod']['object_fields'][ $field ]['type']; } - $pod_data['fields'][ $field ] = array( + $pod_data['fields'][ $field ] = [ 'id' => 0, 'name' => $field, 'type' => $field_type, 'pick_object' => $traverse_recurse['last_table_info']['pod']['type'], 'pick_val' => $traverse_recurse['last_table_info']['pod']['name'], - ); + ]; $meta_data_table = true; }//end if + $the_field = null; + // Fallback to meta table if the pod type supports it. - if ( ! isset( $pod_data['fields'][ $field ] ) ) { - $last = end( $traverse_recurse['fields'] ); + $last = end( $traverse_recurse['fields'] ); - if ( 'post_type' === $pod_data['type'] && ! isset( $pod_data['object_fields'] ) ) { - $pod_data['object_fields'] = $this->api->get_wp_object_fields( 'post_type', $pod_data ); - } + if ( $pod_data instanceof Pod ) { + // Maybe get the field / object field from the pod. + $the_field = $pod_data->get_field( $field ); + } elseif ( isset( $pod_data['fields'][ $field ] ) ) { + $the_field = $pod_data['fields'][ $field ]; + } - if ( 'post_type' === $pod_data['type'] && isset( $pod_data['object_fields'][ $field ] ) && in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) { - $pod_data['fields'][ $field ] = $pod_data['object_fields'][ $field ]; - } elseif ( 'meta_value' === $last && in_array( - $pod_data['type'], array( + if ( ! $the_field ) { + if ( 'meta_value' === $last && in_array( $pod_data['type'], [ 'post_type', 'media', 'taxonomy', 'user', 'comment', - ), true - ) ) { - $pod_data['fields'][ $field ] = PodsForm::field_setup( array( 'name' => $field ) ); - } else { - if ( 'post_type' === $pod_data['type'] ) { - $pod_data['object_fields'] = $this->api->get_wp_object_fields( 'post_type', $pod_data, true ); + ], true ) ) { + // Set up a faux-field and use meta table fallback. + $the_field = PodsForm::field_setup( [ 'name' => $field ] ); + } elseif ( ! $pod_data instanceof Pod && 'post_type' === $pod_data['type'] ) { + // Maybe fallback to object field if it is tableless. + $pod_data['object_fields'] = $this->api->get_wp_object_fields( 'post_type', $pod_data, true ); - if ( 'post_type' === $pod_data['type'] && isset( $pod_data['object_fields'][ $field ] ) && in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) { - $pod_data['fields'][ $field ] = $pod_data['object_fields'][ $field ]; - } else { - return $joins; - } - } else { - return $joins; + if ( isset( $pod_data['object_fields'][ $field ] ) && in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) { + $the_field = $pod_data['object_fields'][ $field ]; } - }//end if - } elseif ( isset( $pod_data['object_fields'] ) && isset( $pod_data['object_fields'][ $field ] ) && ! in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) { + } + } + + if ( null === $the_field ) { return $joins; - }//end if + } + + $traverse = $the_field; - $traverse = $pod_data['fields'][ $field ]; + $table_info = array(); - if ( in_array( $traverse['type'], $file_field_types, true ) ) { - $traverse['table_info'] = $this->api->get_table_info( 'post_type', 'attachment' ); + if ( $the_field instanceof Field && $the_field->get_table_info() ) { + $table_info = $the_field->get_table_info(); + } elseif ( + in_array( $traverse['type'], $file_field_types, true ) + || ( + 'pick' === $traverse['type'] + && in_array( $traverse['pick_object'], [ 'media', 'attachment' ], true ) + ) + ) { + $table_info = $this->api->get_table_info( 'media', 'media' ); } elseif ( ! in_array( $traverse['type'], $tableless_field_types, true ) ) { - $traverse['table_info'] = $this->api->get_table_info( $pod_data['type'], $pod_data['name'], $pod_data['name'], $pod_data ); - } elseif ( empty( $traverse['table_info'] ) || ( in_array( $traverse['pick_object'], $simple_tableless_objects, true ) && ! empty( $traverse_recurse['last_table_info'] ) ) ) { - if ( in_array( $traverse['pick_object'], $simple_tableless_objects, true ) && ! empty( $traverse_recurse['last_table_info'] ) ) { - $traverse['table_info'] = $traverse_recurse['last_table_info']; + if ( $pod_data instanceof Pod ) { + $table_info = $pod_data->get_table_info(); + } else { + $table_info = $this->api->get_table_info( $pod_data['type'], $pod_data['name'], $pod_data['name'], $pod_data ); + } + } elseif ( in_array( $traverse['pick_object'], $simple_tableless_objects, true ) && ! empty( $traverse_recurse['last_table_info'] ) ) { + $has_last_table_info = ! empty( $traverse_recurse['last_table_info'] ); + + if ( $has_last_table_info ) { + $table_info = $traverse_recurse['last_table_info']; - if ( ! empty( $traverse['table_info']['meta_table'] ) ) { + if ( ! empty( $table_info['meta_table'] ) ) { $meta_data_table = true; } - } elseif ( ! in_array( $traverse['type'], $tableless_field_types, true ) && ! empty( $traverse_recurse['last_table_info'] ) && 0 === $traverse_recurse['depth'] ) { - $traverse['table_info'] = $traverse_recurse['last_table_info']; } else { if ( ! isset( $traverse['pod'] ) ) { $traverse['pod'] = null; @@ -3254,17 +3288,19 @@ public function traverse_recurse( $traverse_recurse ) { $traverse['pick_val'] = null; } - $traverse['table_info'] = $this->api->get_table_info( $traverse['pick_object'], $traverse['pick_val'], null, $traverse['pod'], $traverse ); + $table_info = $this->api->get_table_info( $traverse['pick_object'], $traverse['pick_val'], null, $traverse['pod'], $traverse ); + + $traverse['table_info'] = $table_info; } }//end if if ( isset( $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ] ) ) { - $traverse = array_merge( $traverse, (array) $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ] ); + $traverse = $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ]; } $traverse = apply_filters( 'pods_data_traverse', $traverse, $traverse_recurse, $this ); - if ( empty( $traverse ) ) { + if ( empty( $traverse ) || empty( $table_info ) ) { return $joins; } @@ -3274,14 +3310,12 @@ public function traverse_recurse( $traverse_recurse ) { $traverse['id'] = $field; } - $table_info = $traverse['table_info']; - $this->traversal[ $traverse_recurse['pod'] ][ $field ] = $traverse; $field_joined = $field; if ( 0 < $traverse_recurse['depth'] && 't' !== $traverse_recurse['joined'] ) { - if ( $meta_data_table && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse, true ), $simple_tableless_objects ) ) ) { + if ( $meta_data_table && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse, true ), $simple_tableless_objects, true ) ) ) { $field_joined = $traverse_recurse['joined'] . '_d'; } else { $field_joined = $traverse_recurse['joined'] . '_' . $field; @@ -3412,19 +3446,26 @@ public function traverse_recurse( $traverse_recurse ) { LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$joined_id}` "; - } else { + } elseif ( pods_podsrel_enabled() ) { if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects, true ) ) && 'post_author' === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) { $table_info['recurse'] = false; } - $the_join = " - LEFT JOIN `@wp_podsrel` AS `{$rel_alias}` ON - `{$rel_alias}`.`field_id` = {$traverse[ 'id' ]} - AND `{$rel_alias}`.`item_id` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}` + if ( ! is_numeric( $traverse['id'] ) ) { + $the_join = " + LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON + `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse['id']}` + "; + } else { + $the_join = " + LEFT JOIN `@wp_podsrel` AS `{$rel_alias}` ON + `{$rel_alias}`.`field_id` = {$traverse[ 'id' ]} + AND `{$rel_alias}`.`item_id` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}` - LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON - `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id` - "; + LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON + `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id` + "; + } }//end if } elseif ( 'meta' === $pod_data['storage'] ) { if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects, true ) ) && $table_info['meta_field_value'] === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) { @@ -3485,38 +3526,30 @@ public function traverse_recurse( $traverse_recurse ) { * @return array Array of joins */ public function traverse( $fields = null, $all_fields = null, $params = null ) { - - $joins = array(); - if ( null === $fields ) { $fields = $this->traverse_build( $all_fields, $params ); } - foreach ( (array) $fields as $field_group ) { - $traverse_recurse = array( - 'pod' => $this->pod, - 'fields' => $fields, - 'params' => $params, - 'last_table_info' => $this->pod_data, - 'joined_id' => $this->pod_data['field_id'], - 'joined_index' => $this->pod_data['field_index'], - ); + $fields = (array) $fields; - if ( is_array( $field_group ) ) { - $traverse_recurse['fields'] = $field_group; + $recurse_joins = []; - $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recurse ) ); - } else { - $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recurse ) ); - $joins = array_filter( $joins ); + foreach ( $fields as $field ) { + $traverse_recurse = [ + 'pod' => $this->pod, + 'fields' => (array) $field, + 'params' => $params, + 'last_table_info' => isset( $this->pod_data ) ? $this->pod_data : $this->table_info, + 'joined_id' => $this->field_id, + 'joined_index' => $this->field_index, + ]; - return $joins; - } - }//end foreach + $recurse_joins[] = $this->traverse_recurse( $traverse_recurse ); + } - $joins = array_filter( $joins ); + $joins = array_merge( ...$recurse_joins ); - return $joins; + return array_filter( $joins ); } /** @@ -3581,4 +3614,131 @@ public function get_sql( $sql = '' ) { return $sql; } + + /** + * Handle variables that have been deprecated and PodsData vars + * + * @param string $name Property name. + * + * @return mixed + * + * @since 2.8.0 + */ + public function __get( $name ) { + $name = (string) $name; + + // Map deprecated properties. + $mapped = array( + 'data' => 'rows', + ); + + if ( isset( $mapped[ $name ] ) ) { + return $this->{$mapped[$name]}; + } + + // Handle alias Pod properties. + $supported_pods_object = array( + 'pod' => 'name', + 'pod_id' => 'id', + 'fields' => 'fields', + 'object_fields' => 'object_fields', + 'detail_page' => 'detail_url', + 'detail_url' => 'detail_url', + 'select' => 'select', + 'table' => 'table', + 'field_id' => 'field_id', + 'field_index' => 'field_index', + 'field_slug' => 'field_slug', + 'join' => 'join', + 'where' => 'where', + 'where_default' => 'where_default', + 'orderby' => 'orderby', + 'type' => 'type', + 'storage' => 'storage', + ); + + if ( isset( $supported_pods_object[ $name ] ) ) { + if ( ! $this->pod_data instanceof Pod ) { + // Check if table info is set. + if ( ! is_array( $this->table_info ) ) { + return null; + } + + return pods_v( $supported_pods_object[ $name ], $this->table_info ); + } + + return $this->pod_data->get_arg( $supported_pods_object[ $name ] ); + } + + return null; + } + + /** + * Handle variables that have been deprecated. + * + * @param string $name Property name. + * @param mixed $value Property value. + * + * @since 2.8.0 + */ + public function __set( $name, $value ) { + // Don't do anything. + return; + } + + /** + * Handle variables that have been deprecated. + * + * @param string $name Property name. + * + * @return bool Whether the variable is set or not. + * + * @since 2.8.0 + */ + public function __isset( $name ) { + // Handle alias Pod properties. + $supported_pods_object = array( + 'pod' => 'name', + 'pod_id' => 'id', + 'fields' => 'fields', + 'detail_page' => 'detail_url', + 'detail_url' => 'detail_url', + 'select' => 'select', + 'table' => 'table', + 'field_id' => 'field_id', + 'field_index' => 'field_index', + 'field_slug' => 'field_slug', + 'join' => 'join', + 'where' => 'where', + 'where_default' => 'where_default', + 'orderby' => 'orderby', + ); + + if ( isset( $supported_pods_object[ $name ] ) ) { + if ( ! $this->pod_data instanceof Pod ) { + // Check if table info is set. + if ( ! is_array( $this->table_info ) ) { + return false; + } + + return null !== pods_v( $supported_pods_object[ $name ], $this->table_info ); + } + + return null !== $this->pod_data->get_arg( $supported_pods_object[ $name ] ); + } + + return false; + } + + /** + * Handle variables that have been deprecated. + * + * @param string $name Property name. + * + * @since 2.8.0 + */ + public function __unset( $name ) { + // Don't do anything. + return; + } } diff --git a/classes/PodsField.php b/classes/PodsField.php index c51959f2c6..7c01497a61 100644 --- a/classes/PodsField.php +++ b/classes/PodsField.php @@ -1,5 +1,7 @@ options['_field_object'] ) ) { + $args->field = $args->options['_field_object']; + + unset( $args->options['_field_object'] ); + } + + // Update options so it's as expected. + if ( ! empty( $args->field ) ) { + $args->options = pods_config_merge_data( $args->options, clone $args->field ); + } + + // Remove potential 2.8 beta fragments. + if ( ! empty( $args->options['pod_data'] ) ) { + unset( $args->options['pod_data'] ); + } + + $disable_dfv = ! empty( $args->options['disable_dfv'] ); + + $field_class = "pods-form-ui-field pods-dfv-field"; + + if ( ! $disable_dfv ) { + $field_class .= ' pods-dfv-field--unloaded'; + } + + $pod_name = ''; + + if ( $args->pod instanceof Pods ) { + $pod_name = $args->pod->pod_data['name']; + } elseif ( ! empty( $args->pod ) ) { + $pod_name = $args->pod['name']; + } + $script_content = wp_json_encode( $this->build_dfv_field_data( $args ), JSON_HEX_TAG ); ?> -
+
+ + + - +
options; // Handle DFV options. - $args->options = $this->build_dfv_field_options( $args->options, $args ); + $args->options = $this->build_dfv_field_options( $options, $args ); // Handle DFV attributes. $attributes = PodsForm::merge_attributes( array(), $args->name, $args->type, $args->options ); $attributes = $this->build_dfv_field_attributes( $attributes, $args ); $attributes = array_map( 'esc_attr', $attributes ); + $default_value = ''; + + if ( 'multi' === pods_v( $args->type . '_format_type' ) ) { + $default_value = []; + } + // Build DFV field data. - $data = array( - 'htmlAttr' => array( + $data = [ + 'htmlAttr' => [ 'id' => $attributes['id'], 'class' => $attributes['class'], 'name' => $attributes['name'], 'name_clean' => $attributes['data-name-clean'], - ), + ], 'fieldType' => $args->type, 'fieldItemData' => $this->build_dfv_field_item_data( $args ), 'fieldConfig' => $this->build_dfv_field_config( $args ), - ); + 'fieldEmbed' => true, + 'fieldValue' => isset( $args->value ) ? $args->value : PodsForm::default_value( $default_value, $args->type, pods_v( 'name', $options, $args->name ), $options, $args->pod, $args->id ), + ]; /** * Filter Pods DFV field data to further customize functionality. @@ -495,25 +543,43 @@ public function build_dfv_field_attributes( $attributes, $args ) { * @param object $args { * Field information arguments. * - * @type string $name Field name. - * @type string $type Field type. - * @type array $options Field options. - * @type mixed $value Current value. - * @type array $pod Pod information. - * @type int|string $id Current item ID. - * @type string $form_field_type HTML field type. + * @type string $name Field name. + * @type string $type Field type. + * @type array $options Field options. + * @type Field|null $field Field object (if provided). + * @type mixed $value Current value. + * @type array $pod Pod information. + * @type int|string $id Current item ID. + * @type string $form_field_type HTML field type. * } * * @return array */ public function build_dfv_field_config( $args ) { - - $config = $args->options; + if ( $args->options instanceof Field ) { + $config = $args->options->export(); + } else { + $config = (array) $args->options; + } unset( $config['data'] ); $config['item_id'] = (int) $args->id; + // Support passing missing options. + $check_missing = [ + 'type', + 'name', + 'label', + 'id', + ]; + + foreach ( $check_missing as $missing_name ) { + if ( ! empty( $args->{$missing_name} ) ) { + $config[ $missing_name ] = $args->{$missing_name}; + } + } + return $config; } @@ -539,8 +605,8 @@ public function build_dfv_field_item_data( $args ) { $data = array(); - if ( ! empty( $args->options['data'] ) && is_array( $args->options['data'] ) ) { - $data = $args->options['data']; + if ( ! empty( $args->options['fieldItemData'] ) && is_array( $args->options['fieldItemData'] ) ) { + $data = $args->options['fieldItemData']; } return $data; @@ -774,48 +840,108 @@ public function is_required( $options ) { * @return string */ public function strip_html( $value, $options = null ) { - if ( is_array( $value ) ) { - // @codingStandardsIgnoreLine - $value = @implode( ' ', $value ); - } + foreach ( $value as $k => $v ) { + $value[ $k ] = $this->strip_html( $v, $options ); + } - $value = trim( $value ); + return $value; + } if ( empty( $value ) ) { return $value; } - $options = (array) $options; - - // Strip HTML - if ( 1 === (int) pods_v( static::$type . '_allow_html', $options, 0 ) ) { - $allowed_html_tags = ''; + if ( $options ) { + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; - if ( 0 < strlen( pods_v( static::$type . '_allowed_html_tags', $options ) ) ) { + // Strip HTML + if ( 1 === (int) pods_v( static::$type . '_allow_html', $options, 0 ) ) { $allowed_tags = pods_v( static::$type . '_allowed_html_tags', $options ); - $allowed_tags = trim( str_replace( array( '<', '>', ',' ), ' ', $allowed_tags ) ); - $allowed_tags = explode( ' ', $allowed_tags ); - $allowed_tags = array_unique( array_filter( $allowed_tags ) ); - if ( ! empty( $allowed_tags ) ) { - $allowed_html_tags = '<' . implode( '><', $allowed_tags ) . '>'; + if ( 0 < strlen( $allowed_tags ) ) { + $allowed_tags = trim( str_replace( [ '<', '>', ',' ], ' ', $allowed_tags ) ); + $allowed_tags = explode( ' ', $allowed_tags ); + $allowed_tags = array_unique( array_filter( $allowed_tags ) ); + + if ( ! empty( $allowed_tags ) ) { + $allowed_html_tags = '<' . implode( '><', $allowed_tags ) . '>'; + + $value = strip_tags( $value, $allowed_html_tags ); + } } + + return $value; } + } + + return strip_tags( $value ); + } - if ( ! empty( $allowed_html_tags ) ) { - $value = strip_tags( $value, $allowed_html_tags ); + /** + * Strip shortcodes based on options. + * + * @since 2.8.0 + * + * @param string|array $value The field value. + * @param array|Field|null $options The field options. + * + * @return string The field value. + */ + public function strip_shortcodes( $value, $options = null ) { + if ( is_array( $value ) ) { + foreach ( $value as $k => $v ) { + $value[ $k ] = $this->strip_shortcodes( $v, $options ); } - } else { - $value = strip_tags( $value ); + + return $value; } - // Strip shortcodes - if ( 0 === (int) pods_v( static::$type . '_allow_shortcode', $options ) ) { - $value = strip_shortcodes( $value ); + if ( empty( $value ) ) { + return $value; } - return $value; + if ( $options ) { + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; + + // Check if we should strip shortcodes. + if ( 1 === (int) pods_v( static::$type . '_allow_shortcode', $options, 0 ) ) { + return $value; + } + } + + return strip_shortcodes( $value ); + } + + /** + * Trim whitespace based on options. + * + * @since 2.8.0 + * + * @param string|array $value The field value. + * @param array|Field|null $options The field options. + * + * @return string The field value. + */ + public function trim_whitespace( $value, $options = null ) { + if ( is_array( $value ) ) { + foreach ( $value as $k => $v ) { + $value[ $k ] = $this->trim_whitespace( $v, $options ); + } + + return $value; + } + + if ( $options ) { + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; + + // Check if we should trim the content. + if ( 0 === (int) pods_v( static::$type . '_trim', $options, 1 ) ) { + return $value; + } + } + + return trim( $value ); } /** diff --git a/classes/PodsForm.php b/classes/PodsForm.php index 9230c293fa..0e3f542488 100644 --- a/classes/PodsForm.php +++ b/classes/PodsForm.php @@ -1,5 +1,7 @@ load_helper( array( 'name' => $options['input_helper'] ) ); } - // @todo Move into DFV field method or PodsObject later + // @todo Move into DFV field method or Pods\Whatsit later if ( ( ! isset( $options['data'] ) || empty( $options['data'] ) ) && is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'data' ) ) { $options['data'] = self::$loaded[ $type ]->data( $name, $value, $options, $pod, $id, true ); $data = $options['data']; @@ -610,55 +612,44 @@ public static function merge_attributes( $attributes, $name = null, $type = null * @since 2.0.0 */ public static function options( $type, $options ) { - - $options = (array) $options; - - if ( ! is_object( $options ) && isset( $options['options'] ) ) { - $options_temp = $options['options']; - - unset( $options['options'] ); - - $options = array_merge( $options_temp, $options ); - - $override = array( - 'class', - ); - - foreach ( $override as $check ) { - if ( isset( $options_temp[ $check ] ) ) { - $options[ $check ] = $options_temp[ $check ]; - } - } + if ( is_object( $options ) ) { + $options_array = $options->get_args(); + $options_array['_field_object'] = $options; + } else { + $options_array = (array) $options; + $options_array['_field_object'] = null; } - $defaults = self::options_setup( $type, $options ); + $defaults = self::options_setup( $type ); - $core_defaults = array( + $core_defaults = [ 'id' => 0, 'label' => '', 'description' => '', 'help' => '', 'default' => null, - 'attributes' => array(), + 'attributes' => [], 'class' => '', 'grouped' => 0, - ); + ]; $defaults = array_merge( $core_defaults, $defaults ); foreach ( $defaults as $option => $settings ) { - $default = $settings; + $default = $core_defaults['default']; - if ( is_array( $settings ) && isset( $settings['default'] ) ) { + if ( ! is_array( $settings ) ) { + $default = $settings; + } elseif ( isset( $settings['default'] ) ) { $default = $settings['default']; } - if ( ! isset( $options[ $option ] ) ) { - $options[ $option ] = $default; + if ( ! isset( $options_array[ $option ] ) ) { + $options_array[ $option ] = $default; } } - return $options; + return $options_array; } /** @@ -690,7 +681,9 @@ public static function options_setup( $type = null, $options = null ) { 'developer_mode' => false, 'dependency' => false, 'depends-on' => array(), + 'depends-on-any' => array(), 'excludes-on' => array(), + 'wildcard-on' => array(), 'options' => array(), ); @@ -704,23 +697,19 @@ public static function options_setup( $type = null, $options = null ) { self::field_loader( $type ); } - $options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type ); - - $first_field = current( $options ); + $ui_options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type ); - if ( ! empty( $options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) { - $all_options = array(); + $first_field = reset( $ui_options ); - foreach ( $options as $group => $group_options ) { - $all_options = array_merge( $all_options, self::fields_setup( $group_options, $core_defaults ) ); + if ( ! empty( $ui_options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) { + foreach ( $ui_options as $group => $group_options ) { + $ui_options[ $group ] = self::fields_setup( $group_options, $core_defaults ); } - $options = $all_options; - } else { - $options = self::fields_setup( $options, $core_defaults ); + return $ui_options; } - return $options; + return self::fields_setup( $ui_options, $core_defaults ); } /** @@ -751,25 +740,27 @@ public static function ui_options( $type ) { 'developer_mode' => false, 'dependency' => false, 'depends-on' => array(), + 'depends-on-any' => array(), 'excludes-on' => array(), + 'wildcard-on' => array(), 'options' => array(), ); self::field_loader( $type ); - $options = apply_filters( "pods_field_{$type}_ui_options", (array) self::$loaded[ $type ]->ui_options(), $type ); + $ui_options = apply_filters( "pods_field_{$type}_ui_options", (array) self::$loaded[ $type ]->ui_options(), $type ); - $first_field = current( $options ); + $first_field = reset( $ui_options ); - if ( ! empty( $options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) { - foreach ( $options as $group => $group_options ) { - $options[ $group ] = self::fields_setup( $group_options, $core_defaults ); + if ( ! empty( $ui_options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) { + foreach ( $ui_options as $group => $group_options ) { + $ui_options[ $group ] = self::fields_setup( $group_options, $core_defaults ); } - } else { - $options = self::fields_setup( $options, $core_defaults ); + + return $ui_options; } - return $options; + return self::fields_setup( $ui_options, $core_defaults ); } /** @@ -802,7 +793,9 @@ public static function fields_setup( $fields = null, $core_defaults = null, $sin 'developer_mode' => false, 'dependency' => false, 'depends-on' => array(), + 'depends-on-any' => array(), 'excludes-on' => array(), + 'wildcard-on' => array(), 'options' => array(), ); } @@ -812,11 +805,11 @@ public static function fields_setup( $fields = null, $core_defaults = null, $sin } foreach ( $fields as $f => $field ) { - $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) ); - - if ( ! $single && strlen( $fields[ $f ]['name'] ) < 1 ) { - $fields[ $f ]['name'] = $f; + if ( ! $single && empty( $field['name'] ) ) { + $field['name'] = $f; } + + $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) ); } if ( $single ) { @@ -831,9 +824,9 @@ public static function fields_setup( $fields = null, $core_defaults = null, $sin * * @static * - * @param null $field - * @param null $core_defaults - * @param null $type + * @param null|array|string|Field $field + * @param null|array $core_defaults + * @param null|string $type * * @return array|null * @@ -841,7 +834,7 @@ public static function fields_setup( $fields = null, $core_defaults = null, $sin */ public static function field_setup( $field = null, $core_defaults = null, $type = null ) { - $options = array(); + $ui_options = array(); if ( empty( $core_defaults ) ) { $core_defaults = array( @@ -859,7 +852,9 @@ public static function field_setup( $field = null, $core_defaults = null, $type 'developer_mode' => false, 'dependency' => false, 'depends-on' => array(), + 'depends-on-any' => array(), 'excludes-on' => array(), + 'wildcard-on' => array(), 'options' => array(), ); @@ -867,36 +862,55 @@ public static function field_setup( $field = null, $core_defaults = null, $type self::field_loader( $type ); if ( method_exists( self::$loaded[ $type ], 'options' ) ) { - $options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type ); + $ui_options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type ); } } }//end if - if ( ! is_array( $field ) ) { - $field = array( 'default' => $field ); + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { + $field = [ + 'default' => $field, + ]; } + // @todo Revisit this. if ( isset( $field['group'] ) && is_array( $field['group'] ) ) { - foreach ( $field['group'] as $g => $group_option ) { - $field['group'][ $g ] = array_merge( $core_defaults, $group_option ); + $group = $field['group']; + + foreach ( $group as $g => $group_option ) { + $group[ $g ] = array_merge( $core_defaults, $group_option ); - if ( strlen( $field['group'][ $g ]['name'] ) < 1 ) { - $field['group'][ $g ]['name'] = $g; + if ( ! isset( $group[ $g ] ) || '' === $group[ $g ]['name'] ) { + $group[ $g ]['name'] = $g; } } + + $field['group'] = $group; } - $field = array_merge( $core_defaults, $field ); + $field = pods_config_merge_data( $core_defaults, $field ); + + foreach ( $ui_options as $option => $settings ) { + if ( ! is_string( $option ) ) { + $option = $settings['name']; + } - foreach ( $options as $option => $settings ) { - $v = null; + $default = null; if ( isset( $settings['default'] ) ) { - $v = $settings['default']; + $default = $settings['default']; } - if ( ! isset( $field['options'][ $option ] ) ) { - $field['options'][ $option ] = $v; + if ( $is_field_object ) { + $option_value = $field->get_arg( $option ); + + if ( null === $option_value ) { + $field->set_arg( $option, $default ); + } + } elseif ( ! isset( $field['options'][ $option ] ) ) { + $field['options'][ $option ] = $default; } } @@ -913,53 +927,41 @@ public static function field_setup( $field = null, $core_defaults = null, $type * @static * @since 2.0.0 */ - public static function dependencies( $options, $prefix = '' ) { - - $options = (array) $options; - $classes = array(); - $data = array(); - $depends_on = array(); - $excludes_on = array(); - $wildcard_on = array(); + public static function dependencies( $options, $prefix = 'pods-form-ui-' ) { + $options = (array) $options; + $classes = []; + $data = []; + + $dependency_checks = [ + 'depends-on', + 'depends-on-any', + 'excludes-on', + ]; + + foreach ( $dependency_checks as $dependency_check ) { + if ( ! isset( $options[ $dependency_check ] ) ) { + continue; + } - if ( isset( $options['depends-on'] ) ) { - $depends_on = (array) $options['depends-on']; + $dependency_list = (array) $options[ $dependency_check ]; - if ( ! empty( $depends_on ) ) { - $classes[] = 'pods-depends-on'; + if ( ! empty( $dependency_list ) ) { + $classes[] = 'pods-' . $dependency_check; - foreach ( $depends_on as $depends => $on ) { - $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ); + foreach ( $dependency_list as $depends => $on ) { + $classes[] = 'pods-' . $dependency_check . '-' . $prefix . self::clean( $depends, true ); if ( ! is_bool( $on ) ) { $on = (array) $on; foreach ( $on as $o ) { - $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true ); + $classes[] = 'pods-' . $dependency_check . '-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true ); } } } } } - if ( isset( $options['excludes-on'] ) ) { - $excludes_on = (array) $options['excludes-on']; - - if ( ! empty( $excludes_on ) ) { - $classes[] = 'pods-excludes-on'; - - foreach ( $excludes_on as $excludes => $on ) { - $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ); - - $on = (array) $on; - - foreach ( $on as $o ) { - $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ) . '-' . self::clean( $o, true ); - } - } - } - } - if ( isset( $options['wildcard-on'] ) ) { $wildcard_on = (array) $options['wildcard-on']; @@ -1284,12 +1286,13 @@ public static function delete( $type, $id = null, $name = null, $options = null, * @return bool */ public static function permission( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) { - $permission = pods_permission( $options ); - $permission = (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params ); - - return $permission; + /** + * @since 2.0.0 + * @deprecated 2.8.0 + */ + return (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params ); } /** @@ -1317,21 +1320,29 @@ public static function default_value( $value, $type = 'text', $name = null, $opt $default = pods_v( 'default', $options, $default_value, true ); if ( is_string( $default ) ) { - $default_value = str_replace( array( '{@', '}' ), '', trim( $default ) ); - } + $default_value = str_replace( array( '{@', '}' ), '', $default ); - if ( $default != $default_value && 1 == (int) pods_v( 'default_evaluate_tags', $options, 1 ) ) { - $default = pods_evaluate_tags( $default ); + if ( $default !== $default_value && 1 === (int) pods_v( 'default_evaluate_tags', $options, 1 ) ) { + $default = pods_evaluate_tags( $default ); + } } - $default = pods_v( pods_v( 'default_value_parameter', $options ), 'request', $default, true ); + $default_value_parameter = pods_v( 'default_value_parameter', $options ); + + if ( $default_value_parameter ) { + $default_value = pods_v( $default_value_parameter, 'request', $default ); + + if ( '' !== $default_value ) { + $default = $default_value; + } + } if ( $default != $value ) { $value = $default; } - if ( is_array( $value ) ) { - $value = pods_serial_comma( $value ); + if ( is_array( $value ) && 'multi' !== pods_v( $args->type . '_format_type' ) ) { + $value = pods_serial_comma( $value, $name, [ $name => $options ] ); } return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id ); @@ -1402,7 +1413,7 @@ public function admin_init() { } } - pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types ); + pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types, WEEK_IN_SECONDS ); } else { foreach ( $admin_field_types as $field_type ) { self::field_method( $field_type, 'admin_init' ); @@ -1434,8 +1445,6 @@ public static function field_loader( $field_type, $file = '' ) { } } - include_once PODS_DIR . 'classes/PodsField.php'; - $field_type = self::clean( $field_type, true, true ); $class_name = ucfirst( $field_type ); @@ -1455,11 +1464,14 @@ public static function field_loader( $field_type, $file = '' ) { if ( ! empty( $file ) && 0 === strpos( $file, $abspath_dir ) && file_exists( $file ) ) { include_once $file; } else { - $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', PODS_DIR . 'classes/fields/' . basename( $field_type ) . '.php', $field_type ) ); - $file = realpath( $file ); + $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', '', $field_type ) ); - if ( file_exists( $file ) && ( 0 === strpos( $file, $pods_dir ) || 0 === strpos( $file, $content_dir ) || 0 === strpos( $file, $plugins_dir ) || 0 === strpos( $file, $muplugins_dir ) || 0 === strpos( $file, $abspath_dir ) ) ) { - include_once $file; + if ( ! empty( $file ) ) { + $file = realpath( $file ); + + if ( file_exists( $file ) && ( 0 === strpos( $file, $pods_dir ) || 0 === strpos( $file, $content_dir ) || 0 === strpos( $file, $plugins_dir ) || 0 === strpos( $file, $muplugins_dir ) || 0 === strpos( $file, $abspath_dir ) ) ) { + include_once $file; + } } } } @@ -1472,6 +1484,7 @@ public static function field_loader( $field_type, $file = '' ) { } $class_vars = get_class_vars( $class_name ); + // PHP 5.2.x workaround self::$field_group = ( isset( $class_vars['group'] ) ? $class_vars['group'] : '' ); self::$field_type = $class_vars['type']; @@ -1535,7 +1548,7 @@ public static function register_field_type( $type, $file = null ) { self::$field_types[ $type ] = $class_vars; self::$field_types[ $type ]['file'] = $file; - pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ] ); + pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ], WEEK_IN_SECONDS ); } else { self::$field_types[ $type ] = $field_type; } @@ -1544,15 +1557,43 @@ public static function register_field_type( $type, $file = null ) { } /** - * Get a list of all available field types and include + * Get a list of all available Pod types. * - * @return array Registered Field Types data + * @return string[] List of Pod types. * - * @since 2.3.0 + * @since 2.8.0 */ - public static function field_types() { + public static function pod_types_list() { + $pod_types = [ + 'post_type', + 'taxonomy', + 'user', + 'media', + 'comment', + 'settings', + 'pod', + 'table', + ]; - $field_types = array( + /** + * Allow filtering of the supported Pod types. + * + * @since 2.8.0 + * + * @param array $pod_types List of Pod types supported. + */ + return apply_filters( 'pods_api_pod_types', $pod_types ); + } + + /** + * Get a list of all available Field types. + * + * @return string[] List of Field types. + * + * @since 2.8.0 + */ + public static function field_types_list() { + $field_types = [ 'text', 'website', // 'link', @@ -1574,13 +1615,27 @@ public static function field_types() { 'boolean', 'color', 'slug', - ); + 'heading', + 'html', + ]; $field_types = array_merge( $field_types, array_keys( self::$field_types ) ); $field_types = array_filter( array_unique( $field_types ) ); - $types = apply_filters( 'pods_api_field_types', $field_types ); + return apply_filters( 'pods_api_field_types', $field_types ); + } + + /** + * Get a list of all available field types and include + * + * @return array Registered Field Types data + * + * @since 2.3.0 + */ + public static function field_types() { + + $types = self::field_types_list(); $field_types = pods_transient_get( 'pods_field_types' ); @@ -1608,7 +1663,7 @@ public static function field_types() { self::$field_types = $field_types; - pods_transient_set( 'pods_field_types', self::$field_types ); + pods_transient_set( 'pods_field_types', self::$field_types, WEEK_IN_SECONDS ); } else { self::$field_types = array_merge( $field_types, self::$field_types ); }//end if @@ -1617,24 +1672,24 @@ public static function field_types() { } /** - * Get list of available tableless field types - * - * @return array Tableless field types + * Get the list of available tableless field types. * * @since 2.3.0 + * + * @return array The list of available tableless field types. */ public static function tableless_field_types() { - static $field_types = null; if ( null === $field_types ) { - $field_types = array( + $field_types = [ 'pick', 'file', 'avatar', 'taxonomy', 'comment', - ); + 'author', + ]; $field_types = apply_filters( 'pods_tableless_field_types', $field_types ); } @@ -1643,18 +1698,20 @@ public static function tableless_field_types() { } /** - * Get list of available file field types - * - * @return array File field types + * Get the list of available file field types. * * @since 2.3.0 + * + * @return array The list of available file field types. */ public static function file_field_types() { - static $field_types = null; if ( null === $field_types ) { - $field_types = array( 'file', 'avatar' ); + $field_types = [ + 'file', + 'avatar', + ]; $field_types = apply_filters( 'pods_file_field_types', $field_types ); } @@ -1663,18 +1720,17 @@ public static function file_field_types() { } /** - * Get list of available repeatable field types - * - * @return array Repeatable field types + * Get the list of available repeatable field types. * * @since 2.3.0 + * + * @return array The list of available repeatable field types. */ public static function repeatable_field_types() { - static $field_types = null; if ( null === $field_types ) { - $field_types = array( + $field_types = [ 'code', 'color', 'currency', @@ -1688,7 +1744,7 @@ public static function repeatable_field_types() { 'time', 'website', 'wysiwyg', - ); + ]; $field_types = apply_filters( 'pods_repeatable_field_types', $field_types ); } @@ -1697,18 +1753,20 @@ public static function repeatable_field_types() { } /** - * Get list of available number field types - * - * @return array Number field types + * Get the list of available number field types. * * @since 2.3.0 + * + * @return array The list of available number field types. */ public static function number_field_types() { - static $field_types = null; if ( null === $field_types ) { - $field_types = array( 'currency', 'number' ); + $field_types = [ + 'currency', + 'number', + ]; $field_types = apply_filters( 'pods_tableless_field_types', $field_types ); } @@ -1717,18 +1775,21 @@ public static function number_field_types() { } /** - * Get list of available date field types - * - * @return array Date field types + * Get the list of available date field types. * * @since 2.3.0 + * + * @return array The list of available date field types. */ public static function date_field_types() { - static $field_types = null; if ( null === $field_types ) { - $field_types = array( 'date', 'datetime', 'time' ); + $field_types = [ + 'date', + 'datetime', + 'time', + ]; $field_types = apply_filters( 'pods_tableless_field_types', $field_types ); } @@ -1737,18 +1798,24 @@ public static function date_field_types() { } /** - * Get list of available text field types - * - * @return array Text field types + * Get the list of available text field types. * * @since 2.3.0 + * + * @return array The list of available text field types. */ public static function text_field_types() { - static $field_types = null; if ( null === $field_types ) { - $field_types = array( 'code', 'paragraph', 'slug', 'password', 'text', 'wysiwyg' ); + $field_types = [ + 'code', + 'paragraph', + 'slug', + 'password', + 'text', + 'wysiwyg', + ]; $field_types = apply_filters( 'pods_text_field_types', $field_types ); } @@ -1757,39 +1824,68 @@ public static function text_field_types() { } /** - * Get list of available text field types + * Get the list of available Layout field types. * - * @return array Text field types + * @since 2.8.0 * - * @since 2.3.0 + * @return array The list of available Layout field types. */ - public static function block_field_types() { - + public static function layout_field_types() { static $field_types = null; if ( null === $field_types ) { - $field_types = array( 'heading', 'html' ); + $field_types = [ + 'heading', + 'html', + ]; /** - * Returns the available text field types + * Allow filtering of the list of Layout field types. * - * @since unknown + * @since 2.8.0 * - * @param object $field_types Outputs the field types + * @param array $field_types The list of Layout field types. */ - - $field_types = apply_filters( 'pods_block_field_types', $field_types ); + $field_types = apply_filters( 'pods_layout_field_types', $field_types ); } return $field_types; } /** - * Get list of available text field types + * Get the list of available Non-Input field types. * - * @return array Text field types + * @since 2.8.0 + * + * @return array The list of available Non-Input field types. + */ + public static function non_input_field_types() { + static $field_types = null; + + if ( null === $field_types ) { + $field_types = [ + 'internal', + ]; + + /** + * Allow filtering of the list of Non-Input field types. + * + * @since 2.8.0 + * + * @param array $field_types The list of Non-Input field types. + */ + $field_types = apply_filters( 'pods_non_input_field_types', $field_types ); + } + + return $field_types; + } + + /** + * Get the list of simple tableless objects. * * @since 2.3.0 + * + * @return array The list of simple tableless objects. */ public static function simple_tableless_objects() { diff --git a/classes/PodsI18n.php b/classes/PodsI18n.php index c508837295..3b3863f077 100644 --- a/classes/PodsI18n.php +++ b/classes/PodsI18n.php @@ -24,7 +24,7 @@ final class PodsI18n { /** * @var mixed Current language data */ - private static $current_language_data = null; + private static $current_language_context = null; /** * Singleton handling for a basic pods_i18n() request @@ -37,9 +37,6 @@ private function __construct() { // Hook all enqueue scripts actions add_action( 'pods_before_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); - - // Polylang - add_filter( 'pll_get_post_types', array( $this, 'pll_get_post_types' ), 10, 2 ); } /** @@ -236,25 +233,43 @@ public function get_current_language( $args = array() ) { return self::$current_language; } - $this->get_current_language_data( $args ); + /** + * Override language data used by Pods. + * + * @since 2.8.0 + * + * @param string $language Language slug + * @param array $context Language context + * @param array $args Arguments + */ + self::$current_language = apply_filters( 'pods_get_current_language', self::$current_language, self::get_current_language_context( $args ), $args ); return self::$current_language; } /** - * Get current language information from Multilingual plugins + * Get current language context information. * * @since 2.6.6 * @since 2.7 Moved to this class from PodsAPI + * @since 2.8.0 Refactored from get_current_language_data() * * @param array $args (optional) { - * - * @type bool $refresh Rerun logic? + * @type bool $refresh Rerun logic? * } * - * @return array + * @return array $context { + * Language data. + * @type bool $is_admin Is admin. + * @type bool $is_ajax Is AJAX call. + * @type bool $is_pods_ajax Is Pods AJAX call. + * @type string $current_page Current admin page. + * @type string $current_object_type Current object type (post / term / comment / user). + * @type int $current_item_id Current item id. + * @type string $current_item_type Current item type. + * } */ - public function get_current_language_data( $args = array() ) { + public function get_current_language_context( $args = array() ) { $defaults = array( 'refresh' => false, @@ -262,58 +277,29 @@ public function get_current_language_data( $args = array() ) { $args = wp_parse_args( $args, $defaults ); - if ( ! $args['refresh'] && ! empty( self::$current_language_data ) ) { - return self::$current_language_data; + if ( ! $args['refresh'] && ! empty( self::$current_language_context ) ) { + return self::$current_language_context; } - /** - * @var \SitePress $sitepress object - * @var \Polylang $polylang object - */ - /* - * @todo wpml-comp Remove global object usage - */ - global $sitepress, $polylang; - - $lang_data = false; - $translator = false; - $current_language = false; + $pods_ajax = pods_v( 'pods_ajax', 'request', false ); - // Multilingual support. - if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { - // WPML support. - $translator = 'WPML'; - - // Get the global current language (if set). - $wpml_language = apply_filters( 'wpml_current_language', null ); - $current_language = ( 'all' !== $wpml_language ) ? $wpml_language : ''; - - } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) { - // Polylang support. - $translator = 'PLL'; - - // Get the global current language (if set). - $current_language = pll_current_language( 'slug' ); - } + $context = [ + 'is_admin' => is_admin(), + 'is_ajax' => defined( 'DOING_AJAX' ) && DOING_AJAX, + 'is_pods_ajax' => $pods_ajax, + 'current_page' => '', + 'current_object_type' => '', + 'current_item_id' => '', + 'current_item_type' => '', + ]; /** - * Admin functions that overwrite the current language. + * Admin functions that overwrite the current language context. * * @since 2.6.6 + * @since 2.8.0 Refactored for current context instead of language data. */ - if ( is_admin() && ! empty( $translator ) ) { - if ( 'PLL' === $translator ) { - /** - * Polylang support. - * Get the current user's preferred language. - * This is a user meta setting that will overwrite the language returned from pll_current_language(). - * - * @see \PLL_Admin_Base::init_user() (polylang/admin/admin-base.php) - */ - $current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true ); - } - - $pods_ajax = pods_v( 'pods_ajax', 'request', false ); + if ( is_admin() ) { // Get current language based on the object language if available. $page = basename( pods_v( 'SCRIPT_NAME', $_SERVER, '' ) ); @@ -323,197 +309,93 @@ public function get_current_language_data( $args = array() ) { $page = explode( '?', $page ); $page = reset( $page ); - /** - * Overwrite the current language if needed for post types. - */ - if ( 'post.php' === $page || 'edit.php' === $page ) { + $context['current_page'] = $page; - $current_post = (int) pods_v( 'post', 'request', 0 ); - if ( $pods_ajax ) { - $current_post = (int) pods_v( 'id', 'request', $current_post ); - } + switch ( $page ) { - if ( $current_post ) { + case 'post.php': + case 'edit.php': + $context['current_object_type'] = 'post'; - $current_post_type = get_post_type( $current_post ); + $current_post_id = (int) pods_v( 'post', 'request', 0 ); + if ( $pods_ajax ) { + $current_post_id = (int) pods_v( 'id', 'request', $current_post_id ); + } - /** - * WPML support. - * In WPML the current language is always set to default on an edit screen. - * We need to overwrite this when the current object is not-translatable to enable relationships with different languages. - */ - if ( 'WPML' === $translator && ! apply_filters( 'wpml_is_translated_post_type', false, $current_post_type ) ) { - // Overwrite the current language to nothing if this is a NOT-translatable post_type. - $current_language = ''; + $current_post_type = pods_v( 'post_type', 'request', '' ); + if ( ! $current_post_type && $current_post_id ) { + $current_post_type = get_post_type( $current_post_id ); } - /** - * Polylang support. - * In polylang the preferred language could be anything. - */ - if ( 'PLL' === $translator && pll_is_translated_post_type( $current_post_type ) ) { - - /** - * Polylang (1.5.4+). - * We only want the related objects if they are not translatable OR the same language as the current object. - */ - if ( function_exists( 'pll_get_post_language' ) ) { - // Overwrite the current language if this is a translatable post_type. - $current_language = pll_get_post_language( $current_post ); - } - - /** - * Polylang (1.0.1+). - * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language. - */ - $current_language = pods_v( 'new_lang', 'request', $current_language ); + $context['current_item_id'] = $current_post_id; + $context['current_item_type'] = $current_post_type; + break; + + case 'term.php': + case 'edit-tags.php': + $context['current_object_type'] = 'term'; + + $current_term_id = (int) pods_v( 'tag_ID', 'request', 0 ); + if ( $pods_ajax ) { + $current_term_id = (int) pods_v( 'id', 'request', $current_term_id ); } - } - } //end if - - /** - * Overwrite the current language if needed for taxonomies. - */ - elseif ( 'term.php' === $page || 'edit-tags.php' === $page ) { - - $current_term_id = pods_v( 'tag_ID', 'request', 0 ); - if ( $pods_ajax ) { - $current_term_id = (int) pods_v( 'id', 'request', $current_term_id ); - } - - $current_taxonomy = pods_v( 'taxonomy', 'request', '' ); - if ( ! $current_taxonomy && $current_term_id ) { - $current_taxonomy = pods_v( 'taxonomy', get_term( $current_term_id ), null ); - } - - // @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy'] - if ( $current_taxonomy ) { - - /* - * @todo wpml-comp API call for taxonomy needed! - * Suggested API call: - * add_filter( 'wpml_is_translated_taxonomy', $_GET['taxonomy'], 10, 2 ); - */ - /** - * WPML support. - * In WPML the current language is always set to default on an edit screen. - * We need to overwrite this when the current object is not-translatable to enable relationships with different languages. - */ - if ( 'WPML' === $translator && method_exists( $sitepress, 'is_translated_taxonomy' ) && ! $sitepress->is_translated_taxonomy( $current_taxonomy ) ) { - // Overwrite the current language to nothing if this is a NOT-translatable taxonomy. - $current_language = ''; + + $current_taxonomy = pods_v( 'taxonomy', 'request', '' ); + if ( ! $current_taxonomy && $current_term_id ) { + $current_taxonomy = pods_v( 'taxonomy', get_term( $current_term_id ), null ); } - /** - * Polylang support. - * In polylang the preferred language could be anything. - */ - if ( 'PLL' === $translator && pll_is_translated_taxonomy( $current_taxonomy ) ) { - - /** - * Polylang (1.5.4+). - * We only want the related objects if they are not translatable OR the same language as the current object. - */ - if ( $current_term_id && function_exists( 'pll_get_term_language' ) ) { - // Overwrite the current language if this is a translatable taxonomy - $current_language = pll_get_term_language( $current_term_id ); - } - - /** - * Polylang (1.0.1+). - * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language. - */ - $current_language = pods_v( 'new_lang', 'request', $current_language ); + $context['current_item_id'] = $current_term_id; + $context['current_item_type'] = $current_taxonomy; + break; + + case 'comment.php': + $context['current_object_type'] = 'comment'; + $context['current_item_type'] = 'comment'; + + $current_comment_id = (int) pods_v( 'c', 'request', 0 ); + if ( $pods_ajax ) { + $current_comment_id = (int) pods_v( 'id', 'request', $current_comment_id ); } - }//end if - }//end if - }//end if (admin) + $context['current_item_id'] = $current_comment_id; + break; + + case 'user-edit.php': + $context['current_object_type'] = 'user'; + $context['current_item_type'] = 'user'; + + $current_user_id = (int) pods_v( 'user_id', 'request', 0 ); + if ( $pods_ajax ) { + $current_user_id = (int) pods_v( 'id', 'request', $current_user_id ); + } + + $context['current_item_id'] = $current_user_id; + break; + } - $current_language = pods_sanitize( sanitize_text_field( $current_language ) ); - - if ( ! empty( $current_language ) ) { - // We need to return language data - $lang_data = array( - 'language' => $current_language, - 't_id' => 0, - 'tt_id' => 0, - 'term' => null, - ); - - /** - * Polylang support. - * Get the language taxonomy object for the current language. - */ - if ( 'PLL' === $translator ) { - $current_language_t = false; - - // Get the language term object. - if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) { - // Polylang 1.8 and newer. - $current_language_t = PLL()->model->get_language( $current_language ); - } elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) { - // Polylang 1.2 - 1.7.x - $current_language_t = $polylang->model->get_language( $current_language ); - } elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) { - // Polylang 1.1.x and older. - $current_language_t = $polylang->get_language( $current_language ); - } - - // If the language object exists, add it! - if ( $current_language_t && ! empty( $current_language_t->term_id ) ) { - $lang_data['t_id'] = (int) $current_language_t->term_id; - $lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id; - $lang_data['tl_t_id'] = (int) $current_language_t->tl_term_id; - $lang_data['tl_tt_id'] = (int) $current_language_t->tl_term_taxonomy_id; - $lang_data['term'] = $current_language_t; - } - }//end if - }//end if + }//end if (admin) /** - * Override language data used by Pods. + * Override language context used by Pods. * - * @since 2.6.6 + * @since 2.8.0 * - * @param array|false $lang_data { - * Language data - * @type string $language Language slug - * @type int $t_id Language term_id - * @type int $tt_id Language term_taxonomy_id - * @type WP_Term $term Language term object + * @param array $context { + * Language data. + * @type bool $is_admin Is admin. + * @type bool $is_ajax Is AJAX call. + * @type bool $is_pods_ajax Is Pods AJAX call. + * @type string $current_page Current admin page. + * @type string $current_object_type Current object type (post / term / comment / user). + * @type int $current_item_id Current item id. + * @type string $current_item_type Current item type. * } - * - * @param string|boolean $translator Language plugin used. */ - $lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator ); - - if ( $lang_data ) { - self::$current_language = $lang_data['language']; - self::$current_language_data = $lang_data; - } + self::$current_language_context = apply_filters( 'pods_get_current_language_context', $context ); - return $lang_data; - - } - - /** - * Add Pods templates to possible i18n enabled post-types (polylang settings). - * - * @since 2.7.0 - * - * @param array $post_types - * @param bool $is_settings - * - * @return array mixed - */ - public function pll_get_post_types( $post_types, $is_settings = false ) { - - if ( $is_settings ) { - $post_types['_pods_template'] = '_pods_template'; - } + return self::$current_language_context; - return $post_types; } } diff --git a/classes/PodsInit.php b/classes/PodsInit.php index a837d1a459..c33c17644e 100644 --- a/classes/PodsInit.php +++ b/classes/PodsInit.php @@ -1,5 +1,7 @@ needs_upgrade(); - add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) ); - add_action( 'plugins_loaded', array( $this, 'activate_install' ), 9 ); - add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) ); + add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 0 ); + add_action( 'plugins_loaded', [ $this, 'activate_install' ], 9 ); + add_action( 'after_setup_theme', [ $this, 'after_setup_theme' ] ); + add_action( 'wp_loaded', [ $this, 'flush_rewrite_rules' ] ); + + // Setup common info for after TEC/ET load. + add_action( 'plugins_loaded', [ $this, 'maybe_set_common_lib_info' ], 1 ); + add_action( 'tribe_common_loaded', [ $this, 'run' ], 0 ); + } + + /** + * Setup of Common Library. + * + * @since 2.8.0 + */ + public function maybe_set_common_lib_info() { + // Set up the path for /tribe-common/ loading. + $common_version = file_get_contents( PODS_DIR . 'tribe-common/src/Tribe/Main.php' ); + + // If there isn't a tribe-common version, bail. + if ( ! preg_match( "/const\s+VERSION\s*=\s*'([^']+)'/m", $common_version, $matches ) ) { + add_action( 'admin_head', [ $this, 'missing_common_libs' ] ); + + return; + } + + $common_version = $matches[1]; + + /** + * Attempt to load our Common if it's not already loaded. + */ + if ( empty( $GLOBALS['tribe-common-info'] ) ) { + /** + * Custom tribe-common package: + * + * - Removed /vendor/freemius/ folder. + * - Removed /lang/ folder (for now). + * - Removed /src/resources/ folder (for now). + */ + $solo_install = empty( $GLOBALS['tribe-common-info'] ); + + // Handle stopping anything we don't want to run in Tribe Common. + if ( $solo_install ) { + // Bypass Tribe-related options. + $tribe_options = [ + 'tribe_settings_errors', + 'pue_install_key_promoter', + 'tribe_pue_key_notices', + 'tribe_events_calendar_options', + 'tribe_settings_major_error', + 'tribe_settings_sent_data', + 'tribe_events_calendar_network_options', + ]; + + $tribe_empty_options = [ + 'pue_install_key_promoter', + 'tribe_settings_major_error', + '_tribe_admin_notices', + ]; + + foreach ( $tribe_options as $option_name ) { + $return_third_param = static function() { + return func_get_arg( 2 ); + }; + $return_fourth_param = static function() { + return func_get_arg( 3 ); + }; + + add_filter( "pre_option_{$option_name}", $return_third_param, 10, 3 ); + add_filter( "pre_site_option_{$option_name}", $return_fourth_param, 10, 4 ); + } + + foreach ( $tribe_empty_options as $option_name ) { + add_filter( "pre_option_{$option_name}", '__return_null' ); + add_filter( "pre_site_option_{$option_name}", '__return_null' ); + add_filter( "pre_transient_{$option_name}", '__return_null' ); + } + + // Remove hooks that are added and run before we can remove them. + add_action( 'tribe_common_loaded', static function() { + $main = Tribe__Main::instance(); + + remove_action( 'tribe_common_loaded', [ $main, 'load_assets' ], 1 ); + remove_action( 'plugins_loaded', [ $main, 'tribe_plugins_loaded' ], PHP_INT_MAX ); + remove_filter( 'body_class', [ $main, 'add_js_class' ] ); + remove_action( 'wp_footer', [ $main, 'toggle_js_class' ] ); + }, 0 ); + + if ( ! defined( 'TRIBE_HIDE_MARKETING_NOTICES' ) ) { + define( 'TRIBE_HIDE_MARKETING_NOTICES', true ); + } + } + + $GLOBALS['tribe-common-info'] = [ + 'dir' => PODS_DIR . 'tribe-common/src/Tribe', + 'version' => $common_version, + ]; + + /** + * After this method we can use any `Tribe__` and `\Pods\...` classes + */ + $this->init_autoloading(); + + // Start up Common. + $main = Tribe__Main::instance(); + $main->plugins_loaded(); - add_action( 'wp_loaded', array( $this, 'flush_rewrite_rules' ) ); + // Handle anything we want to unhook/stop in Tribe Common. + if ( $solo_install ) { + // Look into any others here. + remove_action( 'plugins_loaded', [ 'Tribe__App_Shop', 'instance' ] ); + remove_action( 'plugins_loaded', [ 'Tribe__Admin__Notices', 'instance' ], 1 ); - $this->run(); + /** @var Tribe__Assets $assets */ + $assets = tribe( 'assets' ); + $assets->remove( 'tribe-tooltip' ); + /** @var Tribe__Asset__Data $asset_data */ + $asset_data = tribe( 'asset.data' ); + + remove_action( 'admin_footer', [ $asset_data, 'render_json' ] ); + remove_action( 'customize_controls_print_footer_scripts', [ $asset_data, 'render_json' ] ); + remove_action( 'wp_footer', [ $asset_data, 'render_json' ] ); + + /** @var Tribe__Assets_Pipeline $assets_pipeline */ + $assets_pipeline = tribe( 'assets.pipeline' ); + remove_filter( 'script_loader_tag', [ $assets_pipeline, 'prevent_underscore_conflict' ] ); + } + } + } + + /** + * Display a missing-tribe-common library error. + * + * @since 2.8.0 + */ + public function missing_common_libs() { + ?> +
+

+ +

+
+ PODS_DIR . 'classes/cli/Pods_CLI_Command.php', + 'PodsAPI_CLI_Command' => PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php', + ); + + if ( isset( $custom[ $class ] ) ) { + $path = $custom[ $class ]; + + require_once $path; + + return; + } + + $loaders = array( + array( + 'prefix' => 'Pods', + 'separator' => '\\', // Namespace + 'path' => PODS_DIR . 'src', + ), + array( + 'prefix' => 'PodsField_', + 'filter' => 'strtolower', + 'exclude_prefix' => true, + 'path' => PODS_DIR . 'classes/fields', + ), + array( + 'prefix' => 'PodsWidget', + 'path' => PODS_DIR . 'classes/widgets', + ), + array( + 'prefix' => 'Pods', + 'path' => PODS_DIR . 'classes', + ), + ); + + foreach ( $loaders as $loader ) { + if ( 0 !== strpos( $class, $loader['prefix'] ) ) { + continue; + } + + $path = array( + $loader['path'], + ); + + if ( ! empty( $loader['exclude_prefix'] ) ) { + $class = substr( $class, strlen( $loader['prefix'] ) ); + } + + if ( ! empty( $loader['filter'] ) ) { + $class = call_user_func( $loader['filter'], $class ); + } + + if ( ! isset( $loader['separator'] ) ) { + $path[] = $class; + } else { + $separated_path = explode( $loader['separator'], $class ); + + /** @noinspection SlowArrayOperationsInLoopInspection */ + $path = array_merge( $path, $separated_path ); + } + + $path = implode( DIRECTORY_SEPARATOR, $path ) . '.php'; + + if ( file_exists( $path ) ) { + require_once $path; + + break; + } + } } /** * Load the plugin textdomain and set default constants */ public function plugins_loaded() { - if ( ! defined( 'PODS_LIGHT' ) ) { define( 'PODS_LIGHT', false ); } @@ -158,85 +395,168 @@ public function plugins_loaded() { define( 'PODS_TABLELESS', false ); } - load_plugin_textdomain( 'pods' ); - - $this->freemius(); + if ( ! defined( 'PODS_TEXTDOMAIN' ) || PODS_TEXTDOMAIN ) { + load_plugin_textdomain( 'pods' ); + } + if ( ! defined( 'PODS_STATS_TRACKING' ) || PODS_STATS_TRACKING ) { + $this->stats_tracking( PODS_FILE, 'pods' ); + } } /** - * Handle Freemius SDK registration. + * Handle Stats Tracking. + * + * @since 2.8.0 * - * @since 1.0.0 + * @param string $plugin_file The plugin file. + * @param string $plugin_slug The plugin slug. * - * @return \Freemius + * @return Wisdom_Tracker The Stats Tracking object. */ - public function freemius() { + public function stats_tracking( $plugin_file, $plugin_slug ) { // Admin only. - if ( ! is_admin() ) { + if ( + ! is_admin() + && ! wp_doing_cron() + ) { return; } global $pagenow; + $is_pods_page = isset( $_GET['page'] ) && 0 === strpos( $_GET['page'], 'pods' ); + // Pods admin pages or plugins/update page only. if ( 'plugins.php' !== $pagenow && 'update-core.php' !== $pagenow && 'update.php' !== $pagenow && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) - && ( ! isset( $_GET['page'] ) || 0 !== strpos( $_GET['page'], 'pods' ) ) + && ! $is_pods_page + && ! wp_doing_cron() ) { return; } - if ( $this->freemius ) { - return $this->freemius; - } - - require_once dirname( __DIR__ ) . '/vendor/freemius/wordpress-sdk/start.php'; - - try { - $this->freemius = fs_dynamic_init( array( - 'id' => '5347', - 'slug' => 'pods', - 'type' => 'plugin', - 'public_key' => 'pk_737105490825babae220297e18920', - 'is_premium' => false, - 'has_addons' => false, - 'has_paid_plans' => false, - 'menu' => array( - 'slug' => 'pods-settings', - 'contact' => false, - 'support' => false, - 'affiliation' => false, - 'account' => true, - 'pricing' => false, - 'addons' => false, - 'parent' => array( - 'slug' => 'pods', - ), - ), - ) ); + $is_main_plugin = PODS_FILE === $plugin_file; + + if ( $is_main_plugin && $this->stats_tracking ) { + return $this->stats_tracking; + } + + $settings = []; + + if ( $is_main_plugin ) { + $settings[] = 'pods_settings'; + } + + $stats_tracking = new Wisdom_Tracker( + $plugin_file, + $plugin_slug, + 'https://stats.pods.io', + $settings, + true, + true, + 1 + ); + + if ( $is_main_plugin ) { + add_action( 'update_option_wisdom_allow_tracking', static function ( $old_value, $value ) use ( $plugin_slug ) { + $opt_out = ! empty( $value[ $plugin_slug ] ) ? 0 : 1; + + pods_update_setting( 'wisdom_opt_out', $opt_out ); + }, 10, 2 ); + } + + add_action( 'update_option_pods_settings', static function ( $old_value, $value ) use ( $stats_tracking, $plugin_slug ) { + // Only handle opt in when needed. + if ( ! isset( $value['wisdom_opt_out'] ) || 0 !== (int) $value['wisdom_opt_out'] ) { + return; + } + + // We are doing opt-in> + $stats_tracking->set_is_tracking_allowed( true, $plugin_slug ); + $stats_tracking->set_can_collect_email( true, $plugin_slug ); + }, 10, 2 ); + + add_filter( 'wisdom_is_local_' . $plugin_slug, static function ( $is_local = false ) { + if ( true === $is_local ) { + return $is_local; + } - $this->override_freemius_strings(); + $url = network_site_url( '/' ); - add_filter( 'fs_plugins_api', array( $this, 'filter_freemius_plugins_api_data' ), 15 ); + $url = strtolower( trim( $url ) ); + $url_parts = parse_url( $url ); + $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false; - $this->freemius->add_filter( 'templates/add-ons.php', array( $this, 'filter_freemius_addons_html' ) ); - $this->freemius->add_filter( 'download_latest_url', array( $this, 'get_freemius_action_link' ) ); + if ( empty( $host ) ) { + return $is_local; + } + + if ( 'localhost' === $host ) { + return true; + } + + if ( false !== ip2long( $host ) && ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { + return true; + } + + $tlds_to_check = [ + '.local', + '.test', + ]; + + foreach ( $tlds_to_check as $tld ) { + $minus_tld = strlen( $host ) - strlen( $tld ); + + if ( $minus_tld === strpos( $host, $tld ) ) { + return true; + } + } + + return $is_local; + } ); + + add_filter( 'wisdom_notice_text_' . $plugin_slug, static function() { + return __( 'Thank you for installing our plugin. We\'d like your permission to track its usage on your site. We won\'t record any sensitive data, only information regarding the WordPress environment, your site admin email address, and plugin settings. We will only use this information help us make improvements to the plugin and provide better support when you reach out. Tracking is completely optional.', 'pods' ); + } ); + // Handle non-Pods pages, we don't want certain things happening. + if ( ! $is_pods_page ) { + remove_action( 'admin_notices', [ $stats_tracking, 'optin_notice' ] ); + remove_action( 'admin_notices', [ $stats_tracking, 'marketing_notice' ] ); + } + + if ( ! $is_main_plugin ) { /** - * Allow hooking into the Freemius registration after Pods has registered it's own Freemius. + * Allow hooking after the Stats Tracking object is setup for the main plugin. * - * @since 2.7.27 + * @since 2.8.0 + * + * @param Wisdom_Tracker $stats_tracking The Stats Tracking object. + * @param string $plugin_file The plugin file. */ - do_action( 'pods_freemius_after_init' ); - } catch ( \Exception $exception ) { - return null; + do_action( 'pods_stats_tracking_after_init', $stats_tracking, $plugin_file ); } - return $this->freemius; + /** + * Allow hooking after the Stats Tracking object is setup. + * + * @since 2.8.0 + * + * @param Wisdom_Tracker $stats_tracking The Stats Tracking object. + * @param string $plugin_file The plugin file. + */ + do_action( 'pods_stats_tracking_object', $stats_tracking, $plugin_file ); + + // Maybe store the object. + if ( $is_main_plugin ) { + $this->stats_tracking = $stats_tracking; + } + + return $stats_tracking; } /** @@ -353,13 +673,41 @@ public function get_freemius_friends_addons() { ); } + /** + * Sets up autoloading. + * + * @since 2.8.0 + */ + protected function init_autoloading() { + $autoloader = $this->get_autoloader_instance(); + $autoloader->register_autoloader(); + } + + /** + * Returns the autoloader singleton instance to use in a context-aware manner. + * + * @since 2.8.0 + * + * @return \Tribe__Autoloader The singleton common Autoloader instance. + */ + public function get_autoloader_instance() { + if ( ! class_exists( 'Tribe__Autoloader' ) ) { + require_once $GLOBALS['tribe-common-info']['dir'] . '/Autoloader.php'; + + Tribe__Autoloader::instance()->register_prefixes( [ + 'Tribe__' => $GLOBALS['tribe-common-info']['dir'], + ] ); + } + + return Tribe__Autoloader::instance(); + } + /** * Add compatibility for other plugins. * * @since 2.7.17 */ public function after_setup_theme() { - if ( ! defined( 'PODS_COMPATIBILITY' ) ) { define( 'PODS_COMPATIBILITY', true ); } @@ -369,7 +717,6 @@ public function after_setup_theme() { } require_once PODS_DIR . 'includes/compatibility/acf.php'; - } /** @@ -391,8 +738,9 @@ public function load_components() { * Load Pods Meta */ public function load_meta() { + self::$meta = pods_meta(); - self::$meta = pods_meta()->core(); + self::$meta->core(); } /** @@ -419,21 +767,14 @@ public function core() { add_shortcode( 'pods-form', 'pods_shortcode_form' ); $security_settings = array( - 'pods_disable_file_browser' => 0, - 'pods_files_require_login' => 1, + 'pods_disable_file_browser' => false, + 'pods_files_require_login' => true, 'pods_files_require_login_cap' => '', - 'pods_disable_file_upload' => 0, - 'pods_upload_require_login' => 1, + 'pods_disable_file_upload' => false, + 'pods_upload_require_login' => true, 'pods_upload_require_login_cap' => '', ); - foreach ( $security_settings as $security_setting => $setting ) { - $setting = get_option( $security_setting ); - if ( ! empty( $setting ) ) { - $security_settings[ $security_setting ] = $setting; - } - } - foreach ( $security_settings as $security_setting => $setting ) { if ( 0 === (int) $setting ) { $setting = false; @@ -481,6 +822,13 @@ public function core() { * Register Scripts and Styles */ public function register_assets() { + static $registered = false; + + if ( $registered ) { + return; + } + + $registered = true; $suffix_min = SCRIPT_DEBUG ? '' : '.min'; @@ -596,7 +944,7 @@ public function register_assets() { // Marionette dependencies for DFV/MV fields. wp_register_script( - 'backbone.radio', + 'pods-backbone-radio', PODS_URL . "ui/js/marionette/backbone.radio{$suffix_min}.js", array( 'backbone' ), '2.0.0', @@ -607,7 +955,7 @@ public function register_assets() { PODS_URL . "ui/js/marionette/backbone.marionette{$suffix_min}.js", array( 'backbone', - 'backbone.radio', + 'pods-backbone-radio', ), '3.3.1', true @@ -617,22 +965,56 @@ public function register_assets() { 'PodsMn = Backbone.Marionette.noConflict();' ); - // DFV/MV. + // Dynamic Field Views / Marionette Views scripts. + $pods_dfv_options_file = file_get_contents( PODS_DIR . 'ui/js/dfv/pods-dfv.min.asset.json' ); + + $pods_dfv_options = json_decode( $pods_dfv_options_file, true ); + wp_register_script( - 'pods-dfv', PODS_URL . 'ui/js/pods-dfv/pods-dfv.min.js', - array( - 'jquery', - 'jquery-ui-core', - 'jquery-ui-sortable', - 'pods-i18n', - 'pods-marionette', - 'media-views', - 'media-models', + 'pods-dfv', + PODS_URL . 'ui/js/dfv/pods-dfv.min.js', + array_merge( + $pods_dfv_options['dependencies'], + [ + 'jquery', + 'jquery-ui-core', + 'jquery-ui-sortable', + 'pods-marionette', + 'media-views', + 'media-models', + 'wp-components', + 'wp-block-library', + 'wp-tinymce', + ] ), - PODS_VERSION, + $pods_dfv_options['version'], true ); + wp_set_script_translations( 'pods-dfv', 'pods' ); + + $config = [ + 'wp_locale' => $GLOBALS['wp_locale'], + 'currencies' => PodsField_Currency::$currencies, + 'datetime' => [ + 'start_of_week' => (int) get_option( 'start_of_week', 0 ), + 'gmt_offset' => (int) get_option( 'gmt_offset', 0 ), + 'date_format' => get_option( 'date_format' ), + 'time_format' => get_option( 'time_format' ), + ], + ]; + + /** + * Allow filtering hte admin config data. + * + * @since 2.8.0 + * + * @param array $config The admin config data. + */ + $config = apply_filters( 'pods_admin_dfv_config', $config ); + + wp_localize_script( 'pods-dfv', 'podsDFVConfig', $config ); + // Page builders. if ( // @todo Finish Elementor & Divi support. @@ -643,29 +1025,35 @@ public function register_assets() { add_filter( 'pods_enqueue_dfv_on_front', '__return_true' ); } - // Check if Pod is a Modal Window. - if ( pods_is_modal_window() ) { - add_filter( 'body_class', array( $this, 'add_classes_to_modal_body' ) ); - add_filter( 'admin_body_class', array( $this, 'add_classes_to_modal_body' ) ); - } + $is_admin = is_admin(); // Deal with specifics on admin pages. - if ( is_admin() && function_exists( 'get_current_screen' ) ) { + if ( $is_admin && function_exists( 'get_current_screen' ) ) { $screen = get_current_screen(); // DFV must be enqueued on the media library page for items in grid mode (#4785) // and for posts due to the possibility that post-thumbnails are enabled (#4945) - if ( $screen && $screen->base && in_array( $screen->base, array( 'upload', 'post' ), true ) ) { - wp_enqueue_script( 'pods-dfv' ); + if ( + $screen + && $screen->base + && in_array( $screen->base, [ + 'upload', + 'post', + ], true ) + ) { + // Only load if we have a media pod. + if ( ! empty( PodsMeta::$media ) ) { + wp_enqueue_script( 'pods-dfv' ); + } } } $this->maybe_register_handlebars(); // As of 2.7 we combine styles to just three .css files - wp_register_style( 'pods-styles', PODS_URL . 'ui/styles/dist/pods.css', array(), PODS_VERSION ); - wp_register_style( 'pods-wizard', PODS_URL . 'ui/styles/dist/pods-wizard.css', array(), PODS_VERSION ); - wp_register_style( 'pods-form', PODS_URL . 'ui/styles/dist/pods-form.css', array(), PODS_VERSION ); + wp_register_style( 'pods-styles', PODS_URL . 'ui/styles/dist/pods.css', [ 'wp-components' ], PODS_VERSION ); + wp_register_style( 'pods-wizard', PODS_URL . 'ui/styles/dist/pods-wizard.css', [], PODS_VERSION ); + wp_register_style( 'pods-form', PODS_URL . 'ui/styles/dist/pods-form.css', [ 'wp-components' ], PODS_VERSION ); /** * Filter to enabled loading of the DFV script on frontend. @@ -677,11 +1065,19 @@ public function register_assets() { * * @since 2.7.13 */ - if ( apply_filters( 'pods_enqueue_dfv_on_front', false ) ) { + if ( ! $is_admin && apply_filters( 'pods_enqueue_dfv_on_front', false ) ) { wp_enqueue_script( 'pods-dfv' ); wp_enqueue_style( 'pods-form' ); } + // Check if Pod is a Modal Window. + if ( pods_is_modal_window() ) { + add_filter( 'body_class', array( $this, 'add_classes_to_modal_body' ) ); + add_filter( 'admin_body_class', array( $this, 'add_classes_to_modal_body' ) ); + + wp_enqueue_style( 'pods-styles' ); + } + /** * Fires after Pods assets are registered. * @@ -735,10 +1131,9 @@ public function add_classes_to_modal_body( $classes ) { * Register internal Post Types */ public function register_pods() { - $args = array( - 'label' => 'Pods', - 'labels' => array( 'singular_name' => 'Pod' ), + 'label' => __( 'Pods', 'pods' ), + 'labels' => array( 'singular_name' => __( 'Pod', 'pods' ) ), 'public' => false, 'can_export' => false, 'query_var' => false, @@ -755,8 +1150,26 @@ public function register_pods() { register_post_type( '_pods_pod', apply_filters( 'pods_internal_register_post_type_pod', $args ) ); $args = array( - 'label' => 'Pod Fields', - 'labels' => array( 'singular_name' => 'Pod Field' ), + 'label' => __( 'Pod Groups', 'pods' ), + 'labels' => array( 'singular_name' => __( 'Pod Group', 'pods' ) ), + 'public' => false, + 'can_export' => false, + 'query_var' => false, + 'rewrite' => false, + 'capability_type' => 'pods_pod', + 'has_archive' => false, + 'hierarchical' => true, + 'supports' => array( 'title', 'editor', 'author' ), + 'menu_icon' => 'dashicons-pods', + ); + + $args = self::object_label_fix( $args, 'post_type' ); + + register_post_type( '_pods_group', apply_filters( 'pods_internal_register_post_type_group', $args ) ); + + $args = array( + 'label' => __( 'Pod Fields', 'pods' ), + 'labels' => array( 'singular_name' => __( 'Pod Field', 'pods' ) ), 'public' => false, 'can_export' => false, 'query_var' => false, @@ -792,9 +1205,6 @@ public function setup_content_types( $force = false ) { return; } - require_once PODS_DIR . 'classes/PodsRESTHandlers.php'; - require_once PODS_DIR . 'classes/PodsRESTFields.php'; - $post_types = PodsMeta::$post_types; $taxonomies = PodsMeta::$taxonomies; @@ -853,9 +1263,6 @@ public function setup_content_types( $force = false ) { continue; } - $post_type['options']['name'] = $post_type['name']; - $post_type = array_merge( $post_type, (array) $post_type['options'] ); - $post_type_name = pods_v_sanitized( 'name', $post_type ); // Labels @@ -1016,6 +1423,7 @@ public function setup_content_types( $force = false ) { 'rewrite' => $cpt_rewrite, 'query_var' => ( false !== (boolean) pods_v( 'query_var', $post_type, true ) ? pods_v( 'query_var_string', $post_type, $post_type_name, true ) : false ), 'can_export' => (boolean) pods_v( 'can_export', $post_type, true ), + 'delete_with_user' => (boolean) pods_v( 'delete_with_user', $post_type, true ), ); // REST API @@ -1054,7 +1462,7 @@ public function setup_content_types( $force = false ) { // Taxonomies $cpt_taxonomies = array(); - $_taxonomies = get_taxonomies(); + $_taxonomies = $existing_taxonomies; $_taxonomies = array_merge_recursive( $_taxonomies, $pods_taxonomies ); $ignore = array( 'nav_menu', 'link_category', 'post_format' ); @@ -1091,9 +1499,6 @@ public function setup_content_types( $force = false ) { continue; } - $taxonomy['options']['name'] = $taxonomy['name']; - $taxonomy = array_merge( $taxonomy, (array) $taxonomy['options'] ); - $taxonomy_name = pods_v( 'name', $taxonomy ); // Labels @@ -1223,7 +1628,7 @@ public function setup_content_types( $force = false ) { // Post Types $ct_post_types = array(); - $_post_types = get_post_types(); + $_post_types = $existing_post_types; $_post_types = array_merge_recursive( $_post_types, $pods_post_types ); $ignore = array( 'revision' ); @@ -1277,7 +1682,7 @@ public function setup_content_types( $force = false ) { $pods_cpt_ct['post_format_post_types'] = $post_format_post_types; - pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct ); + pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct, WEEK_IN_SECONDS ); }//end if foreach ( $pods_cpt_ct['taxonomies'] as $taxonomy => $options ) { @@ -1389,30 +1794,25 @@ public function setup_content_types( $force = false ) { // Handle existing post types / taxonomies settings (just REST for now) global $wp_post_types, $wp_taxonomies; - $post_type_names = wp_list_pluck( $post_types, 'name', 'id' ); - $taxonomy_names = wp_list_pluck( $taxonomies, 'name', 'id' ); - foreach ( $existing_post_types as $post_type_name => $post_type_name_again ) { if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type_name, self::$content_types_registered['post_types'], true ) ) { // Post type already registered / setup by Pods continue; } - $pod_id = array_search( $post_type_name, $post_type_names, true ); - - if ( ! $pod_id ) { + if ( ! isset( $post_types[ $post_type_name ] ) ) { // Post type not a pod continue; } - $pod = $post_types[ $pod_id ]; + $pod = $post_types[ $post_type_name ]; // REST API - $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false ); + $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false ); if ( $rest_enabled ) { if ( empty( $wp_post_types[ $post_type_name ]->show_in_rest ) ) { - $rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_post_types[ $post_type_name ] ), true ) ); + $rest_base = sanitize_title( pods_v( 'rest_base', $pod, pods_v( 'rest_base', $wp_post_types[ $post_type_name ] ), true ) ); $wp_post_types[ $post_type_name ]->show_in_rest = true; $wp_post_types[ $post_type_name ]->rest_base = $rest_base; @@ -1429,21 +1829,19 @@ public function setup_content_types( $force = false ) { continue; } - $pod_id = array_search( $taxonomy_name, $taxonomy_names, true ); - - if ( ! $pod_id ) { + if ( ! isset( $taxonomies[ $taxonomy_name ] ) ) { // Taxonomy not a pod continue; } - $pod = $taxonomies[ $pod_id ]; + $pod = $taxonomies[ $taxonomy_name ]; // REST API - $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false ); + $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false ); if ( $rest_enabled ) { if ( empty( $wp_taxonomies[ $taxonomy_name ]->show_in_rest ) ) { - $rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_taxonomies[ $taxonomy_name ] ), true ) ); + $rest_base = sanitize_title( pods_v( 'rest_base', $pod, pods_v( 'rest_base', $wp_taxonomies[ $taxonomy_name ] ), true ) ); $wp_taxonomies[ $taxonomy_name ]->show_in_rest = true; $wp_taxonomies[ $taxonomy_name ]->rest_base = $rest_base; @@ -1457,7 +1855,7 @@ public function setup_content_types( $force = false ) { if ( ! empty( PodsMeta::$user ) ) { $pod = current( PodsMeta::$user ); - $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false ); + $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false ); if ( $rest_enabled ) { new PodsRESTFields( $pod['name'] ); @@ -1467,13 +1865,25 @@ public function setup_content_types( $force = false ) { if ( ! empty( PodsMeta::$media ) ) { $pod = current( PodsMeta::$media ); - $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false ); + $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false ); if ( $rest_enabled ) { new PodsRESTFields( $pod['name'] ); } } + do_action( 'pods_setup_content_types' ); + + if ( ! did_action( 'pods_init' ) ) { + /** + * Allow hooking into after Pods has been setup. + * + * @since 2.8.0 + * + * @param PodsInit $init The PodsInit class object. + */ + do_action( 'pods_init', $this ); + } } /** @@ -1497,7 +1907,7 @@ public function flush_rewrite_rules() { $wp_rewrite->flush_rules(); $wp_rewrite->init(); - pods_transient_set( 'pods_flush_rewrites', 0 ); + pods_transient_clear( 'pods_flush_rewrites' ); } } @@ -1760,7 +2170,7 @@ public function needs_upgrade( $current = null, $last = null ) { if ( '2.1.0' === $new_version && ( is_developer() ) ) continue;*/ - if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 !== self::$upgraded ) { + if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 !== self::$upgraded && 2 !== self::$upgraded ) { $upgrade_needed = true; break; @@ -1885,12 +2295,7 @@ public function reset( $_blog_id = null ) { $api = pods_api(); - $pods = $api->load_pods( - array( - 'names_ids' => true, - 'table_info' => false, - ) - ); + $pods = $api->load_pods( array( 'names_ids' => true ) ); foreach ( $pods as $pod_id => $pod_label ) { $api->delete_pod( array( 'id' => $pod_id ) ); @@ -1970,6 +2375,20 @@ public function run() { $ran = true; + tribe_register_provider( \Pods\Service_Provider::class ); + tribe_register_provider( \Pods\Admin\Service_Provider::class ); + tribe_register_provider( \Pods\Blocks\Service_Provider::class ); + tribe_register_provider( \Pods\Integrations\Service_Provider::class ); + tribe_register_provider( \Pods\REST\V1\Service_Provider::class ); + + // Add WP-CLI commands. + if ( defined( 'WP_CLI' ) && WP_CLI ) { + //require_once PODS_DIR . 'classes/cli/Pods_CLI_Command.php'; + //require_once PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php'; + + tribe_register_provider( \Pods\CLI\Service_Provider::class ); + } + $this->load_i18n(); if ( ! did_action( 'plugins_loaded' ) ) { @@ -1984,25 +2403,32 @@ public function run() { $this->load_meta(); } + $is_admin = is_admin(); + if ( ! did_action( 'init' ) ) { add_action( 'init', array( $this, 'core' ), 11 ); add_action( 'init', array( $this, 'setup_content_types' ), 11 ); - if ( is_admin() ) { + if ( $is_admin ) { add_action( 'init', array( $this, 'admin_init' ), 12 ); } } else { $this->core(); $this->setup_content_types(); - if ( is_admin() ) { + if ( $is_admin ) { $this->admin_init(); } } - add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ), 15 ); - add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ), 15 ); + if ( ! $is_admin ) { + add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ], 15 ); + } else { + add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ], 15 ); + } + add_action( 'login_enqueue_scripts', array( $this, 'register_assets' ), 15 ); + // @todo Elementor Page Builder. //add_action( 'elementor/editor/before_enqueue_scripts', array( $this, 'register_assets' ), 15 ); @@ -2021,12 +2447,32 @@ public function run() { // Compatibility for Query Monitor conditionals add_filter( 'query_monitor_conditionals', array( $this, 'filter_query_monitor_conditionals' ) ); - // Add WP-CLI commands - if ( defined( 'WP_CLI' ) && WP_CLI ) { - require_once PODS_DIR . 'classes/cli/Pods_CLI_Command.php'; - require_once PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php'; + // Remove Common menus + add_action( 'admin_menu', array( $this, 'remove_common_menu' ), 11 ); + add_action( 'network_admin_menu', array( $this, 'remove_common_network_menu' ), 11 ); + } + + /** + * Remove Common menu. + * + * @since 2.8.0 + */ + public function remove_common_menu() { + if ( ! class_exists( 'Tribe__Events__Main' ) && ! class_exists( 'Tribe__Tickets__Main' ) ) { + remove_menu_page( 'tribe-common' ); } + } + /** + * Remove Common network menu. + * + * @since 2.8.0 + */ + public function remove_common_network_menu() { + if ( ! class_exists( 'Tribe__Events__Main' ) && ! class_exists( 'Tribe__Tickets__Main' ) ) { + remove_submenu_page( 'settings.php', 'tribe-common' ); + remove_submenu_page( 'settings.php', 'tribe-common-help' ); + } } /** @@ -2044,7 +2490,7 @@ public function delete_attachment( $_ID ) { $file_types = "'" . implode( "', '", PodsForm::file_field_types() ) . "'"; - if ( ! pods_tableless() ) { + if ( pods_podsrel_enabled() ) { $sql = " DELETE `rel` FROM `@wp_podsrel` AS `rel` @@ -2060,14 +2506,16 @@ public function delete_attachment( $_ID ) { WHERE `p`.`ID` IS NOT NULL AND `pm`.`meta_id` IS NOT NULL - AND `rel`.`item_id` = {$_ID}"; + AND `rel`.`item_id` = {$_ID} + "; pods_query( $sql, false ); } - // Post Meta - if ( ! empty( PodsMeta::$post_types ) ) { - $sql = " + if ( pods_relationship_meta_storage_enabled() ) { + // Post Meta + if ( ! empty( PodsMeta::$post_types ) ) { + $sql = " DELETE `rel` FROM `@wp_postmeta` AS `rel` LEFT JOIN `{$wpdb->posts}` AS `p` @@ -2084,12 +2532,12 @@ public function delete_attachment( $_ID ) { AND `rel`.`meta_key` = `p`.`post_name` AND `rel`.`meta_value` = '{$_ID}'"; - pods_query( $sql, false ); - } + pods_query( $sql, false ); + } - // User Meta - if ( ! empty( PodsMeta::$user ) ) { - $sql = " + // User Meta + if ( ! empty( PodsMeta::$user ) ) { + $sql = " DELETE `rel` FROM `@wp_usermeta` AS `rel` LEFT JOIN `{$wpdb->posts}` AS `p` @@ -2106,12 +2554,12 @@ public function delete_attachment( $_ID ) { AND `rel`.`meta_key` = `p`.`post_name` AND `rel`.`meta_value` = '{$_ID}'"; - pods_query( $sql, false ); - } + pods_query( $sql, false ); + } - // Comment Meta - if ( ! empty( PodsMeta::$comment ) ) { - $sql = " + // Comment Meta + if ( ! empty( PodsMeta::$comment ) ) { + $sql = " DELETE `rel` FROM `@wp_commentmeta` AS `rel` LEFT JOIN `{$wpdb->posts}` AS `p` @@ -2128,8 +2576,18 @@ public function delete_attachment( $_ID ) { AND `rel`.`meta_key` = `p`.`post_name` AND `rel`.`meta_value` = '{$_ID}'"; - pods_query( $sql, false ); + pods_query( $sql, false ); + } } + + /** + * Allow hooking into the attachment deletion process. + * + * @since 2.8.0 + * + * @param int $_ID The attachment ID being deleted. + */ + do_action( 'pods_init_delete_attachment', $_ID ); } /** @@ -2150,7 +2608,6 @@ public function register_widgets() { continue; } - require_once PODS_DIR . 'classes/widgets/' . $widget . '.php'; register_widget( $widget ); } @@ -2167,17 +2624,11 @@ public function admin_bar_links() { return; } - $all_pods = pods_api()->load_pods( - array( - 'type' => 'pod', - 'fields' => false, - 'table_info' => false, - ) - ); + $all_pods = pods_api()->load_pods( array( 'type' => 'pod' ) ); // Add New item links for all pods foreach ( $all_pods as $pod ) { - if ( 0 === (int) $pod['options']['show_in_menu'] ) { + if ( ! isset( $pod['show_in_menu'] ) || 0 === (int) $pod['show_in_menu'] ) { continue; } @@ -2185,7 +2636,7 @@ public function admin_bar_links() { continue; } - $singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true ); + $singular_label = pods_v( 'label_singular', $pod, pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true ); $wp_admin_bar->add_node( array( @@ -2202,7 +2653,7 @@ public function admin_bar_links() { $pod = $pods->pod_data; if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) { - $singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true ); + $singular_label = pods_v( 'label_singular', $pod, pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true ); $wp_admin_bar->add_node( array( @@ -2266,6 +2717,7 @@ public function filter_query_monitor_conditionals( $conditionals ) { $conditionals[] = 'pods_allow_deprecated'; $conditionals[] = 'pods_api_cache'; $conditionals[] = 'pods_shortcode_allow_evaluate_tags'; + $conditionals[] = 'pods_session_auto_start'; return $conditionals; } } diff --git a/classes/PodsMeta.php b/classes/PodsMeta.php index 2151f73b41..3b7599fa2f 100644 --- a/classes/PodsMeta.php +++ b/classes/PodsMeta.php @@ -1,5 +1,7 @@ cache_pods( false ); - self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod' ) ); - self::$post_types = pods_api()->load_pods( array( 'type' => 'post_type' ) ); - self::$taxonomies = pods_api()->load_pods( array( 'type' => 'taxonomy' ) ); - self::$media = pods_api()->load_pods( array( 'type' => 'media' ) ); - self::$user = pods_api()->load_pods( array( 'type' => 'user' ) ); - self::$comment = pods_api()->load_pods( array( 'type' => 'comment' ) ); - self::$settings = pods_api()->load_pods( array( 'type' => 'settings' ) ); - - // Handle Post Type Editor (needed for Pods core) - - // Loop through and add meta boxes for individual types (can't use this, Tabify doesn't pick it up) - /* - foreach ( self::$post_types as $post_type ) { - $post_type_name = $post_type[ 'name' ]; + $core_loader_objects = pods_transient_get( 'pods_core_loader_objects' ); - if ( !empty( $post_type[ 'object' ] ) ) - $post_type_name = $post_type[ 'object' ]; - - add_action( 'add_meta_boxes_' . $post_type_name, array( $this, 'meta_post_add' ) ); - } - */ - - add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ); - add_action( 'transition_post_status', array( $this, 'save_post_detect_new' ), 10, 3 ); - add_action( 'save_post', array( $this, 'save_post' ), 10, 3 ); - add_filter( 'wp_insert_post_data', array( $this, 'save_post_track_changed_fields' ), 10, 2 ); - - if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) { - // Handle *_post_meta - if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) { - add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 ); - } + $original_loader_objects = $core_loader_objects; - if ( ! pods_tableless() ) { - add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 ); - add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 ); - add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 ); - } + if ( ! is_array( $core_loader_objects ) ) { + $core_loader_objects = []; } - add_action( 'delete_post', array( $this, 'delete_post' ), 10, 1 ); - - if ( ! empty( self::$taxonomies ) ) { - $has_fields = false; - - // Handle Taxonomy Editor - foreach ( self::$taxonomies as $taxonomy ) { - if ( empty( $taxonomy['fields'] ) ) { - continue; - } - - $has_fields = true; - - $taxonomy_name = $taxonomy['name']; - - if ( ! empty( $taxonomy['object'] ) ) { - $taxonomy_name = $taxonomy['object']; - } + if ( ! isset( $core_loader_objects['taxonomies'] ) ) { + $core_loader_objects['taxonomies'] = []; - add_action( $taxonomy_name . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 ); - add_action( $taxonomy_name . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 ); - } + if ( ! empty( self::$taxonomies ) ) { + foreach ( self::$taxonomies as $taxonomy ) { + if ( $taxonomy instanceof Pod ) { + if ( ! $taxonomy->has_fields() ) { + continue; + } + } elseif ( empty( $taxonomy['fields'] ) ) { + continue; + } - if ( $has_fields ) { - // Handle Term Editor - add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 ); - add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 ); - add_action( 'edit_terms', array( $this, 'save_taxonomy_track_changed_fields' ), 10, 2 ); + $taxonomy_name = $taxonomy['name']; - if ( apply_filters( 'pods_meta_handler', true, 'term' ) ) { - // Handle *_term_meta - if ( apply_filters( 'pods_meta_handler_get', true, 'term' ) ) { - add_filter( 'get_term_metadata', array( $this, 'get_term_meta' ), 10, 4 ); + if ( ! empty( $taxonomy['object'] ) ) { + $taxonomy_name = $taxonomy['object']; } - if ( ! pods_tableless() ) { - add_filter( 'add_term_metadata', array( $this, 'add_term_meta' ), 10, 5 ); - add_filter( 'update_term_metadata', array( $this, 'update_term_meta' ), 10, 5 ); - add_filter( 'delete_term_metadata', array( $this, 'delete_term_meta' ), 10, 5 ); - } + $core_loader_objects['taxonomies'][] = $taxonomy_name; } } } - /** - * Fires after a previously shared taxonomy term is split into two separate terms. - * - * @since 4.2.0 - * - * @param int $term_id ID of the formerly shared term. - * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. - * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. - * @param string $taxonomy Taxonomy for the split term. - */ - add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 ); - - // Handle Delete - add_action( 'delete_term_taxonomy', array( $this, 'delete_taxonomy' ), 10, 1 ); + if ( ! isset( $core_loader_objects['media'] ) ) { + $core_loader_objects['media'] = ! empty( self::$media ); + } - if ( ! empty( self::$media ) ) { - add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ); - add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 ); + if ( ! isset( $core_loader_objects['user'] ) ) { + $core_loader_objects['user'] = ! empty( self::$user ); + } - add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 ); + if ( ! isset( $core_loader_objects['comment'] ) ) { + $core_loader_objects['comment'] = ! empty( self::$comment ); + } - add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 ); - add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 ); - add_filter( 'wp_insert_attachment_data', array( $this, 'save_post_track_changed_fields' ), 10, 2 ); + if ( ! isset( $core_loader_objects['settings'] ) ) { + $core_loader_objects['settings'] = []; - if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) { - // Handle *_post_meta - if ( ! has_filter( 'get_post_metadata', array( $this, 'get_post_meta' ) ) ) { - if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) { - add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 ); + if ( ! empty( self::$settings ) ) { + foreach ( self::$settings as $setting_pod ) { + if ( $setting_pod instanceof Pod ) { + if ( ! $setting_pod->has_fields() ) { + continue; + } + } elseif ( empty( $setting_pod['fields'] ) ) { + continue; } - if ( ! pods_tableless() ) { - add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 ); - add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 ); - add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 ); - } + $core_loader_objects['settings'][] = $setting_pod['name']; } } } - // Handle Delete - add_action( 'delete_attachment', array( $this, 'delete_media' ), 10, 1 ); - - if ( ! empty( self::$user ) ) { - // Handle User Editor - add_action( 'show_user_profile', array( $this, 'meta_user' ) ); - add_action( 'edit_user_profile', array( $this, 'meta_user' ) ); - add_action( 'user_register', array( $this, 'save_user' ) ); - add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 ); - add_filter( 'pre_user_login', array( $this, 'save_user_track_changed_fields' ) ); + if ( $original_loader_objects !== $core_loader_objects ) { + pods_transient_set( 'pods_core_loader_objects', $core_loader_objects, WEEK_IN_SECONDS ); + } - if ( apply_filters( 'pods_meta_handler', true, 'user' ) ) { - // Handle *_user_meta - if ( apply_filters( 'pods_meta_handler_get', true, 'user' ) ) { - add_filter( 'get_user_metadata', array( $this, 'get_user_meta' ), 10, 4 ); - } + // Handle Post Type Editor (needed for Pods core). + pods_no_conflict_off( 'post', null, true ); - if ( ! pods_tableless() ) { - add_filter( 'add_user_metadata', array( $this, 'add_user_meta' ), 10, 5 ); - add_filter( 'update_user_metadata', array( $this, 'update_user_meta' ), 10, 5 ); - add_filter( 'delete_user_metadata', array( $this, 'delete_user_meta' ), 10, 5 ); - } + // Handle Taxonomies. + if ( ! empty( $core_loader_objects['taxonomies'] ) ) { + foreach ( $core_loader_objects['taxonomies'] as $taxonomy_name ) { + pods_no_conflict_off( 'taxonomy', $taxonomy_name, true ); } + } else { + // At least add the hook to delete. + add_action( 'delete_term_taxonomy', [ $this, 'delete_taxonomy' ], 10, 1 ); } - // Handle Delete - add_action( 'delete_user', array( $this, 'delete_user' ), 10, 1 ); + if ( $core_loader_objects['media'] ) { + pods_no_conflict_off( 'media', null, true ); + } else { + // At least add the hook to delete. + add_action( 'delete_attachment', [ $this, 'delete_media' ], 10, 1 ); + } - if ( ! empty( self::$comment ) ) { - // Handle Comment Form / Editor - add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 ); - add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) ); - add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) ); - add_filter( 'pre_comment_approved', array( $this, 'validate_comment' ), 10, 2 ); - add_action( 'comment_post', array( $this, 'save_comment' ) ); - add_action( 'edit_comment', array( $this, 'save_comment' ) ); - add_action( 'wp_update_comment_data', array( $this, 'save_comment_track_changed_fields' ), 10, 3 ); + if ( $core_loader_objects['user'] ) { + pods_no_conflict_off( 'user', null, true ); + } else { + // At least add the hook to delete. + add_action( 'delete_user', [ $this, 'delete_user' ], 10, 1 ); + } - if ( apply_filters( 'pods_meta_handler', true, 'comment' ) ) { - // Handle *_comment_meta - add_filter( 'get_comment_metadata', array( $this, 'get_comment_meta' ), 10, 4 ); + if ( $core_loader_objects['comment'] ) { + pods_no_conflict_off( 'comment', null, true ); + } else { + // At least add the hook to delete. + add_action( 'delete_comment', [ $this, 'delete_comment' ], 10, 1 ); + } - if ( ! pods_tableless() ) { - add_filter( 'add_comment_metadata', array( $this, 'add_comment_meta' ), 10, 5 ); - add_filter( 'update_comment_metadata', array( $this, 'update_comment_meta' ), 10, 5 ); - add_filter( 'delete_comment_metadata', array( $this, 'delete_comment_meta' ), 10, 5 ); - } + if ( ! empty( $core_loader_objects['settings'] ) ) { + foreach ( $core_loader_objects['settings'] as $setting_pod_name ) { + pods_no_conflict_off( 'settings', $setting_pod_name, true ); } } - // Handle Delete - add_action( 'delete_comment', array( $this, 'delete_comment' ), 10, 1 ); - - // @todo Patch core to provide $option back in filters, patch core to add filter pre_add_option to add_option - /*if ( !empty( self::$settings ) ) { - foreach ( self::$settings as $setting_pod ) { - foreach ( $setting_pod[ 'fields' ] as $option ) { - add_filter( 'pre_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'get_option' ), 10, 1 ); - add_action( 'add_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'add_option' ), 10, 2 ); - add_filter( 'pre_update_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'update_option' ), 10, 2 ); - } - } - }*/ - if ( is_admin() ) { $this->integrations(); } add_action( 'init', array( $this, 'enqueue' ), 9 ); - if ( function_exists( 'pll_current_language' ) ) { - add_action( 'init', array( $this, 'cache_pods' ), 101 ); - } - - do_action( 'pods_meta_init' ); + do_action( 'pods_meta_init', $this ); return $this; } @@ -326,7 +241,7 @@ public static function enqueue() { foreach ( self::$queue as $type => $objects ) { foreach ( $objects as $pod_name => $pod ) { - pods_transient_set( 'pods_pod_' . $pod_name, $pod ); + pods_transient_set( 'pods_pod_' . $pod_name, $pod, WEEK_IN_SECONDS ); } self::${$type} = array_merge( self::${$type}, $objects ); @@ -334,17 +249,47 @@ public static function enqueue() { } /** - * Go back through and cache the Pods now that Polylang has loaded + * Cache the Pods list. + * + * This is helpful to run to cache the Pods after Polylang has loaded. */ - public function cache_pods() { + public function cache_pods( $refresh = true ) { + $api = pods_api(); + + self::$advanced_content_types = $api->load_pods( [ + 'type' => 'pod', + 'refresh' => $refresh, + ] ); + + self::$post_types = $api->load_pods( [ + 'type' => 'post_type', + 'refresh' => $refresh, + ] ); + + self::$taxonomies = $api->load_pods( [ + 'type' => 'taxonomy', + 'refresh' => $refresh, + ] ); + + self::$media = $api->load_pods( [ + 'type' => 'media', + 'refresh' => $refresh, + ] ); - self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod', 'refresh' => true ) ); - self::$post_types = pods_api()->load_pods( array( 'type' => 'post_type', 'refresh' => true ) ); - self::$taxonomies = pods_api()->load_pods( array( 'type' => 'taxonomy', 'refresh' => true ) ); - self::$media = pods_api()->load_pods( array( 'type' => 'media', 'refresh' => true ) ); - self::$user = pods_api()->load_pods( array( 'type' => 'user', 'refresh' => true ) ); - self::$comment = pods_api()->load_pods( array( 'type' => 'comment', 'refresh' => true ) ); - self::$settings = pods_api()->load_pods( array( 'type' => 'settings', 'refresh' => true ) ); + self::$user = $api->load_pods( [ + 'type' => 'user', + 'refresh' => $refresh, + ] ); + + self::$comment = $api->load_pods( [ + 'type' => 'comment', + 'refresh' => $refresh, + ] ); + + self::$settings = $api->load_pods( [ + 'type' => 'settings', + 'refresh' => $refresh, + ] ); } /** @@ -612,7 +557,7 @@ public function cpac_meta_value( $meta, $id, $obj ) { } } - $field = ( "cpachidden" === substr( $obj->get_option( 'field' ), 0, 10 ) ) ? str_replace( 'cpachidden', '', $obj->get_option( 'field' ) ) : $obj->get_option( 'field' ); + $field = ( 'cpachidden' === substr( $obj->get_option( 'field' ), 0, 10 ) ) ? str_replace( 'cpachidden', '', $obj->get_option( 'field' ) ) : $obj->get_option( 'field' ); $field_type = $obj->get_option( 'field_type' ); if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] !== $object ) { @@ -652,7 +597,7 @@ public function cpac_meta_value( $meta, $id, $obj ) { $meta = $podterms->field( $field ); } - $meta = PodsForm::field_method( $pod['fields'][ $field ]['type'], 'ui', $id, $meta, $field, array_merge( $pod['fields'][ $field ], $pod['fields'][ $field ]['options'] ), $pod['fields'], $pod ); + $meta = PodsForm::field_method( $pod['fields'][ $field ]['type'], 'ui', $id, $meta, $field, $pod['fields'][ $field ], $pod['fields'], $pod ); } return $meta; @@ -675,7 +620,6 @@ public function cpac_meta_value( $meta, $id, $obj ) { * @return mixed|void */ public function group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default' ) { - if ( is_array( $pod ) && ! empty( $pod ) && ! isset( $pod['name'] ) ) { foreach ( $pod as $p ) { $this->group_add( $p, $label, $fields, $context, $priority ); @@ -757,7 +701,9 @@ public function group_add( $pod, $label, $fields, $context = 'normal', $priority 'type' => 'text' ); - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $name = trim( $field ); $field = array( @@ -766,12 +712,12 @@ public function group_add( $pod, $label, $fields, $context = 'normal', $priority ); } - $field = array_merge( $defaults, $field ); + $field = pods_config_merge_data( $defaults, $field ); $field['name'] = trim( $field['name'] ); if ( isset( $pod['fields'] ) && isset( $pod['fields'][ $field['name'] ] ) ) { - $field = array_merge( $field, $pod['fields'][ $field['name'] ] ); + $field = pods_config_merge_data( $field, $pod['fields'][ $field['name'] ] ); } $_fields[ $k ] = $field; @@ -800,45 +746,23 @@ public function group_add( $pod, $label, $fields, $context = 'normal', $priority // Hook it up! if ( 'post_type' == $pod['type'] ) { if ( ! has_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ) ) { - add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ); + pods_no_conflict_off( $pod['type'], $pod['object'], true ); } - - /*if ( !has_action( 'save_post', array( $this, 'save_post' ), 10, 3 ) ) - add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );*/ } elseif ( 'taxonomy' == $pod['type'] ) { - if ( ! has_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 ) ) { - add_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 ); - add_action( $pod['object'] . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 ); - } - - if ( ! has_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 ) ) { - add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 ); - add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 ); + if ( ! has_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ) ) ) { + pods_no_conflict_off( $pod['type'], $pod['object'], true ); } } elseif ( 'media' == $pod['type'] ) { - if ( ! has_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 ) ) { - add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ); - add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 ); - - add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 ); - - add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 ); - add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 ); + if ( ! has_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ) ) ) { + pods_no_conflict_off( $pod['type'], null, true ); } } elseif ( 'user' == $pod['type'] ) { if ( ! has_action( 'show_user_profile', array( $this, 'meta_user' ) ) ) { - add_action( 'show_user_profile', array( $this, 'meta_user' ) ); - add_action( 'edit_user_profile', array( $this, 'meta_user' ) ); - add_action( 'user_register', array( $this, 'save_user' ) ); - add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 ); + pods_no_conflict_off( $pod['type'], null, true ); } } elseif ( 'comment' == $pod['type'] ) { - if ( ! has_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 ) ) { - add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 ); - add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) ); - add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) ); - add_action( 'wp_insert_comment', array( $this, 'save_comment' ) ); - add_action( 'edit_comment', array( $this, 'save_comment' ) ); + if ( ! has_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ) ) ) { + pods_no_conflict_off( $pod['type'], null, true ); } } } @@ -867,7 +791,7 @@ public function object_get( $type, $name ) { $object = self::$comment; } - if ( 'pod' != $type && ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) { + if ( 'pod' !== $type && ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) { $pod = $object[ $name ]; } else { if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) { @@ -887,7 +811,7 @@ public function object_get( $type, $name ) { 'type' => 'post_type' ); - $pod = array_merge( $defaults, (array) $pod ); + $pod = pods_config_merge_data( $defaults, $pod ); if ( empty( $pod['name'] ) ) { $pod['name'] = $pod['object']; @@ -903,15 +827,16 @@ public function object_get( $type, $name ) { } /** - * @param $type - * @param $name - * @param $default_fields + * Get groups of fields for the content type. * - * @return array + * @param $type Content type. + * @param $name Content name. + * @param $default_fields List of default fields to include. + * + * @return array List of groups and their fields. */ public function groups_get( $type, $name, $default_fields = null ) { - - static $groups_cache = array(); + static $groups_cache = []; if ( isset( $groups_cache[ $type . '/' . $name ] ) ) { return $groups_cache[ $type . '/' . $name ]; @@ -926,8 +851,8 @@ public function groups_get( $type, $name, $default_fields = null ) { do_action( 'pods_meta_groups', $type, $name ); - $pod = array(); - $fields = array(); + $pod = []; + $fields = []; $object = self::$post_types; @@ -944,15 +869,16 @@ public function groups_get( $type, $name, $default_fields = null ) { } if ( ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) { - $fields = $object[ $name ]['fields']; + $pod = $object[ $name ]; + $fields = $pod['fields']; } else { - if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) { - self::$current_pod_data = pods_api()->load_pod( array( 'name' => $name ), false ); + if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] !== $name ) { + self::$current_pod_data = pods_api()->load_pod( [ 'name' => $name ], false ); } $pod = self::$current_pod_data; - if ( ! empty( $pod ) ) { + if ( ! empty( $pod ) && empty( $pod['groups'] ) ) { $fields = $pod['fields']; } } @@ -961,61 +887,86 @@ public function groups_get( $type, $name, $default_fields = null ) { $fields = $default_fields; } - $defaults = array( - 'name' => 'post', + $defaults = [ + 'name' => $name, 'object' => 'post', - 'type' => 'post_type' - ); + 'type' => 'post_type', + ]; - $pod = array_merge( $defaults, (array) $pod ); + if ( is_array( $pod ) ) { + $pod = array_merge( $defaults, $pod ); - if ( empty( $pod['name'] ) ) { - $pod['name'] = $pod['object']; - } elseif ( empty( $pod['object'] ) ) { - $pod['object'] = $pod['name']; + if ( empty( $pod['name'] ) ) { + $pod['name'] = $pod['object']; + } elseif ( empty( $pod['object'] ) ) { + $pod['object'] = $pod['name']; + } } - if ( $pod['type'] != $type ) { - $groups_cache[ $type . '/' . $name ] = array(); + if ( $pod && $pod['type'] !== $type ) { + $groups_cache[ $type . '/' . $name ] = []; return $groups_cache[ $type . '/' . $name ]; } - $groups = array( - array( + /** + * Filter the title of the Pods Metabox used in the post editor. + * + * @since unknown + * + * @param string $title The title to use, default is 'More Fields'. + * @param obj|Pod $pod Current Pods Object. + * @param array $fields Array of fields that will go in the metabox. + * @param string $type The type of Pod. + * @param string $name Name of the Pod. + */ + $title = apply_filters( 'pods_meta_default_box_title', __( 'More Fields', 'pods' ), $pod, $fields, $type, $name ); + + $groups = []; + + $has_custom_groups = ! empty( self::$groups[ $type ][ $name ] ); + + if ( ! empty( $pod['groups'] ) ) { + foreach ( $pod['groups'] as $group ) { + if ( empty( $group['fields'] ) ) { + continue; + } + + $groups[] = [ + 'pod' => $pod, + 'label' => $group['label'], + 'fields' => $group['fields'], + 'context' => pods_v( 'meta_box_context', $group, 'normal', true ), + 'priority' => pods_v( 'meta_box_priority', $group, 'default', true ), + ]; + } + + if ( $has_custom_groups ) { + $groups = array_merge( $groups, self::$groups[ $type ][ $name ] ); + } + } elseif ( $has_custom_groups ) { + $groups = self::$groups[ $type ][ $name ]; + } + + if ( empty( $groups ) && ! empty( $fields ) ) { + $groups[] = [ 'pod' => $pod, - /** - * Filter the title of the Pods Metabox In The Post Editor - * - * @param string $title The title to use, default is 'More Fields' - * @param obj|Pod $pod Current Pods Object - * @param array $fields Array of fields that will go in the metabox - * @param string $type The type of Pod - * @param string $name Name of the Pod - * - * @return string The title for the metabox. - * - * @since unknown - */ - 'label' => apply_filters( 'pods_meta_default_box_title', __( 'More Fields', 'pods' ), $pod, $fields, $type, $name ), + 'label' => $title, 'fields' => $fields, 'context' => 'normal', - 'priority' => 'default' - ) - ); - - if ( isset( self::$groups[ $type ] ) && isset( self::$groups[ $type ][ $name ] ) ) { - $groups = self::$groups[ $type ][ $name ]; + 'priority' => 'default', + ]; } /** * Filter the array of field groups * - * @param array $groups Array of groups + * @since 2.6.6 + * * @param string $type The type of Pod * @param string $name Name of the Pod * - * @since 2.6.6 + * @param array $groups Array of groups */ $groups = apply_filters( 'pods_meta_groups_get', $groups, $type, $name ); @@ -1046,14 +997,18 @@ public function meta_post_add( $post_type, $post = null ) { continue; } + if ( ! pods_permission( $group ) ) { + continue; + } + $field_found = false; $group_hidden = true; foreach ( $group['fields'] as $field ) { - if ( false !== PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'] ) ) { + if ( pods_permission( $field ) ) { $field_found = true; } - if ( ! isset( $field['options']['hidden'] ) || 1 != (int) $field['options']['hidden'] ) { + if ( ! isset( $field['hidden'] ) || 1 !== (int) $field['hidden'] ) { $group_hidden = false; } } @@ -1082,16 +1037,94 @@ public function meta_post_add( $post_type, $post = null ) { } } + /** + * Handle overriding the "Add title" placeholder. + * + * @since 2.8.0 + * + * @param string $placeholder The "Add title" placeholder. + * @param WP_Post $post The post object. + * + * @return string The "Add title" placeholder. + */ + public function meta_post_enter_title_here( $placeholder, $post ) { + $pod = $this->maybe_set_up_pod( $post->post_type, null, 'post_type' ); + + // Check if we have a valid pod. + if ( ! $pod ) { + return $placeholder; + } + + return pods_v( 'placeholder_enter_title_here', $pod->pod_data, $placeholder, true ); + } + + /** + * Handle overriding the number of revisions to keep. + * + * @since 2.8.0 + * + * @param int $num Number of revisions to store. + * @param WP_Post $post The post object. + * + * @return int The number of revisions to keep. + */ + public function meta_post_revisions_to_keep( $num, $post ) { + $pod = $this->maybe_set_up_pod( $post->post_type, null, 'post_type' ); + + // Check if we have a valid pod. + if ( ! $pod ) { + return $num; + } + + $revisions_to_keep_limit = pods_v( 'revisions_to_keep_limit', $pod->pod_data ); + + // Check if we have a valid limit. + if ( ! is_numeric( $revisions_to_keep_limit ) ) { + return $num; + } + + return (int) $revisions_to_keep_limit; + } + /** * * Called by 'post_edit_form_tag' action to include the classes in the
tag * */ public function add_class_submittable() { - echo ' class="pods-submittable pods-form"'; } + /** + * Maybe set up the Pods object or return the current one. + * + * @since 2.8.0 + * + * @param string $pod_name The pod name. + * @param int|null $id The item ID or null to not check ID. + * @param string|null $pod_type The pod type if we need to be strict on the check. + * + * @return bool|Pods The Pods object or false if the pod is invalid. + */ + public function maybe_set_up_pod( $pod_name, $id = null, $pod_type = null ) { + // Check if we have a pod object set up for this pod name yet. + if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== $pod_name ) { + self::$current_pod = pods( $pod_name, null, true ); + } + + // Check if we need to strictly check the pod type. + if ( self::$current_pod instanceof Pods && null !== $pod_type && self::$current_pod->pod_data['type'] !== $pod_type ) { + self::$current_pod = false; + } + + // Check if we have a valid pod and if we need to fetch the new ID. + if ( self::$current_pod instanceof Pods && null !== $id && (int) self::$current_pod->id() !== (int) $id ) { + self::$current_pod->fetch( $id ); + } + + return self::$current_pod; + } + /** * @param $post * @param $metabox @@ -1109,21 +1142,13 @@ public function meta_post( $post, $metabox ) { do_action( 'pods_meta_meta_post', $post ); - $hidden_fields = array(); - $id = null; if ( is_object( $post ) ) { $id = $post->ID; } - if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod ) || self::$current_pod->pod != $metabox['args']['group']['pod']['name'] ) { - self::$current_pod = pods( $metabox['args']['group']['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } - - $pod = self::$current_pod; + $pod = $this->maybe_set_up_pod( $metabox['args']['group']['pod']['name'], $id, 'post_type' ); $fields = $metabox['args']['group']['fields']; @@ -1141,34 +1166,26 @@ public function meta_post( $post, $metabox ) { $fields = apply_filters( 'pods_meta_post_fields', $fields, $id, $post, $metabox, $pod ); if ( empty( $fields ) ) { - _e( 'There are no fields to display', 'pods' ); + esc_html_e( 'There are no fields to display', 'pods' ); return; } + + echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_' . $pod_type ), 'hidden' ); ?> field( array( 'name' => $field['name'], 'in_form' => true ) ); - - pods_no_conflict_off( 'post' ); + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true, 'single' => true ] ); } elseif ( ! empty( $id ) ) { $value = get_post_meta( $id, $field['name'], true ); } @@ -1182,56 +1199,30 @@ public function meta_post( $post, $metabox ) { } } - if ( 'hidden' == $field['type'] ) { - $hidden_fields[] = array( - 'field' => $field, - 'value' => $value - ); - } else { - $dep_options = PodsForm::dependencies( $field, 'pods-meta-' ); - $dep_classes = $dep_options['classes']; - $dep_data = $dep_options['data']; - - $field_name = $field['name']; - do_action( "pods_meta_meta_post_{$field_name}", $post, $field, $pod ); - ?> - "> - - - - -
- -
- - -
-
+ pods_no_conflict_off( 'post' ); - + $post_callback = static function( $field_name, $id, $field, $pod ) use ( $post ) { + do_action( "pods_meta_meta_post_{$field_name}_post", $post, $field, $pod ); + do_action( "pods_meta_meta_post_post_row_{$field_name}", $post, $field, $pod ); + }; + + pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) ); + ?> + + + post_type, $blacklisted_types ) ) { + if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || in_array( $post->post_type, $blacklisted_types, true ) ) { return; } @@ -1325,25 +1317,18 @@ public function save_post( $post_id, $post, $update = null ) { $blacklisted_status = apply_filters( 'pods_meta_save_post_blacklist_status', $blacklisted_status, $post_id, $post ); - if ( in_array( $post->post_status, $blacklisted_status ) ) { + if ( in_array( $post->post_status, $blacklisted_status, true ) ) { return; } $groups = $this->groups_get( 'post_type', $post->post_type ); - $id = $post_id; - - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== $post->post_type ) { - self::$current_pod = pods( $post->post_type, $id, true ); - } elseif ( is_object( self::$current_pod ) && (int) self::$current_pod->id() !== (int) $id ) { - self::$current_pod->fetch( $id ); - } - - $pod = self::$current_pod; - $data = array(); + $id = $post_id; + $pod = $this->maybe_set_up_pod( $post->post_type, $id, 'post_type' ); + $data = []; if ( $pod ) { - $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false ); + $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false ); // Block REST API saves, we handle those separately in PodsRESTHandlers if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) { @@ -1353,14 +1338,24 @@ public function save_post( $post_id, $post, $update = null ) { // The following code will run for all post_types (not just Pods) if ( false !== $nonced && ! empty( $groups ) ) { + $layout_field_types = PodsForm::layout_field_types(); + foreach ( $groups as $group ) { if ( empty( $group['fields'] ) ) { continue; } + if ( ! pods_permission( $group ) ) { + continue; + } + foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_v( 'hidden', $field['options'], false ) ) { + if ( in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } + + if ( ! pods_permission( $field ) ) { + if ( ! pods_v( 'hidden', $field, false ) ) { continue; } } @@ -1389,7 +1384,10 @@ public function save_post( $post_id, $post, $update = null ) { // Fix for Pods doing it's own sanitizing. $data = pods_unslash( (array) $data ); - $pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) ); + $pod->save( $data, null, $id, array( + 'is_new_item' => $is_new_item, + 'podsmeta' => true + ) ); } elseif ( ! empty( $id ) ) { foreach ( $data as $field => $value ) { update_post_meta( $id, $field, $value ); @@ -1466,45 +1464,66 @@ public function meta_media( $form_fields, $post ) { continue; } - if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'media' ); } + $did_init = false; + foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_var( 'hidden', $field['options'], false ) ) { + if ( ! pods_permission( $field ) ) { + if ( ! pods_var( 'hidden', $field, false ) ) { continue; } } + // Skip heavy fields. + if ( in_array( $field['type'], [ 'wysiwyg', 'code', 'file', 'oembed' ], true ) ) { + continue; + } + $value = ''; + pods_no_conflict_on( 'post' ); + if ( ! empty( $pod ) ) { - $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) ); + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); } elseif ( ! empty( $id ) ) { - pods_no_conflict_on( 'post' ); - $value = get_post_meta( $id, $field['name'], true ); - - pods_no_conflict_off( 'post' ); } - // Manually force DFV initialization. This is needed for attachments in "grid mode" in the - // media library. Note that this should only occur for attachment_fields_to_edit (see #4785) - $dfv_init_script = ""; + pods_no_conflict_off( 'post' ); $form_fields[ 'pods_meta_' . $field['name'] ] = array( 'label' => $field['label'], 'input' => 'html', - 'html' => PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ) . $meta_nonce . $dfv_init_script, + 'html' => PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ), 'helps' => PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ) ); + + // Manually force DFV initialization. This is needed for attachments in "grid mode" in the + // media library. Note that this should only occur for attachment_fields_to_edit (see #4785) + $dfv_init_script = ''; + + // Only output nonce/init script on the very first field of the first group we have. + if ( ! $did_init ) { + $form_fields[ 'pods_meta_' . $field['name'] ]['html'] .= $meta_nonce; + $form_fields[ 'pods_meta_' . $field['name'] ]['html'] .= $dfv_init_script; + + $did_init = true; + } + + if ( 'heading' === $field['type'] ) { + $form_fields[ 'pods_meta_' . $field['name'] ]['html'] = $form_fields[ 'pods_meta_' . $field['name'] ]['label']; + $form_fields[ 'pods_meta_' . $field['name'] ]['label'] = ''; + } elseif ( 'html' === $field['type'] ) { + $form_fields[ 'pods_meta_' . $field['name'] ]['label'] = ''; + $form_fields[ 'pods_meta_' . $field['name'] ]['helps'] = ''; + } } } @@ -1546,25 +1565,28 @@ public function save_media( $post, $attachment ) { $id = $post_id; $pod = null; + $layout_field_types = PodsForm::layout_field_types(); + foreach ( $groups as $group ) { if ( empty( $group['fields'] ) ) { continue; } - if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'media' ); } foreach ( $group['fields'] as $field ) { + if ( in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_var( 'hidden', $field['options'], false ) ) { + if ( ! pods_permission( $field ) ) { + if ( ! pods_var( 'hidden', $field, false ) ) { continue; } } @@ -1578,7 +1600,7 @@ public function save_media( $post, $attachment ) { } if ( $pod ) { - $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false ); + $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false ); // Block REST API saves, we handle those separately in PodsRESTHandlers if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) { @@ -1592,7 +1614,7 @@ public function save_media( $post, $attachment ) { // Fix for Pods doing it's own sanitization $data = pods_unslash( (array) $data ); - $pod->save( $data, null, null, array( 'podsmeta' => true ) ); + $pod->save( $data, null, $id, array( 'podsmeta' => true ) ); } elseif ( ! empty( $id ) ) { pods_no_conflict_on( 'post' ); @@ -1684,56 +1706,54 @@ public function meta_taxonomy( $tag, $taxonomy = null ) { continue; } - if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'taxonomy' ); } - foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } else { - continue; - } - } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } + $fields = array_merge( [ + '_group_title' => [ + 'name' => '_group_title', + 'label' => $group['label'], + 'type' => 'heading', + 'heading_tag' => 'h2', + ], + ], $group['fields'] ); + $field_prefix = 'pods_meta_'; + $field_row_classes = 'form-field'; + $th_scope = 'row'; + $value_callback = static function( $field_name, $id, $field, $pod ) { $value = ''; + pods_no_conflict_on( 'taxonomy' ); + if ( ! empty( $pod ) ) { - $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) ); + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); + } elseif ( ! empty( $id ) ) { + $value = get_term_meta( $id, $field['name'], true ); } - if ( ! is_object( $tag ) ) { - ?> -
- -
- - - - - - - - id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } - - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'taxonomy' ); } foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_var( 'hidden', $field['options'], false ) ) { + if ( in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } + + if ( ! pods_permission( $field ) ) { + if ( ! pods_var( 'hidden', $field, false ) ) { continue; } } @@ -1816,7 +1840,7 @@ public function save_taxonomy( $term_id, $term_taxonomy_id, $taxonomy ) { } if ( $pod ) { - $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false ); + $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false ); // Block REST API saves, we handle those separately in PodsRESTHandlers if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) { @@ -1842,7 +1866,7 @@ public function save_taxonomy( $term_id, $term_taxonomy_id, $taxonomy ) { // Fix for Pods doing it's own sanitization $data = pods_unslash( (array) $data ); - $pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) ); + $pod->save( $data, null, $id, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) ); } pods_no_conflict_off( 'taxonomy' ); @@ -1890,7 +1914,10 @@ public function meta_user( $user_id ) { $groups = $this->groups_get( 'user', 'user' ); if ( is_object( $user_id ) ) { + $user = $user_id; $user_id = $user_id->ID; + } else { + $user = get_userdata( $user_id ); } $id = $user_id; @@ -1901,17 +1928,13 @@ public function meta_user( $user_id ) { continue; } - if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } - - $pod = self::$current_pod; + if ( ! pods_permission( $group ) ) { + continue; } - $hidden_fields = array(); + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'user' ); + } ?>

@@ -1920,56 +1943,40 @@ public function meta_user( $user_id ) { field( array( 'name' => $field['name'], 'in_form' => true ) ); + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); } elseif ( ! empty( $id ) ) { - pods_no_conflict_on( 'user' ); - $value = get_user_meta( $id, $field['name'], true ); - - pods_no_conflict_off( 'user' ); } - if ( 'hidden' == $field['type'] ) { - $hidden_fields[] = array( - 'field' => $field, - 'value' => $value - ); - } else { - ?> - - - - -
- - -
groups_get( 'user', 'user' ); - $id = $user_id; - - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== 'user' ) { - self::$current_pod = pods( 'user', $id, true ); - } elseif ( is_object( self::$current_pod ) && (int) self::$current_pod->id() !== (int) $id ) { - self::$current_pod->fetch( $id ); - } - - $pod = self::$current_pod; - $data = array(); + $id = $user_id; + $pod = $this->maybe_set_up_pod( 'user', $id, 'user' ); + $data = []; if ( $pod ) { - $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false ); + $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false ); // Block REST API saves, we handle those separately in PodsRESTHandlers if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) { @@ -2024,14 +2024,24 @@ public function save_user( $user_id, $old_user_data = null ) { } if ( false !== $nonced && ! empty( $groups ) ) { + $layout_field_types = PodsForm::layout_field_types(); + foreach ( $groups as $group ) { if ( empty( $group['fields'] ) ) { continue; } + if ( ! pods_permission( $group ) ) { + continue; + } + foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_v( 'hidden', $field['options'], false ) ) { + if ( in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } + + if ( ! pods_permission( $field ) ) { + if ( ! pods_v( 'hidden', $field, false ) ) { continue; } } @@ -2058,7 +2068,7 @@ public function save_user( $user_id, $old_user_data = null ) { // Fix for Pods doing it's own sanitizing $data = pods_unslash( (array) $data ); - $pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) ); + $pod->save( $data, null, $id, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) ); } elseif ( ! empty( $id ) ) { foreach ( $data as $field => $value ) { update_user_meta( $id, $field, $value ); @@ -2127,48 +2137,53 @@ public function meta_comment_new_logged_in( $commenter, $user_identity ) { continue; } - if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' ); } - foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } else { - continue; - } - } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } + $fields = array_merge( [ + '_group_title' => [ + 'name' => '_group_title', + 'label' => $group['label'], + 'type' => 'heading', + 'heading_tag' => 'h2', + ], + ], $group['fields'] ); + $field_prefix = 'pods_meta_'; + $field_row_classes = 'comment-form-author comment-form-pods-meta'; + $value_callback = static function( $field_name, $id, $field, $pod ) { $value = ''; + pods_no_conflict_on( 'comment' ); + if ( ! empty( $pod ) ) { - $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) ); + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); } elseif ( ! empty( $id ) ) { - pods_no_conflict_on( 'comment' ); - $value = get_comment_meta( $id, $field['name'], true ); - - pods_no_conflict_off( 'comment' ); } - ?> -

- -

- id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' ); } - foreach ( $group['fields'] as $field ) { + $fields = array_merge( [ + '_group_title' => [ + 'name' => '_group_title', + 'label' => $group['label'], + 'type' => 'heading', + 'heading_tag' => 'h2', + ], + ], $group['fields'] ); + $field_prefix = 'pods_meta_'; + $field_row_classes = 'comment-form-author comment-form-pods-meta'; - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } else { + $value_callback = static function( $field_name, $id, $field, $pod ) { + $value = ''; + + pods_no_conflict_on( 'comment' ); + + if ( ! empty( $pod ) ) { + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); + } elseif ( ! empty( $id ) ) { + $value = get_comment_meta( $id, $field['name'], true ); + } + + pods_no_conflict_off( 'comment' ); + + return $value; + }; + + // There is no comment yet. + $comment = null; + + $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) { + do_action( "pods_meta_meta_comment_pre_row_{$field_name}", $comment, $field, $pod ); + }; + + $post_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) { + do_action( "pods_meta_meta_comment_post_row_{$field_name}", $comment, $field, $pod ); + }; + + foreach ( $fields as $field ) { + $hidden_field = (boolean) pods_v( 'hidden', $field, false ); + + if ( + ! pods_permission( $field ) + || ( ! pods_has_permissions( $field ) && $hidden_field ) + ) { + if ( ! $hidden_field ) { continue; } - } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) { + $field['type'] = 'hidden'; } $value = ''; - if ( ! empty( $pod ) ) { - $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) ); - } elseif ( ! empty( $id ) ) { - pods_no_conflict_on( 'comment' ); + if ( ! empty( $value_callback ) && is_callable( $value_callback ) ) { + $value = $value_callback( $field['name'], $id, $field, $pod ); + } elseif ( ! empty( $pod ) ) { + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); + } - $value = get_comment_meta( $id, $field['name'], true ); + $row_classes = $field_row_classes . ' pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ); + $row_classes = trim( $row_classes ); - pods_no_conflict_off( 'comment' ); + ob_start(); + + if ( ! empty( $pre_callback ) && is_callable( $pre_callback ) ) { + $pre_callback( $field['name'], $id, $field, $pod ); + } + + pods_view( PODS_DIR . 'ui/forms/p-row.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true ); + + if ( ! empty( $post_callback ) && is_callable( $post_callback ) ) { + $post_callback( $field['name'], $id, $field, $pod ); } - ob_start(); - ?> -

- -

- comment_ID; } - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $metabox['args']['group']['pod']['name'] ) { - self::$current_pod = pods( $metabox['args']['group']['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } - - $pod = self::$current_pod; + $pod = $this->maybe_set_up_pod( $metabox['args']['group']['pod']['name'], $id, 'comment' ); - foreach ( $metabox['args']['group']['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $metabox['args']['group']['fields'], $pod, $id ) ) { - if ( pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } else { - continue; - } - } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) { - $field['type'] = 'hidden'; - } + $fields = $metabox['args']['group']['fields']; + $field_prefix = 'pods_meta_'; + $field_row_classes = 'comment-form-author comment-form-pods-meta'; + $value_callback = static function( $field_name, $id, $field, $pod ) { $value = ''; + pods_no_conflict_on( 'comment' ); + if ( ! empty( $pod ) ) { - $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) ); + $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] ); + } elseif ( ! empty( $id ) ) { + $value = get_comment_meta( $id, $field['name'], true ); } - if ( 'hidden' == $field['type'] ) { - $hidden_fields[] = array( - 'field' => $field, - 'value' => $value - ); - } else { - ?> - - - - - - - - id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' ); } foreach ( $group['fields'] as $field ) { + if ( in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_var( 'hidden', $field['options'], false ) ) { + if ( ! pods_permission( $field ) ) { + if ( ! pods_var( 'hidden', $field, false ) ) { continue; } } @@ -2425,7 +2471,7 @@ public function validate_comment( $approved, $commentdata ) { $data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ]; } - $validate = pods_api()->handle_field_validation( $data[ $field['name'] ], $field['name'], pods_api()->get_wp_object_fields( 'comment' ), $pod->fields(), $pod, array() ); + $validate = $api->handle_field_validation( $data[ $field['name'] ], $field['name'], $api->get_wp_object_fields( 'comment' ), $pod->fields(), $pod, array() ); if ( false === $validate ) { $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field['label'] ); @@ -2460,24 +2506,28 @@ public function save_comment( $comment_id ) { $id = $comment_id; $pod = null; + $layout_field_types = PodsForm::layout_field_types(); + foreach ( $groups as $group ) { if ( empty( $group['fields'] ) ) { continue; } - if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) { - if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) { - self::$current_pod = pods( $group['pod']['name'], $id, true ); - } elseif ( self::$current_pod->id() != $id ) { - self::$current_pod->fetch( $id ); - } + if ( ! pods_permission( $group ) ) { + continue; + } - $pod = self::$current_pod; + if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) { + $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' ); } foreach ( $group['fields'] as $field ) { - if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) { - if ( ! pods_var( 'hidden', $field['options'], false ) ) { + if ( in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } + + if ( ! pods_permission( $field ) ) { + if ( ! pods_var( 'hidden', $field, false ) ) { continue; } } @@ -2491,7 +2541,7 @@ public function save_comment( $comment_id ) { } if ( $pod ) { - $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false ); + $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false ); // Block REST API saves, we handle those separately in PodsRESTHandlers if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) { @@ -2505,7 +2555,7 @@ public function save_comment( $comment_id ) { // Fix for Pods doing it's own sanitization $data = pods_unslash( (array) $data ); - $pod->save( $data, null, null, array( 'podsmeta' => true ) ); + $pod->save( $data, null, $id, array( 'podsmeta' => true ) ); } elseif ( ! empty( $id ) ) { pods_no_conflict_on( 'comment' ); @@ -2545,13 +2595,70 @@ public function save_comment_track_changed_fields( $data, $comment, $commentarr } + /** + * Get list of keys not covered for an object type. + * + * @param string $type The object type. + * + * @return array The list of keys not covered in key=>true format for isset() optimization. + */ + public function get_keys_not_covered( $type ) { + if ( 'post' === $type ) { + $type = 'post_type'; + } + + $keys_not_covered = [ + 'post_type' => [ + '_wp_attachment_metadata' => true, + '_thumbnail_id' => true, + ], + 'user' => [ + 'capabilities' => true, + 'session_tokens' => true, + 'primary_blog' => true, + 'default_password_nag' => true, + 'tribe-dismiss-notice' => true, + 'user-settings' => true, + 'admin_color' => true, + 'show_admin_bar_front' => true, + 'show_admin_bar_admin' => true, + ], + 'settings' => [ + ], + ]; + + // Add prefix-specific keys for user type. + if ( 'user' === $type ) { + global $wpdb; + + $prefix = $wpdb->get_blog_prefix(); + + $keys = $keys_not_covered['user']; + + foreach ( $keys as $key => $ignored ) { + $keys_not_covered['user'][ $prefix . $key ] = true; + } + } + + /** + * Allow filtering the list of keys not covered. + * + * @since 2.8.0 + * + * @param array $keys_not_covered The list of keys not covered in key=>true format for isset() optimization. + * @param string $type The object type. + */ + $keys_not_covered = apply_filters( 'pods_meta_keys_not_covered', $keys_not_covered, $type ); + + return isset( $keys_not_covered[ $type ] ) ? $keys_not_covered[ $type ] : []; + } + /** * All *_*_meta filter handler aliases * * @return mixed */ public function get_post_meta() { - $args = func_get_args(); array_unshift( $args, 'post_type' ); @@ -2569,7 +2676,6 @@ public function get_post_meta() { * @return mixed */ public function get_user_meta() { - $args = func_get_args(); array_unshift( $args, 'user' ); @@ -2587,7 +2693,6 @@ public function get_user_meta() { * @return mixed */ public function get_comment_meta() { - $args = func_get_args(); array_unshift( $args, 'comment' ); @@ -2605,7 +2710,6 @@ public function get_comment_meta() { * @return mixed */ public function get_term_meta() { - $args = func_get_args(); array_unshift( $args, 'term' ); @@ -2625,9 +2729,12 @@ public function get_term_meta() { * @return mixed */ public function get_option() { - $args = func_get_args(); + if ( 0 === strpos( $args[2], '_transient_' ) || 0 === strpos( $args[2], '_site_transient_' ) ) { + return $args[0]; + } + array_unshift( $args, 'settings' ); $_null = apply_filters( 'pods_meta_get_option', null, $args ); @@ -2643,7 +2750,6 @@ public function get_option() { * @return mixed */ public function add_post_meta() { - $args = func_get_args(); array_unshift( $args, 'post_type' ); @@ -2661,7 +2767,6 @@ public function add_post_meta() { * @return mixed */ public function add_user_meta() { - $args = func_get_args(); array_unshift( $args, 'user' ); @@ -2679,7 +2784,6 @@ public function add_user_meta() { * @return mixed */ public function add_comment_meta() { - $args = func_get_args(); array_unshift( $args, 'comment' ); @@ -2697,7 +2801,6 @@ public function add_comment_meta() { * @return mixed */ public function add_term_meta() { - $args = func_get_args(); array_unshift( $args, 'term' ); @@ -2715,7 +2818,6 @@ public function add_term_meta() { * @return mixed */ public function add_option() { - $args = func_get_args(); array_unshift( $args, 'settings' ); @@ -2733,7 +2835,6 @@ public function add_option() { * @return mixed */ public function update_post_meta() { - $args = func_get_args(); array_unshift( $args, 'post_type' ); @@ -2751,7 +2852,6 @@ public function update_post_meta() { * @return mixed */ public function update_user_meta() { - $args = func_get_args(); array_unshift( $args, 'user' ); @@ -2769,7 +2869,6 @@ public function update_user_meta() { * @return mixed */ public function update_comment_meta() { - $args = func_get_args(); array_unshift( $args, 'comment' ); @@ -2787,7 +2886,6 @@ public function update_comment_meta() { * @return mixed */ public function update_term_meta() { - $args = func_get_args(); array_unshift( $args, 'term' ); @@ -2805,7 +2903,6 @@ public function update_term_meta() { * @return mixed */ public function update_option() { - $args = func_get_args(); array_unshift( $args, 'settings' ); @@ -2820,10 +2917,157 @@ public function update_option() { } /** + * Handle updating post meta by meta ID. + * + * @since 2.8.0 + * * @return mixed */ - public function delete_post_meta() { + public function update_post_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'post_type' ); + + // WP core filter is weird and has meta value before meta key. + $meta_value = $args[3]; + $meta_key = $args[4]; + + // Switch order of meta key / meta value. + $args[3] = $meta_key; + $args[4] = $meta_value; + + /** + * Allow circumventing the update meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_update_post_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'update_meta_by_id' ], $args ); + } + + /** + * Handle updating user meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function update_user_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'user' ); + + // WP core filter is weird and has meta value before meta key. + $meta_value = $args[3]; + $meta_key = $args[4]; + + // Switch order of meta key / meta value. + $args[3] = $meta_key; + $args[4] = $meta_value; + + /** + * Allow circumventing the update meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_update_user_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'update_meta_by_id' ], $args ); + } + + /** + * Handle updating comment meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function update_comment_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'comment' ); + + // WP core filter is weird and has meta value before meta key. + $meta_value = $args[3]; + $meta_key = $args[4]; + + // Switch order of meta key / meta value. + $args[3] = $meta_key; + $args[4] = $meta_value; + + /** + * Allow circumventing the update meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_update_comment_meta_by_id', null, $args ); + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'update_meta_by_id' ], $args ); + } + + /** + * Handle updating term meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function update_term_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'term' ); + + // WP core filter is weird and has meta value before meta key. + $meta_value = $args[3]; + $meta_key = $args[4]; + + // Switch order of meta key / meta value. + $args[3] = $meta_key; + $args[4] = $meta_value; + + /** + * Allow circumventing the update meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_update_term_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'update_meta_by_id' ], $args ); + } + + /** + * @return mixed + */ + public function delete_post_meta() { $args = func_get_args(); array_unshift( $args, 'post_type' ); @@ -2841,7 +3085,6 @@ public function delete_post_meta() { * @return mixed */ public function delete_user_meta() { - $args = func_get_args(); array_unshift( $args, 'user' ); @@ -2859,7 +3102,6 @@ public function delete_user_meta() { * @return mixed */ public function delete_comment_meta() { - $args = func_get_args(); array_unshift( $args, 'comment' ); @@ -2877,7 +3119,6 @@ public function delete_comment_meta() { * @return mixed */ public function delete_term_meta() { - $args = func_get_args(); array_unshift( $args, 'term' ); @@ -2895,7 +3136,6 @@ public function delete_term_meta() { * @return mixed */ public function delete_option() { - $args = func_get_args(); array_unshift( $args, 'settings' ); @@ -2909,6 +3149,122 @@ public function delete_option() { return call_user_func_array( array( $this, 'delete_meta' ), $args ); } + /** + * Handle deleting post meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function delete_post_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'post_type' ); + + /** + * Allow circumventing the delete meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_delete_post_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args ); + } + + /** + * Handle deleting user meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function delete_user_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'user' ); + + /** + * Allow circumventing the delete meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_delete_user_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args ); + } + + /** + * Handle deleting comment meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function delete_comment_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'comment' ); + + /** + * Allow circumventing the delete meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_delete_comment_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args ); + } + + /** + * Handle deleting term meta by meta ID. + * + * @since 2.8.0 + * + * @return mixed + */ + public function delete_term_meta_by_id() { + $args = func_get_args(); + + array_unshift( $args, 'term' ); + + /** + * Allow circumventing the delete meta handling by meta ID for Pods. + * + * @since 2.8.0 + * + * @param null|bool $_null Whether to override the meta handling by Pods. + * @param array $args The function arguments with the type added to the front. + */ + $_null = apply_filters( 'pods_meta_delete_term_meta_by_id', null, $args ); + + if ( null !== $_null ) { + return $_null; + } + + return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args ); + } + /* * The real meta functions */ @@ -2920,7 +3276,6 @@ public function delete_option() { * @return bool|mixed */ public function get_object( $object_type, $object_id, $aux = '' ) { - global $wpdb; if ( 'term' == $object_type ) { @@ -3025,7 +3380,6 @@ public function get_object( $object_type, $object_id, $aux = '' ) { * @return array|bool|int|mixed|null|string|void */ public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $single = false ) { - // Enforce boolean as it can be a string sometimes $single = filter_var( $single, FILTER_VALIDATE_BOOLEAN ); @@ -3037,6 +3391,14 @@ public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key $meta_type = 'term'; } + // List of keys we do not cover optimized for fastest isset() operation. + $keys_not_covered = $this->get_keys_not_covered( $object_type ); + + // Skip keys we do not cover. + if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) { + return $_null; + } + if ( empty( $meta_key ) ) { if ( ! defined( 'PODS_ALLOW_FULL_META' ) || ! PODS_ALLOW_FULL_META ) { return $_null; // don't cover get_post_meta( $id ) @@ -3088,7 +3450,11 @@ public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key $pod = self::$current_field_pod; - $meta_keys = array( $meta_key ); + $pod_object = $pod->pod_data; + + $meta_keys = [ + $meta_key, + ]; if ( empty( $meta_key ) ) { $meta_keys = array_keys( $meta_cache ); @@ -3096,15 +3462,20 @@ public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key $key_found = false; + $tableless_field_types = PodsForm::tableless_field_types(); + foreach ( $meta_keys as $meta_k ) { if ( ! empty( $pod ) ) { $first_meta_key = $meta_k; + if ( false !== strpos( $first_meta_key, '.' ) ) { // Get the first meta key. $first_meta_key = current( explode( '.', $first_meta_key ) ); } - if ( isset( $pod->fields[ $first_meta_key ] ) ) { + $field_object = $pod_object->get_field( $first_meta_key ); + + if ( $field_object ) { $key_found = true; $meta_cache[ $meta_k ] = $pod->field( array( @@ -3121,7 +3492,7 @@ public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key } } - if ( in_array( $pod->fields[ $first_meta_key ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $first_meta_key ] ) ) { + if ( isset( $meta_cache[ '_pods_' . $first_meta_key ] ) && in_array( $field_object['type'], $tableless_field_types, true ) ) { unset( $meta_cache[ '_pods_' . $first_meta_key ] ); } } @@ -3175,11 +3546,18 @@ public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key * @return bool|int|null */ public function add_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $unique = false ) { - if ( pods_tableless() ) { return $_null; } + // List of keys we do not cover optimized for fastest isset() operation. + $keys_not_covered = $this->get_keys_not_covered( $object_type ); + + // Skip keys we do not cover. + if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) { + return $_null; + } + $object = $this->get_object( $object_type, $object_id ); if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) { @@ -3223,38 +3601,47 @@ public function add_meta( $object_type, $_null = null, $object_id = 0, $meta_key * @return bool|int|null */ public function update_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) { - if ( pods_tableless() ) { return $_null; } + // List of keys we do not cover optimized for fastest isset() operation. + $keys_not_covered = $this->get_keys_not_covered( $object_type ); + + // Skip keys we do not cover. + if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) { + return $_null; + } + $object = $this->get_object( $object_type, $object_id ); if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) { return $_null; } - if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) { + if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod !== $object['name'] ) { self::$current_field_pod = pods( $object['name'] ); } $pod = self::$current_field_pod; - if ( ( isset( $pod->fields[ $meta_key ] ) || false !== strpos( $meta_key, '.' ) ) && $pod->row !== null ) { + $pod_object = $pod->pod_data; + $field_object = $pod_object->get_field( $meta_key ); + $tableless_field_types = PodsForm::tableless_field_types(); + + if ( null !== $pod->data->row && ( $field_object || false !== strpos( $meta_key, '.' ) ) ) { $key = $meta_key; + if ( false !== strpos( $meta_key, '.' ) ) { $key = current( explode( '.', $meta_key ) ); } - $pod->row[ $meta_key ] = $meta_value; + $pod->data->row[ $meta_key ] = $meta_value; - if ( isset( $pod->fields[ $key ] ) ) { - if ( in_array( $pod->fields[ $key ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $key ] ) ) { - unset( $meta_cache[ '_pods_' . $key ] ); - } + if ( isset( $meta_cache[ '_pods_' . $key ] ) && $field_object && in_array( $field_object['type'], $tableless_field_types, true ) ) { + unset( $meta_cache[ '_pods_' . $key ] ); } - } $pod->save( $meta_key, $meta_value, $object_id, array( 'podsmeta_direct' => true, 'error_mode' => 'false' ) ); @@ -3262,6 +3649,38 @@ public function update_meta( $object_type, $_null = null, $object_id = 0, $meta_ return $object_id; } + /** + * Handle updating the meta by meta ID. + * + * @since 2.8.0 + * + * @param string $object_type The object type. + * @param null $_null The default value for the filter. + * @param int $meta_id The meta ID. + * @param string $meta_value The meta value. + * @param string $meta_key The meta key. + * + * @return bool|int|null + */ + public function update_meta_by_id( $object_type, $_null = null, $meta_id = 0, $meta_key = '', $meta_value = '' ) { + $meta_type = 'post_type' === $object_type ? 'post' : $object_type; + + // Get the original meta record. + $meta = get_metadata_by_mid( $meta_type, $meta_id ); + + // Stop overriding the saving process if the original meta record was not found. + if ( ! $meta ) { + return $_null; + } + + $column = sanitize_key( $meta_type . '_id' ); + + // Get the object ID from the original meta record. + $object_id = $meta->{$column}; + + return $this->update_meta( $object_type, $_null, $object_id, $meta_key, $meta_value ); + } + /** * @param $object_type * @param null $_null @@ -3273,11 +3692,18 @@ public function update_meta( $object_type, $_null = null, $object_id = 0, $meta_ * @return null */ public function delete_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $delete_all = false ) { - if ( pods_tableless() ) { return $_null; } + // List of keys we do not cover optimized for fastest isset() operation. + $keys_not_covered = $this->get_keys_not_covered( $object_type ); + + // Skip keys we do not cover. + if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) { + return $_null; + } + $object = $this->get_object( $object_type, $object_id ); if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) { @@ -3311,13 +3737,42 @@ public function delete_meta( $object_type, $_null = null, $object_id = 0, $meta_ return $_null; } + /** + * Handle delete the meta by meta ID. + * + * @since 2.8.0 + * + * @param string $object_type The object type. + * @param null $_null The default value for the filter. + * @param int $meta_id The meta ID. + * + * @return bool|int|null + */ + public function delete_meta_by_id( $object_type, $_null = null, $meta_id = 0 ) { + $meta_type = 'post_type' === $object_type ? 'post' : $object_type; + + // Get the original meta record. + $meta = get_metadata_by_mid( $meta_type, $meta_id ); + + // Stop overriding the saving process if the original meta record was not found. + if ( ! $meta ) { + return $_null; + } + + $column = sanitize_key( $meta_type . '_id' ); + + // Get the object ID from the original meta record. + $object_id = $meta->{$column}; + + return $this->delete_meta( $object_type, $_null, $object_id, $meta->meta_key, $meta->meta_value ); + } + /** * @param $id * * @return bool|void */ public function delete_post( $id ) { - $post = get_post( $id ); if ( empty( $post ) ) { @@ -3334,7 +3789,6 @@ public function delete_post( $id ) { * @param $id */ public function delete_taxonomy( $id ) { - /** * @var $wpdb WPDB */ @@ -3366,7 +3820,6 @@ public function delete_taxonomy( $id ) { */ public static function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { - require_once( PODS_DIR . 'classes/PodsTermSplitting.php' ); $term_splitting = new Pods_Term_Splitting( $term_id, $new_term_id, $taxonomy ); $term_splitting->split_shared_term(); @@ -3422,7 +3875,8 @@ public function delete_object( $type, $id, $name = null ) { $params = array( 'pod' => pods_var( 'name', $object ), 'pod_id' => pods_var( 'id', $object ), - 'id' => $id + 'id' => $id, + 'strict' => false, ); return pods_api()->delete_pod_item( $params, false ); diff --git a/classes/PodsMigrate.php b/classes/PodsMigrate.php index f9038d4f99..74bde924b3 100644 --- a/classes/PodsMigrate.php +++ b/classes/PodsMigrate.php @@ -111,7 +111,7 @@ public function set_data( $data ) { $this->data = array_merge( $defaults, (array) $data ); } - + /** * Get items. * @@ -120,9 +120,9 @@ public function set_data( $data ) { * @return array List of data items. */ private function get_items() { - - return empty( $this->data['single'] ) ? - $this->data['items'] : + + return empty( $this->data['single'] ) ? + $this->data['items'] : array( $this->data['items'] ); } @@ -1101,7 +1101,7 @@ public function heres_the_beef( $import, $output = true ) { $field_data = array(); } - $field_data = array_merge( $default_field_data, $field_data ); + $field_data = pods_config_merge_data( $default_field_data, $field_data ); if ( null === $field_data['field'] ) { $field_data['field'] = $field; diff --git a/classes/PodsRESTFields.php b/classes/PodsRESTFields.php index 87feee2d7c..4ac71aa1e1 100644 --- a/classes/PodsRESTFields.php +++ b/classes/PodsRESTFields.php @@ -1,5 +1,8 @@ set_pod( $pod ); if ( $this->pod ) { - $this->add_fields(); + add_action( 'rest_api_init', [ $this, 'add_fields' ] ); } - } /** @@ -52,63 +53,68 @@ public function __construct( $pod ) { * @param string|Pods $pod Pods object or name of Pods object */ private function set_pod( $pod ) { + $this->pod = null; + + // Normalize the $pod object. + $pod = pods_config_for_pod( $pod ); + + // Check if the $pod is valid. + if ( false === $pod ) { + return; + } - if ( is_string( $pod ) ) { - $pod = pods( $pod, null, true ); + $type = $pod->get_type(); - $this->set_pod( $pod ); - } else { - $type = $pod->pod_data['type']; + $supported_pod_types = [ + 'post_type' => true, + 'taxonomy' => true, + 'media' => true, + 'user' => true, + 'comment' => true, + ]; - $supported_pod_types = array( - 'post_type', - 'taxonomy', - 'media', - 'user', - 'comment', - ); + // Check if the $type is supported. + if ( ! isset( $supported_pod_types[ $type ] ) ) { + return; + } - if ( in_array( $type, $supported_pod_types, true ) ) { - $this->pod = $pod; - } else { - $this->pod = false; - } - }//end if + $rest_enable = filter_var( $pod->get_arg( 'rest_enable', false ), FILTER_VALIDATE_BOOLEAN ); + // Check if this Pod has REST API integration enabled. + if ( ! $rest_enable ) { + return; + } + + $this->pod = $pod; } /** * Add fields, based on options to REST read/write requests * * @since 2.5.6 - * - * @access protected */ - protected function add_fields() { + public function add_fields() { + $pod_name = $this->pod->get_name(); + $pod_type = $this->pod->get_type(); + $fields = $this->pod->get_fields(); - $fields = $this->pod->fields(); + $rest_hook_name = $pod_name; - $rest_hook_name = $this->pod->pod_data['name']; - - if ( 'media' === $rest_hook_name ) { + if ( 'media' === $pod_name ) { $rest_hook_name = 'attachment'; - } elseif ( 'comment' === $this->pod->pod_data['type'] ) { + } elseif ( 'comment' === $pod_type ) { $rest_hook_name = 'comment'; } $rest_hook_name = 'rest_insert_' . $rest_hook_name; - if ( ! has_action( $rest_hook_name, array( 'PodsRESTHandlers', 'save_handler' ) ) ) { - add_action( $rest_hook_name, array( 'PodsRESTHandlers', 'save_handler' ), 10, 3 ); + if ( ! has_action( $rest_hook_name, [ 'PodsRESTHandlers', 'save_handler' ] ) ) { + add_action( $rest_hook_name, [ 'PodsRESTHandlers', 'save_handler' ], 10, 3 ); } - foreach ( $fields as $field_name => $field ) { - $read = self::field_allowed_to_extend( $field_name, $this->pod, 'read' ); - $write = self::field_allowed_to_extend( $field_name, $this->pod, 'write' ); - - $this->register( $field_name, $read, $write ); + foreach ( $fields as $field ) { + $this->register( $field ); } - } /** @@ -118,32 +124,36 @@ protected function add_fields() { * * @access protected * - * @param string $field_name Name of field - * @param bool $read Field allows REST API read access - * @param bool $write Field allows REST API write access + * @param Field $field The field object. */ - protected function register( $field_name, $read, $write ) { + protected function register( $field ) { + $rest_read = self::field_allowed_to_extend( $field, $this->pod, 'read' ); + $rest_write = self::field_allowed_to_extend( $field, $this->pod, 'write' ); - $args = array(); + // Check if we have any access. + if ( ! $rest_read && ! $rest_write ) { + return; + } + + $rest_args = []; - if ( $read ) { - $args['get_callback'] = array( 'PodsRESTHandlers', 'get_handler' ); + if ( $rest_read ) { + $rest_args['get_callback'] = [ 'PodsRESTHandlers', 'get_handler' ]; } - if ( $write ) { - $args['pods_update'] = true; + if ( $rest_write ) { + $rest_args['pods_update'] = true; } - $object_type = $this->pod->pod; + $object_type = $this->pod->get_type(); if ( 'media' === $object_type ) { $object_type = 'attachment'; } - if ( $read || $write ) { - register_rest_field( $object_type, $field_name, $args ); + if ( ! empty( $rest_args ) ) { + register_rest_field( $object_type, $field->get_name(), $rest_args ); } - } /** @@ -151,44 +161,39 @@ protected function register( $field_name, $read, $write ) { * * @since 2.5.6 * - * @param string $field_name The field name. - * @param Pods $pod Pods object. - * @param string $mode Are we checking read or write? + * @param string|Field $field The field object or name. + * @param Pod|Pods $pod The Pod object. + * @param string $mode The mode to use (read or write). * * @return bool If supports, true, else false. */ - public static function field_allowed_to_extend( $field_name, $pod, $mode = 'read' ) { + public static function field_allowed_to_extend( $field, $pod, $mode ) { + // Normalize the $pod object. + $pod = pods_config_for_pod( $pod ); - $allowed = false; - - if ( is_object( $pod ) ) { - $field = $pod->fields( $field_name ); - - if ( $field ) { - $pod_options = $pod->pod_data['options']; + // Check if the $pod is valid. + if ( false === $pod ) { + return false; + } - $read_all = (int) pods_v( 'read_all', $pod_options, 0 ); - $write_all = (int) pods_v( 'write_all', $pod_options, 0 ); + $all_fields_access = filter_var( $pod->get_arg( $mode . '_all', false ), FILTER_VALIDATE_BOOLEAN ); - if ( 'read' === $mode && 1 === $read_all ) { - $allowed = true; - } elseif ( 'write' === $mode && 1 === $write_all ) { - $allowed = true; - } else { - $rest_read = (int) $pod->fields( $field_name, 'rest_read' ); - $rest_write = (int) $pod->fields( $field_name, 'rest_write' ); + // Check for access on all fields. + if ( $all_fields_access ) { + return true; + } - if ( 'read' === $mode && 1 === $rest_read ) { - $allowed = true; - } elseif ( 'write' === $mode && 1 === $rest_write ) { - $allowed = true; - } - } - }//end if - }//end if + // Maybe get the Field object from the Pod. + if ( is_string( $field ) ) { + $field = $pod->get_field( $field ); + } - return $allowed; + // Check if we have a valid $field. + if ( ! $field instanceof Field ) { + return false; + } + return filter_var( $field->get_arg( $mode, false ), FILTER_VALIDATE_BOOLEAN ); } } diff --git a/classes/PodsRESTHandlers.php b/classes/PodsRESTHandlers.php index 08becb0e5d..622789e449 100755 --- a/classes/PodsRESTHandlers.php +++ b/classes/PodsRESTHandlers.php @@ -149,20 +149,16 @@ public static function get_handler( $object, $field_name, $request, $object_type * @var $related_pod Pods */ foreach ( $related_pod_items as $related_pod ) { - if ( ! is_object( $related_pod ) || ! is_a( $related_pod, 'Pods' ) ) { + if ( ! is_object( $related_pod ) || ! $related_pod instanceof Pods ) { $items = $related_pod_items; break; } if ( false === $fields ) { - $fields = $related_pod->fields(); + $fields = pods_config_get_all_fields( $related_pod ); $fields = array_keys( $fields ); - if ( isset( $related_pod->pod_data['object_fields'] ) && ! empty( $related_pod->pod_data['object_fields'] ) ) { - $fields = array_merge( $fields, array_keys( $related_pod->pod_data['object_fields'] ) ); - } - /** * What fields to show in a related field REST response. * @@ -229,19 +225,19 @@ public static function get_handler( $object, $field_name, $request, $object_type */ public static function save_handler( $object, $request, $creating ) { - if ( is_a( $object, 'WP_Post' ) ) { + if ( $object instanceof WP_Post ) { $type = $object->post_type; $id = $object->ID; - } elseif ( is_a( $object, 'WP_Term' ) ) { + } elseif ( $object instanceof WP_Term ) { $type = $object->taxonomy; $id = $object->term_id; - } elseif ( is_a( $object, 'WP_User' ) ) { + } elseif ( $object instanceof WP_User ) { $type = 'user'; $id = $object->ID; - } elseif ( is_a( $object, 'WP_Comment' ) ) { + } elseif ( $object instanceof WP_Comment ) { $type = 'comment'; $id = $object->comment_ID; @@ -252,7 +248,7 @@ public static function save_handler( $object, $request, $creating ) { $pod_name = $type; - if ( 'attachment' === $type && is_a( $object, 'WP_Post' ) ) { + if ( 'attachment' === $type && $object instanceof WP_Post ) { $pod_name = 'media'; } diff --git a/classes/PodsTermSplitting.php b/classes/PodsTermSplitting.php index 7c3ede152f..e278a4f10b 100644 --- a/classes/PodsTermSplitting.php +++ b/classes/PodsTermSplitting.php @@ -18,7 +18,7 @@ class Pods_Term_Splitting { private $progress_option_name; /** @var array */ - private $previous_progress = array(); + private $previous_progress = []; /** * @param int $term_id ID of the formerly shared term. @@ -26,22 +26,20 @@ class Pods_Term_Splitting { * @param string $taxonomy Taxonomy for the split term. */ public function __construct( $term_id, $new_term_id, $taxonomy ) { - $this->term_id = $term_id; $this->new_term_id = $new_term_id; $this->taxonomy = $taxonomy; $this->progress_option_name = "_pods_term_split_{$term_id}_{$taxonomy}"; - } /** * */ public function split_shared_term() { - // Stash any previous progress $this->previous_progress = $this->get_progress(); + if ( empty( $this->previous_progress ) ) { $this->append_progress( 'started' ); $this->append_progress( "new term ID: {$this->new_term_id}" ); @@ -51,7 +49,7 @@ public function split_shared_term() { $taxonomy_pod = $this->get_pod_info(); // Is the taxonomy a Pod? - if ( is_array( $taxonomy_pod ) ) { + if ( is_array( $taxonomy_pod ) || $taxonomy_pod instanceof Pods\Whatsit ) { $this->update_podsrel_taxonomy( $taxonomy_pod['id'] ); // Update the Pods table if the taxonomy is a table based Pod @@ -65,7 +63,6 @@ public function split_shared_term() { // Clean up $this->delete_progress(); - } /** @@ -74,93 +71,119 @@ public function split_shared_term() { * @return array|bool|mixed|null */ private function get_pod_info() { - $pod_info = null; - if ( pods_api()->pod_exists( $this->taxonomy ) ) { + try { + $api = pods_api(); - // Load the taxonomy Pod - $params = array( - 'name' => $this->taxonomy, - 'table_info' => true, - ); - $pod_info = pods_api()->load_pod( $params, false ); + if ( $api->pod_exists( [ 'name' => $this->taxonomy ] ) ) { + // Load the taxonomy Pod + $params = [ + 'name' => $this->taxonomy, + ]; + + $pod_info = $api->load_pod( $params, false ); + } + } catch ( Exception $exception ) { + // Do nothing. } return $pod_info; - } /** * @param int $pod_id */ private function update_podsrel_taxonomy( $pod_id ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; $task = "update_podsrel_taxonomy_{$pod_id}"; + if ( ! $this->have_done( $task ) ) { + if ( pods_podsrel_enabled() ) { + // UPDATE {$wpdb->prefix}podsrel SET item_id = {$new_term_id} WHERE pod_id = {$pod_id} AND item_id = {$term_id} + $table = "{$wpdb->prefix}podsrel"; - // UPDATE {$wpdb->prefix}podsrel SET item_id = {$new_term_id} WHERE pod_id = {$pod_id} AND item_id = {$term_id} - $table = "{$wpdb->prefix}podsrel"; - $data = array( 'item_id' => $this->new_term_id ); - $where = array( - 'pod_id' => $pod_id, - 'item_id' => $this->term_id, - ); - $format = '%d'; - $where_format = '%d'; + $data = [ + 'item_id' => $this->new_term_id, + ]; - $wpdb->update( $table, $data, $where, $format, $where_format ); + $where = [ + 'pod_id' => $pod_id, + 'item_id' => $this->term_id, + ]; + + $format = '%d'; + $where_format = '%d'; + + $wpdb->update( $table, $data, $where, $format, $where_format ); + } + + /** + * Allow hooking into the term splitting process for taxonomy. + * + * @since 2.8.0 + * + * @param int $pod_id The pod ID for the taxonomy. + * @param int $term_id The current term ID being split. + * @param int $new_term_id The new term ID. + * @param string $task The task being done. + */ + do_action( 'pods_term_splitting_update_taxonomy', $pod_id, $this->term_id, $this->new_term_id, $task ); $this->append_progress( $task ); } - } /** * @param string $pod_table */ private function update_pod_table( $pod_table ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; $task = "update_pod_table_{$pod_table}"; - if ( ! $this->have_done( $task ) ) { + if ( ! $this->have_done( $task ) ) { // Prime the values and update - $data = array( 'id' => $this->new_term_id ); - $where = array( 'id' => $this->term_id ); + $data = [ + 'id' => $this->new_term_id, + ]; + + $where = [ + 'id' => $this->term_id, + ]; + $format = '%d'; $where_format = '%d'; + $wpdb->update( $pod_table, $data, $where, $format, $where_format ); $this->append_progress( $task ); } - } /** * Track down all fields related to the target taxonomy and update stored term IDs as necessary */ private function update_relationships_to_term() { - // Loop through all Pods - $all_pods = pods_api()->load_pods(); + try { + $all_pods = pods_api()->load_pods(); + } catch ( Exception $exception ) { + return; + } if ( ! is_array( $all_pods ) ) { return; } foreach ( $all_pods as $this_pod_id => $this_pod ) { - // Loop through all fields in this Pod foreach ( $this_pod['fields'] as $this_field_name => $this_field ) { - // Ignore everything except relationship fields to this taxonomy - if ( 'pick' !== $this_field['type'] || 'taxonomy' !== $this_field['pick_object'] || $this->taxonomy != $this_field['pick_val'] ) { + if ( 'pick' !== $this_field['type'] || 'taxonomy' !== $this_field['pick_object'] || $this->taxonomy !== $this_field['pick_val'] ) { continue; } @@ -169,7 +192,6 @@ private function update_relationships_to_term() { // Fix-up any special-case relationships that store term IDs in their own meta table and/or serialized switch ( $this_pod['type'] ) { - case 'post_type': $this->update_postmeta( $this_pod['name'], $this_field_name ); break; @@ -195,29 +217,45 @@ private function update_relationships_to_term() { * @param int $field_id */ private function update_podsrel_related_term( $field_id ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; $task = "update_podsrel_related_term_{$field_id}"; + if ( ! $this->have_done( $task ) ) { + if ( pods_podsrel_enabled() ) { + // UPDATE {$wpdb->prefix}podsrel SET related_item_id = {$new_term_id} WHERE field_id = {$field_id} AND related_item_id = {$term_id} + $table = "{$wpdb->prefix}podsrel"; - // UPDATE {$wpdb->prefix}podsrel SET related_item_id = {$new_term_id} WHERE field_id = {$field_id} AND related_item_id = {$term_id} - $table = "{$wpdb->prefix}podsrel"; - $data = array( - 'related_item_id' => $this->new_term_id, - ); - $where = array( - 'field_id' => $field_id, - 'related_item_id' => $this->term_id, - ); - $format = '%d'; - $where_format = '%d'; - $wpdb->update( $table, $data, $where, $format, $where_format ); + $data = [ + 'related_item_id' => $this->new_term_id, + ]; + + $where = [ + 'field_id' => $field_id, + 'related_item_id' => $this->term_id, + ]; + + $format = '%d'; + $where_format = '%d'; + + $wpdb->update( $table, $data, $where, $format, $where_format ); + } + + /** + * Allow hooking into the term splitting process for taxonomy by related term. + * + * @since 2.8.0 + * + * @param int $field_id The field ID for the relationship. + * @param int $term_id The current term ID being split. + * @param int $new_term_id The new term ID. + * @param string $task The task being done. + */ + do_action( 'pods_term_splitting_update_related_term', $field_id, $this->term_id, $this->new_term_id, $task ); $this->append_progress( $task ); } - } /** @@ -227,17 +265,13 @@ private function update_podsrel_related_term( $field_id ) { * @param string $field_name */ private function update_postmeta( $pod_name, $field_name ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; // Fix up the unserialized data $task = "update_postmeta_{$pod_name}_{$field_name}_unserialized"; if ( ! $this->have_done( $task ) ) { - - $wpdb->query( - $wpdb->prepare( - " + $wpdb->query( $wpdb->prepare( " UPDATE {$wpdb->postmeta} AS meta LEFT JOIN {$wpdb->posts} AS t @@ -248,9 +282,7 @@ private function update_postmeta( $pod_name, $field_name ) { meta_key = %s AND meta_value = %s AND t.post_type = %s - ", $this->new_term_id, $field_name, $this->term_id, $pod_name - ) - ); + ", $this->new_term_id, $field_name, $this->term_id, $pod_name ) ); $this->append_progress( $task ); }//end if @@ -258,14 +290,11 @@ private function update_postmeta( $pod_name, $field_name ) { // Fix up the serialized data $task = "update_postmeta_{$pod_name}_{$field_name}_serialized"; if ( ! $this->have_done( $task ) ) { - $meta_key = sprintf( '_pods_%s', $field_name ); $target_serialized = sprintf( ';i:%s;', $this->term_id ); $replace_serialized = sprintf( ';i:%s;', $this->new_term_id ); - $wpdb->query( - $wpdb->prepare( - " + $wpdb->query( $wpdb->prepare( " UPDATE {$wpdb->postmeta} AS meta LEFT JOIN {$wpdb->posts} AS t @@ -276,9 +305,7 @@ private function update_postmeta( $pod_name, $field_name ) { meta.meta_key = %s AND t.post_type = %s AND meta_value LIKE '%%%s%%' - ", $target_serialized, $replace_serialized, $meta_key, $pod_name, pods_sanitize_like( $target_serialized ) - ) - ); + ", $target_serialized, $replace_serialized, $meta_key, $pod_name, pods_sanitize_like( $target_serialized ) ) ); $this->append_progress( $task ); }//end if @@ -291,22 +318,20 @@ private function update_postmeta( $pod_name, $field_name ) { * @param string $field_name */ private function update_commentmeta( $field_name ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; // Fix up the unserialized data $task = "update_commentmeta_{$field_name}_unserialized"; if ( ! $this->have_done( $task ) ) { - $table = $wpdb->commentmeta; - $data = array( 'meta_value' => $this->new_term_id ); - $where = array( + $data = [ 'meta_value' => $this->new_term_id ]; + $where = [ 'meta_key' => $field_name, 'meta_value' => $this->term_id, - ); + ]; $format = '%s'; - $where_format = array( '%s', '%s' ); + $where_format = [ '%s', '%s' ]; $wpdb->update( $table, $data, $where, $format, $where_format ); $this->append_progress( $task ); @@ -315,14 +340,11 @@ private function update_commentmeta( $field_name ) { // Fix up the serialized data $task = "update_commentmeta_{$field_name}_serialized"; if ( ! $this->have_done( $task ) ) { - $meta_key = sprintf( '_pods_%s', $field_name ); $target_serialized = sprintf( ';i:%s;', $this->term_id ); $replace_serialized = sprintf( ';i:%s;', $this->new_term_id ); - $wpdb->query( - $wpdb->prepare( - " + $wpdb->query( $wpdb->prepare( " UPDATE {$wpdb->commentmeta} SET @@ -330,9 +352,7 @@ private function update_commentmeta( $field_name ) { WHERE meta_key = %s AND meta_value LIKE '%%%s%%' - ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized ) - ) - ); + ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized ) ) ); $this->append_progress( $task ); }//end if @@ -345,22 +365,20 @@ private function update_commentmeta( $field_name ) { * @param string $field_name */ private function update_usermeta( $field_name ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; // Fix up the unserialized data $task = "update_usermeta_{$field_name}_unserialized"; if ( ! $this->have_done( $task ) ) { - $table = $wpdb->usermeta; - $data = array( 'meta_value' => $this->new_term_id ); - $where = array( + $data = [ 'meta_value' => $this->new_term_id ]; + $where = [ 'meta_key' => $field_name, 'meta_value' => $this->term_id, - ); + ]; $format = '%s'; - $where_format = array( '%s', '%s' ); + $where_format = [ '%s', '%s' ]; $wpdb->update( $table, $data, $where, $format, $where_format ); $this->append_progress( $task ); @@ -369,14 +387,11 @@ private function update_usermeta( $field_name ) { // Fix up the serialized data $task = "update_usermeta_{$field_name}_serialized"; if ( ! $this->have_done( $task ) ) { - $meta_key = sprintf( '_pods_%s', $field_name ); $target_serialized = sprintf( ';i:%s;', $this->term_id ); $replace_serialized = sprintf( ';i:%s;', $this->new_term_id ); - $wpdb->query( - $wpdb->prepare( - " + $wpdb->query( $wpdb->prepare( " UPDATE {$wpdb->usermeta} SET @@ -384,9 +399,7 @@ private function update_usermeta( $field_name ) { WHERE meta_key = %s AND meta_value LIKE '%%%s%%' - ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized ) - ) - ); + ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized ) ) ); $this->append_progress( $task ); }//end if @@ -400,8 +413,7 @@ private function update_usermeta( $field_name ) { * @param string $field_name */ private function update_setting_meta( $pod_name, $field_name ) { - - /** @global wpdb $wpdb */ + /** @var wpdb $wpdb */ global $wpdb; $option_name = "{$pod_name}_{$field_name}"; @@ -409,16 +421,15 @@ private function update_setting_meta( $pod_name, $field_name ) { // Fix up the unserialized data $task = "update_setting_meta_{$pod_name}_{$field_name}_unserialized"; if ( ! $this->have_done( $task ) ) { - // UPDATE {$wpdb->options} SET option_value = '{$new_term_id}' WHERE option_name = '{$pod_name}_{$field_name}' AND option_value = '{$term_id}' $table = $wpdb->options; - $data = array( 'option_value' => $this->new_term_id ); - $where = array( + $data = [ 'option_value' => $this->new_term_id ]; + $where = [ 'option_name' => $option_name, 'option_value' => $this->term_id, - ); + ]; $format = '%s'; - $where_format = array( '%s', '%s' ); + $where_format = [ '%s', '%s' ]; $wpdb->update( $table, $data, $where, $format, $where_format ); $this->append_progress( $task ); @@ -427,13 +438,10 @@ private function update_setting_meta( $pod_name, $field_name ) { // Fix up the serialized data $task = "update_setting_meta_{$pod_name}_{$field_name}_serialized"; if ( ! $this->have_done( $task ) ) { - $target_serialized = sprintf( ';i:%s;', $this->term_id ); $replace_serialized = sprintf( ';i:%s;', $this->new_term_id ); - $wpdb->query( - $wpdb->prepare( - " + $wpdb->query( $wpdb->prepare( " UPDATE {$wpdb->options} SET @@ -441,9 +449,7 @@ private function update_setting_meta( $pod_name, $field_name ) { WHERE option_name = %s AND option_value LIKE '%%%s%%' - ", $target_serialized, $replace_serialized, $option_name, pods_sanitize_like( $target_serialized ) - ) - ); + ", $target_serialized, $replace_serialized, $option_name, pods_sanitize_like( $target_serialized ) ) ); $this->append_progress( $task ); }//end if @@ -456,32 +462,28 @@ private function update_setting_meta( $pod_name, $field_name ) { * @return bool */ private function have_done( $task_name ) { - - return in_array( $task_name, $this->previous_progress ); - + return in_array( $task_name, $this->previous_progress, true ); } /** * @return array */ private function get_progress() { - - return get_option( $this->progress_option_name, array() ); + return get_option( $this->progress_option_name, [] ); } /** * @param $data */ private function append_progress( $data ) { - // Get the current progress array $current_progress = $this->get_progress(); if ( ! is_array( $current_progress ) ) { - $current_progress = array(); + $current_progress = []; } // Tack on the new data - $updated_progress = array_merge( $current_progress, array( $data ) ); + $updated_progress = array_merge( $current_progress, [ $data ] ); // Note: we don't want autoload set and you cannot specify autoload via update_option if ( ! empty( $current_progress ) && is_array( $current_progress ) ) { @@ -489,16 +491,13 @@ private function append_progress( $data ) { } else { add_option( $this->progress_option_name, $updated_progress, '', false ); } - } /** * */ private function delete_progress() { - delete_option( $this->progress_option_name ); - } } diff --git a/classes/PodsUI.php b/classes/PodsUI.php index 47e682b074..af482dc5c3 100644 --- a/classes/PodsUI.php +++ b/classes/PodsUI.php @@ -1,5 +1,7 @@ _nonce = pods_v( $this->num_prefix . '_wpnonce' . $this->num, 'request' ); @@ -529,10 +531,6 @@ public function __construct( $options, $deprecated = false ) { $this->pod = $object; } - if ( false !== $deprecated || ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) ) ) { - $options = $this->setup_deprecated( $options ); - } - if ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) && is_object( $this->pod->_data ) ) { $this->pods_data =& $this->pod->_data; } elseif ( is_object( $this->pod ) && 'Pods' == get_class( $this->pod ) && is_object( $this->pod->data ) ) { @@ -563,370 +561,18 @@ public function __construct( $options, $deprecated = false ) { // Assign pod labels // @todo This is also done in setup(), maybe a better / more central way? - if ( is_object( $this->pod ) && ! empty( $this->pod->pod_data['options'] ) ) { - $pod_options = $this->pod->pod_data['options']; - $pod_name = $this->pod->pod_data['name']; - $pod_options = apply_filters( "pods_advanced_content_type_pod_data_{$pod_name}", $pod_options, $this->pod->pod_data['name'] ); - $pod_options = apply_filters( 'pods_advanced_content_type_pod_data', $pod_options, $this->pod->pod_data['name'] ); + if ( is_object( $this->pod ) && ! empty( $this->pod->pod_data ) ) { + $pod_data = $this->pod->pod_data; + $pod_name = $this->pod->pod_data['name']; + $pod_data = apply_filters( "pods_advanced_content_type_pod_data_{$pod_name}", $pod_data, $this->pod->pod_data['name'] ); + $pod_data = apply_filters( 'pods_advanced_content_type_pod_data', $pod_data, $this->pod->pod_data['name'] ); - $this->label = array_merge( $this->label, $pod_options ); + $this->label = array_merge( $this->label, $pod_data['options'] ); } $this->go(); } - /** - * @param $deprecated_options - * - * @return array - */ - public function setup_deprecated( $deprecated_options ) { - - $options = array(); - - if ( isset( $deprecated_options['id'] ) ) { - $options['id'] = $deprecated_options['id']; - } - if ( isset( $deprecated_options['action'] ) ) { - $options['action'] = $deprecated_options['action']; - } - if ( isset( $deprecated_options['num'] ) ) { - $options['num'] = $deprecated_options['num']; - } - - if ( isset( $deprecated_options['title'] ) ) { - $options['items'] = $deprecated_options['title']; - } - if ( isset( $deprecated_options['item'] ) ) { - $options['item'] = $deprecated_options['item']; - } - - if ( isset( $deprecated_options['label'] ) ) { - $options['label'] = array( - 'add' => $deprecated_options['label'], - 'edit' => $deprecated_options['label'], - 'duplicate' => $deprecated_options['label'], - ); - } - if ( isset( $deprecated_options['label_add'] ) ) { - if ( isset( $options['label'] ) ) { - $options['label']['add'] = $deprecated_options['label_add']; - } else { - $options['label'] = array( 'add' => $deprecated_options['label_add'] ); - } - } - if ( isset( $deprecated_options['label_edit'] ) ) { - if ( isset( $options['label'] ) ) { - $options['label']['edit'] = $deprecated_options['label_edit']; - } else { - $options['label'] = array( 'edit' => $deprecated_options['label_edit'] ); - } - } - if ( isset( $deprecated_options['label_duplicate'] ) ) { - if ( isset( $options['label'] ) ) { - $options['label']['duplicate'] = $deprecated_options['label_duplicate']; - } else { - $options['label'] = array( 'duplicate' => $deprecated_options['label_duplicate'] ); - } - } - - if ( isset( $deprecated_options['icon'] ) ) { - $options['icon'] = $deprecated_options['icon']; - } - - if ( isset( $deprecated_options['columns'] ) ) { - $options['fields'] = array( 'manage' => $deprecated_options['columns'] ); - } - if ( isset( $deprecated_options['reorder_columns'] ) ) { - if ( isset( $options['fields'] ) ) { - $options['fields']['reorder'] = $deprecated_options['reorder_columns']; - } else { - $options['fields'] = array( 'reorder' => $deprecated_options['reorder_columns'] ); - } - } - if ( isset( $deprecated_options['add_fields'] ) ) { - if ( isset( $options['fields'] ) ) { - if ( ! isset( $options['fields']['add'] ) ) { - $options['fields']['add'] = $deprecated_options['add_fields']; - } - if ( ! isset( $options['fields']['edit'] ) ) { - $options['fields']['edit'] = $deprecated_options['add_fields']; - } - if ( ! isset( $options['fields']['duplicate'] ) ) { - $options['fields']['duplicate'] = $deprecated_options['add_fields']; - } - } else { - $options['fields'] = array( - 'add' => $deprecated_options['add_fields'], - 'edit' => $deprecated_options['add_fields'], - 'duplicate' => $deprecated_options['add_fields'], - ); - } - } - if ( isset( $deprecated_options['edit_fields'] ) ) { - if ( isset( $options['fields'] ) ) { - if ( ! isset( $options['fields']['add'] ) ) { - $options['fields']['add'] = $deprecated_options['edit_fields']; - } - if ( ! isset( $options['fields']['edit'] ) ) { - $options['fields']['edit'] = $deprecated_options['edit_fields']; - } - if ( ! isset( $options['fields']['duplicate'] ) ) { - $options['fields']['duplicate'] = $deprecated_options['edit_fields']; - } - } else { - $options['fields'] = array( - 'add' => $deprecated_options['edit_fields'], - 'edit' => $deprecated_options['edit_fields'], - 'duplicate' => $deprecated_options['edit_fields'], - ); - } - } - if ( isset( $deprecated_options['duplicate_fields'] ) ) { - if ( isset( $options['fields'] ) ) { - $options['fields']['duplicate'] = $deprecated_options['duplicate_fields']; - } else { - $options['fields'] = array( 'duplicate' => $deprecated_options['duplicate_fields'] ); - } - } - - if ( isset( $deprecated_options['session_filters'] ) && false === $deprecated_options['session_filters'] ) { - $options['session'] = false; - } - if ( isset( $deprecated_options['user_per_page'] ) ) { - if ( isset( $options['user'] ) && ! empty( $options['user'] ) ) { - $options['user'] = array( 'orderby' ); - } else { - $options['user'] = false; - } - } - if ( isset( $deprecated_options['user_sort'] ) ) { - if ( isset( $options['user'] ) && ! empty( $options['user'] ) ) { - $options['user'] = array( 'show_per_page' ); - } else { - $options['user'] = false; - } - } - - if ( isset( $deprecated_options['custom_list'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['manage'] = $deprecated_options['custom_list']; - } else { - $options['actions_custom'] = array( 'manage' => $deprecated_options['custom_list'] ); - } - } - if ( isset( $deprecated_options['custom_reorder'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['reorder'] = $deprecated_options['custom_reorder']; - } else { - $options['actions_custom'] = array( 'reorder' => $deprecated_options['custom_reorder'] ); - } - } - if ( isset( $deprecated_options['custom_add'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['add'] = $deprecated_options['custom_add']; - } else { - $options['actions_custom'] = array( 'add' => $deprecated_options['custom_add'] ); - } - } - if ( isset( $deprecated_options['custom_edit'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['edit'] = $deprecated_options['custom_edit']; - } else { - $options['actions_custom'] = array( 'edit' => $deprecated_options['custom_edit'] ); - } - } - if ( isset( $deprecated_options['custom_duplicate'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['duplicate'] = $deprecated_options['custom_duplicate']; - } else { - $options['actions_custom'] = array( 'duplicate' => $deprecated_options['custom_duplicate'] ); - } - } - if ( isset( $deprecated_options['custom_delete'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['delete'] = $deprecated_options['custom_delete']; - } else { - $options['actions_custom'] = array( 'delete' => $deprecated_options['custom_delete'] ); - } - } - if ( isset( $deprecated_options['custom_save'] ) ) { - if ( isset( $options['actions_custom'] ) ) { - $options['actions_custom']['save'] = $deprecated_options['custom_save']; - } else { - $options['actions_custom'] = array( 'save' => $deprecated_options['custom_save'] ); - } - } - - if ( isset( $deprecated_options['custom_actions'] ) ) { - $options['actions_custom'] = $deprecated_options['custom_actions']; - } - if ( isset( $deprecated_options['action_after_save'] ) ) { - $options['action_after'] = array( - 'add' => $deprecated_options['action_after_save'], - 'edit' => $deprecated_options['action_after_save'], - 'duplicate' => $deprecated_options['action_after_save'], - ); - } - if ( isset( $deprecated_options['edit_link'] ) ) { - if ( isset( $options['action_links'] ) ) { - $options['action_links']['edit'] = $deprecated_options['edit_link']; - } else { - $options['action_links'] = array( 'edit' => $deprecated_options['edit_link'] ); - } - } - if ( isset( $deprecated_options['view_link'] ) ) { - if ( isset( $options['action_links'] ) ) { - $options['action_links']['view'] = $deprecated_options['view_link']; - } else { - $options['action_links'] = array( 'view' => $deprecated_options['view_link'] ); - } - } - if ( isset( $deprecated_options['duplicate_link'] ) ) { - if ( isset( $options['action_links'] ) ) { - $options['action_links']['duplicate'] = $deprecated_options['duplicate_link']; - } else { - $options['action_links'] = array( 'duplicate' => $deprecated_options['duplicate_link'] ); - } - } - - if ( isset( $deprecated_options['reorder'] ) ) { - $options['reorder'] = array( - 'on' => $deprecated_options['reorder'], - 'orderby' => $deprecated_options['reorder'], - ); - } - if ( isset( $deprecated_options['reorder_sort'] ) && isset( $options['reorder'] ) ) { - $options['reorder']['orderby'] = $deprecated_options['reorder_sort']; - } - if ( isset( $deprecated_options['reorder_limit'] ) && isset( $options['reorder'] ) ) { - $options['reorder']['limit'] = $deprecated_options['reorder_limit']; - } - if ( isset( $deprecated_options['reorder_sql'] ) && isset( $options['reorder'] ) ) { - $options['reorder']['sql'] = $deprecated_options['reorder_sql']; - } - - if ( isset( $deprecated_options['sort'] ) ) { - $options['orderby'] = $deprecated_options['sort']; - } - if ( isset( $deprecated_options['sortable'] ) ) { - $options['sortable'] = $deprecated_options['sortable']; - } - if ( isset( $deprecated_options['limit'] ) ) { - $options['limit'] = $deprecated_options['limit']; - } - - if ( isset( $deprecated_options['where'] ) ) { - if ( isset( $options['where'] ) ) { - $options['where']['manage'] = $deprecated_options['where']; - } else { - $options['where'] = array( 'manage' => $deprecated_options['where'] ); - } - } - if ( isset( $deprecated_options['edit_where'] ) ) { - /* - if ( isset( $options[ 'where' ] ) ) - $options[ 'where' ][ 'edit' ] = $deprecated_options[ 'edit_where' ]; - else - $options[ 'where' ] = array( 'edit' => $deprecated_options[ 'edit_where' ] );*/ - - if ( isset( $options['restrict'] ) ) { - $options['restrict']['edit'] = (array) $deprecated_options['edit_where']; - } else { - $options['restrict'] = array( 'edit' => (array) $deprecated_options['edit_where'] ); - } - } - if ( isset( $deprecated_options['duplicate_where'] ) ) { - /* - if ( isset( $options[ 'where' ] ) ) - $options[ 'where' ][ 'duplicate' ] = $deprecated_options[ 'duplicate_where' ]; - else - $options[ 'where' ] = array( 'duplicate' => $deprecated_options[ 'duplicate_where' ] );*/ - - if ( isset( $options['restrict'] ) ) { - $options['restrict']['duplicate'] = (array) $deprecated_options['duplicate_where']; - } else { - $options['restrict'] = array( 'duplicate' => (array) $deprecated_options['duplicate_where'] ); - } - } - if ( isset( $deprecated_options['delete_where'] ) ) { - /* - if ( isset( $options[ 'where' ] ) ) - $options[ 'where' ][ 'delete' ] = $deprecated_options[ 'delete_where' ]; - else - $options[ 'where' ] = array( 'delete' => $deprecated_options[ 'delete_where' ] );*/ - - if ( isset( $options['restrict'] ) ) { - $options['restrict']['delete'] = (array) $deprecated_options['delete_where']; - } else { - $options['restrict'] = array( 'delete' => (array) $deprecated_options['delete_where'] ); - } - } - if ( isset( $deprecated_options['reorder_where'] ) ) { - if ( isset( $options['where'] ) ) { - $options['where']['reorder'] = $deprecated_options['reorder_where']; - } else { - $options['where'] = array( 'reorder' => $deprecated_options['reorder_where'] ); - } - } - - if ( isset( $deprecated_options['sql'] ) ) { - $options['sql'] = array( 'sql' => $deprecated_options['sql'] ); - } - - if ( isset( $deprecated_options['search'] ) ) { - $options['searchable'] = $deprecated_options['search']; - } - if ( isset( $deprecated_options['search_across'] ) ) { - $options['search_across'] = $deprecated_options['search_across']; - } - if ( isset( $deprecated_options['search_across_picks'] ) ) { - $options['search_across_picks'] = $deprecated_options['search_across_picks']; - } - if ( isset( $deprecated_options['filters'] ) ) { - $options['filters'] = $deprecated_options['filters']; - } - if ( isset( $deprecated_options['custom_filters'] ) ) { - if ( is_callable( $deprecated_options['custom_filters'] ) ) { - add_filter( 'pods_ui_filters', $deprecated_options['custom_filters'] ); - } else { - global $pods_ui_custom_filters; - $pods_ui_custom_filters = $deprecated_options['custom_filters']; - add_filter( 'pods_ui_filters', array( $this, 'deprecated_filters' ) ); - } - } - - if ( isset( $deprecated_options['disable_actions'] ) ) { - $options['actions_disabled'] = $deprecated_options['disable_actions']; - } - if ( isset( $deprecated_options['hide_actions'] ) ) { - $options['actions_hidden'] = $deprecated_options['hide_actions']; - } - - if ( isset( $deprecated_options['wpcss'] ) ) { - $options['wpcss'] = $deprecated_options['wpcss']; - } - - $remaining_options = array_diff_assoc( $options, $deprecated_options ); - - foreach ( $remaining_options as $option => $value ) { - if ( isset( $deprecated_options[ $option ] ) && isset( $this->$option ) ) { - $options[ $option ] = $value; - } - } - - return $options; - } - - /** - * - */ - public function deprecated_filters() { - - global $pods_ui_custom_filters; - echo $pods_ui_custom_filters; - } - /** * @param $options * @@ -947,10 +593,10 @@ public function setup( $options ) { $options->num = ''; } - $options->validate( 'id', pods_var( $options->num_prefix . 'id' . $options->num, 'get', $this->id ) ); + $options->validate( 'id', pods_v( $options->num_prefix . 'id' . $options->num, 'get', $this->id ) ); $options->validate( - 'do', pods_var( $options->num_prefix . 'do' . $options->num, 'get', $this->do ), 'in_array', array( + 'do', pods_v( $options->num_prefix . 'do' . $options->num, 'get', $this->do ), 'in_array', array( 'save', 'create', ) @@ -958,14 +604,14 @@ public function setup( $options ) { $options->validate( 'excluded', self::$excluded, 'array_merge' ); - $options->validate( 'action', pods_var( $options->num_prefix . 'action' . $options->num, 'get', $this->action, null, true ), 'in_array', $this->actions ); + $options->validate( 'action', pods_v( $options->num_prefix . 'action' . $options->num, 'get', $this->action, true ), 'in_array', $this->actions ); $options->validate( 'actions_bulk', $this->actions_bulk, 'array_merge' ); - $options->validate( 'action_bulk', pods_var( $options->num_prefix . 'action_bulk' . $options->num, 'get', $this->action_bulk, null, true ), 'isset', $this->actions_bulk ); + $options->validate( 'action_bulk', pods_v( $options->num_prefix . 'action_bulk' . $options->num, 'get', $this->action_bulk, true ), 'isset', $this->actions_bulk ); - $bulk = pods_var( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), null, true ); + $bulk = pods_v( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), true ); if ( ! empty( $bulk ) ) { - $bulk = (array) pods_var( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), null, true ); + $bulk = (array) pods_v( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), true ); } else { $bulk = array(); } @@ -990,12 +636,13 @@ public function setup( $options ) { $options->validate( 'limit', pods_v( $options->num_prefix . 'limit' . $options->num, 'get', $this->limit ), 'int' ); if ( isset( $this->pods_data ) && is_object( $this->pods_data ) ) { - $this->sql = array( + $this->sql = array_merge( $this->sql, array_filter( [ 'table' => $this->pods_data->table, 'field_id' => $this->pods_data->field_id, 'field_index' => $this->pods_data->field_index, - ); + ] ) ); } + $options->validate( 'sql', $this->sql, 'array_merge' ); $options->validate( @@ -1082,7 +729,7 @@ public function setup( $options ) { $this->label = array_merge( $this->label, $pod_data['options'] ); - $item = pods_v( 'label_singular', $pod_data['options'], pods_v( 'label', $pod_data, $item, true ), true ); + $item = pods_v( 'label_singular', $pod_data, pods_v( 'label', $pod_data, $item, true ), true ); $items = pods_v( 'label', $pod_data, $items, true ); } @@ -1130,9 +777,16 @@ public function setup( $options ) { // Set up default manage field. if ( empty( $options->fields['manage'] ) ) { - $options->fields['manage'][ $options->sql['field_index'] ] = array( - 'label' => __( 'Name', 'pods' ), - ); + // Make a local copy of the fields. + $fields = $options->fields; + + // Change the info. + $fields['manage'][ $options->sql['field_index'] ] = [ + 'label' => __( 'Name', 'pods' ), + ]; + + // Set the object fields property. + $options->fields = $fields; } $options->validate( 'export', $this->export, 'array_merge' ); @@ -1225,7 +879,7 @@ public function setup( $options ) { } } - $unique_identifier = pods_var( 'page' ); + $unique_identifier = pods_v( 'page' ); // wp-admin page if ( is_object( $this->pod ) && isset( $this->pod->pod ) ) { $unique_identifier = '_' . $this->pod->pod; @@ -1306,6 +960,8 @@ public function setup_fields( $fields = null, $which = 'fields' ) { if ( is_int( $field ) ) { $field = $attributes; $attributes = array(); + } elseif ( $attributes instanceof Field ) { + $attributes = $attributes->get_args(); } else { $attributes = array( 'label' => $attributes ); } @@ -1315,17 +971,20 @@ public function setup_fields( $fields = null, $which = 'fields' ) { $attributes['name'] = $field; } - if ( ! isset( $attributes['real_name'] ) ) { - $attributes['real_name'] = pods_var( 'name', $attributes, $field ); - } + $field_name = pods_v( 'real_name', $attributes, pods_v( 'name', $attributes, $field ) ); + + if ( is_object( $this->pod ) ) { + $field_attributes = $this->pod->fields( $field_name ); - if ( is_object( $this->pod ) && isset( $this->pod->fields ) && isset( $this->pod->fields[ $attributes['real_name'] ] ) ) { - $attributes = array_merge( $this->pod->fields[ $attributes['real_name'] ], $attributes ); + if ( $field_attributes ) { + $attributes = pods_config_merge_data( $field_attributes, $attributes ); + } } - if ( ! isset( $attributes['options'] ) ) { - $attributes['options'] = array(); + if ( ! empty( $attributes['options'] ) && is_array( $attributes['options'] ) ) { + $attributes = pods_config_merge_data( $attributes['options'], $attributes ); } + if ( ! isset( $attributes['id'] ) ) { $attributes['id'] = ''; } @@ -1335,8 +994,8 @@ public function setup_fields( $fields = null, $which = 'fields' ) { if ( ! isset( $attributes['type'] ) ) { $attributes['type'] = 'text'; } - if ( ! isset( $attributes['options']['date_format_type'] ) ) { - $attributes['options']['date_format_type'] = 'date'; + if ( ! isset( $attributes['date_format_type'] ) ) { + $attributes['date_format_type'] = 'date'; } if ( 'related' !== $attributes['type'] || ! isset( $attributes['related'] ) ) { $attributes['related'] = false; @@ -1388,25 +1047,25 @@ public function setup_fields( $fields = null, $which = 'fields' ) { if ( ! isset( $attributes['sortable'] ) || false === $this->sortable ) { $attributes['sortable'] = $this->sortable; } - if ( ! isset( $attributes['options']['search'] ) || false === $this->searchable ) { - $attributes['options']['search'] = $this->searchable; + if ( ! isset( $attributes['search'] ) || false === $this->searchable ) { + $attributes['search'] = $this->searchable; } - if ( ! isset( $attributes['options']['filter'] ) || false === $this->searchable ) { - $attributes['options']['filter'] = $this->searchable; + if ( ! isset( $attributes['filter'] ) || false === $this->searchable ) { + $attributes['filter'] = $this->searchable; } /* if ( false !== $attributes[ 'options' ][ 'filter' ] && false !== $filterable ) $this->filters[] = $field;*/ - if ( false === $attributes['options']['filter'] || ! isset( $attributes['filter_label'] ) || ! in_array( $field, $this->filters ) ) { + if ( false === $attributes['filter'] || ! isset( $attributes['filter_label'] ) || ! in_array( $field, $this->filters ) ) { $attributes['filter_label'] = $attributes['label']; } - if ( false === $attributes['options']['filter'] || ! isset( $attributes['filter_default'] ) || ! in_array( $field, $this->filters ) ) { + if ( false === $attributes['filter'] || ! isset( $attributes['filter_default'] ) || ! in_array( $field, $this->filters ) ) { $attributes['filter_default'] = false; } - if ( false === $attributes['options']['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! in_array( $field, $this->filters ) ) { + if ( false === $attributes['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! in_array( $field, $this->filters ) ) { $attributes['date_ongoing'] = false; } - if ( false === $attributes['options']['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! isset( $attributes['date_ongoing_default'] ) || ! in_array( $field, $this->filters ) ) { + if ( false === $attributes['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! isset( $attributes['date_ongoing_default'] ) || ! in_array( $field, $this->filters ) ) { $attributes['date_ongoing_default'] = false; } if ( ! isset( $attributes['export'] ) ) { @@ -1443,7 +1102,7 @@ public function setup_fields( $fields = null, $which = 'fields' ) { if ( ! isset( $attributes['css_values'] ) ) { $attributes['css_values'] = true; } - if ( 'search_columns' === $which && ! $attributes['options']['search'] ) { + if ( 'search_columns' === $which && ! $attributes['search'] ) { continue; } @@ -1679,7 +1338,7 @@ public function go() { } }//end if - if ( ! in_array( 'manage', $this->actions_disabled ) ) { + if ( ! in_array( 'manage', $this->actions_disabled, true ) ) { // handle session / user persistent settings for show_per_page, orderby, search, and filters $methods = array( 'session', 'user' ); @@ -1701,7 +1360,15 @@ public function go() { $value = $this->$setting; } - pods_v_set( $value, $setting, $method ); + $current_value = pods_v( $setting, $method ); + + if ( ! is_array( $current_value ) && ! is_array( $value ) ) { + if ( (string) $current_value !== (string) $value ) { + pods_v_set( $value, $setting, $method ); + } + } elseif ( $current_value !== $value ) { + pods_v_set( $value, $setting, $method ); + } } } @@ -1774,7 +1441,7 @@ public function edit( $duplicate = false ) { if ( $duplicate && false !== $this->callback_action( 'duplicate' ) ) { return null; - } elseif ( false !== $this->callback_action( 'edit', $duplicate ) ) { + } elseif ( false !== $this->callback_action( $this->action, $duplicate ) ) { return null; } @@ -1910,23 +1577,23 @@ public function form( $create = false, $duplicate = false ) { } if ( is_object( $this->pod ) ) { - $object_fields = (array) pods_var_raw( 'object_fields', $this->pod->pod_data, array(), null, true ); - - if ( empty( $object_fields ) && in_array( - $this->pod->pod_data['type'], array( - 'post_type', - 'taxonomy', - 'media', - 'user', - 'comment', - ) - ) ) { + $object_fields = $this->pod->pod_data->get_object_fields(); + + $object_field_objects = array( + 'post_type', + 'taxonomy', + 'media', + 'user', + 'comment', + ); + + if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects, true ) ) { $object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data ); } if ( empty( $fields ) ) { // Add core object fields if $fields is empty - $fields = array_merge( $object_fields, $this->pod->fields ); + $fields = $this->pod->pod_data->get_all_fields(); } } @@ -1941,7 +1608,9 @@ public function form( $create = false, $duplicate = false ) { 'name' => $name, ); - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $name = $field; $field = array( @@ -1949,24 +1618,28 @@ public function form( $create = false, $duplicate = false ) { ); } - $field = array_merge( $defaults, $field ); + $field = pods_config_merge_data( $defaults, $field ); $field['name'] = trim( $field['name'] ); - $default_value = pods_var_raw( 'default', $field ); - $value = pods_var_raw( 'value', $field ); + $default_value = pods_v( 'default', $field ); + $value = pods_v( 'value', $field ); if ( empty( $field['name'] ) ) { $field['name'] = trim( $name ); } if ( isset( $object_fields[ $field['name'] ] ) ) { - $field = array_merge( $field, $object_fields[ $field['name'] ] ); + $field_attributes = $object_fields[ $field['name'] ]; + + $field = pods_config_merge_data( $field, $field_attributes ); } elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) { - $field = array_merge( $this->pod->fields[ $field['name'] ], $field ); + $field_attributes = $this->pod->fields[ $field['name'] ]; + + $field = pods_config_merge_data( $field_attributes, $field ); } - if ( pods_var_raw( 'hidden', $field, false, null, true ) ) { + if ( pods_v( 'hidden', $field, false ) ) { $field['type'] = 'hidden'; } @@ -1990,11 +1663,15 @@ public function form( $create = false, $duplicate = false ) { $singular_label = $this->item; $plural_label = $this->items; - if ( is_object( $this->pod ) && 'settings' === $this->pod->pod_data['type'] && 'settings' === $this->style ) { - pods_view( PODS_DIR . 'ui/admin/form-settings.php', compact( array_keys( get_defined_vars() ) ) ); - } else { - pods_view( PODS_DIR . 'ui/admin/form.php', compact( array_keys( get_defined_vars() ) ) ); + $is_settings_pod = is_object( $this->pod ) && 'settings' === $this->pod->pod_data['type']; + + $form_type = 'post'; + + if ( 'settings' === $this->style || $is_settings_pod ) { + $form_type = 'settings'; } + + pods_view( PODS_DIR . 'ui/forms/form.php', compact( array_keys( get_defined_vars() ) ) ); } /** @@ -2025,7 +1702,7 @@ public function view() { } if ( is_object( $this->pod ) ) { - $object_fields = (array) pods_var_raw( 'object_fields', $this->pod->pod_data, array(), null, true ); + $object_fields = $this->pod->pod_data->get_object_fields(); $object_field_objects = array( 'post_type', @@ -2035,13 +1712,13 @@ public function view() { 'comment', ); - if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects ) ) { + if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects, true ) ) { $object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data ); } if ( empty( $fields ) ) { // Add core object fields if $fields is empty - $fields = array_merge( $object_fields, $this->pod->fields ); + $fields = $this->pod->pod_data->get_all_fields(); } } @@ -2058,7 +1735,9 @@ public function view() { 'options' => 'text', ); - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $name = $field; $field = array( @@ -2066,25 +1745,25 @@ public function view() { ); } - $field = array_merge( $defaults, $field ); + $field = pods_config_merge_data( $defaults, $field ); $field['name'] = trim( $field['name'] ); - $value = pods_var_raw( 'default', $field ); + $value = pods_v( 'default', $field ); if ( empty( $field['name'] ) ) { $field['name'] = trim( $name ); } - if ( isset( $object_fields[ $field['name'] ] ) ) { - $field = array_merge( $field, $object_fields[ $field['name'] ] ); - } elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) { - $field = array_merge( $this->pod->fields[ $field['name'] ], $field ); + $found_field = pods_config_get_field_from_all_fields( $field['name'], $this->pod ); + + if ( $found_field ) { + $field = pods_config_merge_data( $field, $found_field ); } if ( pods_v( 'hidden', $field, false, null, true ) || 'hidden' === $field['type'] ) { continue; - } elseif ( ! PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $pod->id() ) ) { + } elseif ( ! pods_permission( $field ) ) { continue; } @@ -2156,7 +1835,7 @@ public function view() { public function reorder() { // loop through order - $order = (array) pods_var_raw( 'order', 'post', array(), null, true ); + $order = (array) pods_v( 'order', 'post', array(), true ); $params = array( 'pod' => $this->pod->pod, @@ -2197,8 +1876,8 @@ public function save( $insert = false ) { foreach ( $this->fields['form'] as $field => $attributes ) { $vartype = '%s'; if ( 'bool' === $attributes['type'] ) { - $selected = ( 1 == pods_var( $field, 'post', 0 ) ) ? 1 : 0; - } elseif ( '' == pods_var( $field, 'post', '' ) ) { + $selected = ( 1 == pods_v( $field, 'post', 0 ) ) ? 1 : 0; + } elseif ( '' == pods_v( $field, 'post', '' ) ) { continue; } if ( false === $attributes['display'] || false !== $attributes['readonly'] ) { @@ -2220,29 +1899,29 @@ public function save( $insert = false ) { if ( false !== $attributes['date_touch'] || ( false !== $attributes['date_touch_on_create'] && true === $insert && $this->id < 1 ) ) { $value = date_i18n( $format ); } else { - $value = date_i18n( $format, strtotime( ( 'time' === $attributes['type'] ) ? date_i18n( 'Y-m-d ' ) : pods_var( $field, 'post', '' ) ) ); + $value = date_i18n( $format, strtotime( ( 'time' === $attributes['type'] ) ? date_i18n( 'Y-m-d ' ) : pods_v( $field, 'post', '' ) ) ); } } else { if ( 'bool' === $attributes['type'] ) { $vartype = '%d'; $value = 0; - if ( '' != pods_var( $field, 'post', '' ) ) { + if ( '' != pods_v( $field, 'post', '' ) ) { $value = 1; } } elseif ( 'number' === $attributes['type'] ) { $vartype = '%d'; - $value = number_format( pods_var( $field, 'post', 0 ), 0, '', '' ); + $value = number_format( pods_v( $field, 'post', 0 ), 0, '', '' ); } elseif ( 'decimal' === $attributes['type'] ) { $vartype = '%d'; - $value = number_format( pods_var( $field, 'post', 0 ), 2, '.', '' ); + $value = number_format( pods_v( $field, 'post', 0 ), 2, '.', '' ); } elseif ( 'related' === $attributes['type'] ) { - if ( is_array( pods_var( $field, 'post', '' ) ) ) { - $value = implode( ',', pods_var( $field, 'post', '' ) ); + if ( is_array( pods_v( $field, 'post', '' ) ) ) { + $value = implode( ',', pods_v( $field, 'post', '' ) ); } else { - $value = pods_var( $field, 'post', '' ); + $value = pods_v( $field, 'post', '' ); } } else { - $value = pods_var( $field, 'post', '' ); + $value = pods_v( $field, 'post', '' ); }//end if }//end if @@ -2261,14 +1940,27 @@ public function save( $insert = false ) { $values[] = $value; $data[ $field ] = $value; }//end foreach - $field_sql = implode( ',', $field_sql ); - if ( false === $insert && 0 < $this->id ) { - $this->insert_id = $this->id; - $values[] = $this->id; - $check = $wpdb->query( $wpdb->prepare( "UPDATE $this->sql['table'] SET $field_sql WHERE id=%d", $values ) ); + + if ( $this->pod instanceof Pods ) { + if ( false === $insert && 0 < $this->id ) { + $this->insert_id = $this->pod->save( $data ); + } else { + $this->insert_id = $this->pod->add( $data ); + } + + $check = 0 < $this->insert_id; } else { - $check = $wpdb->query( $wpdb->prepare( "INSERT INTO $this->sql['table'] SET $field_sql", $values ) ); + $field_sql = implode( ',', $field_sql ); + + if ( false === $insert && 0 < $this->id ) { + $this->insert_id = $this->id; + $values[] = $this->id; + $check = $wpdb->query( $wpdb->prepare( "UPDATE $this->sql['table'] SET $field_sql WHERE id=%d", $values ) ); + } else { + $check = $wpdb->query( $wpdb->prepare( "INSERT INTO $this->sql['table'] SET $field_sql", $values ) ); + } } + if ( $check ) { if ( empty( $this->insert_id ) ) { $this->insert_id = $wpdb->insert_id; @@ -2277,6 +1969,7 @@ public function save( $insert = false ) { } else { $this->error( sprintf( __( 'Error: %1\$s has not been %2\$s.', 'pods' ), $this->item, $action ) ); } + $this->do_hook( 'post_save', $this->insert_id, $data, $insert ); } @@ -2329,7 +2022,7 @@ public function delete_bulk() { $this->do_hook( 'pre_delete_bulk' ); - if ( 1 != pods_var( 'deleted_bulk', 'get', 0 ) ) { + if ( 1 != pods_v( 'deleted_bulk', 'get', 0 ) ) { $ids = $this->bulk; $success = false; @@ -2491,7 +2184,7 @@ public function export_fields_form() { public function export( $export_type = null ) { if ( empty( $export_type ) ) { - $export_type = pods_var( 'export_type', 'get', 'csv' ); + $export_type = pods_v( 'export_type', 'get', 'csv' ); } $export_type = trim( strtolower( $export_type ) ); @@ -2593,6 +2286,8 @@ public function get_params( $params = null, $action = null ) { $action = $this->action; } + $params = (array) $params; + $defaults = array( 'full' => false, 'flatten' => true, @@ -2802,7 +2497,7 @@ public function get_data( $params = null ) { $this->pods_data->select( $find_params ); if ( ! $params->full ) { - $this->data = $this->pods_data->data; + $this->data = $this->pods_data->rows; if ( ! empty( $this->data ) ) { $this->data_keys = array_keys( $this->data ); @@ -2811,7 +2506,7 @@ public function get_data( $params = null ) { $this->total = $this->pods_data->total(); $this->total_found = $this->pods_data->total_found(); } else { - $this->data_full = $this->pods_data->data; + $this->data_full = $this->pods_data->rows; if ( ! empty( $this->data_full ) ) { $this->data_keys = array_keys( $this->data_full ); @@ -3034,7 +2729,7 @@ public function manage( $reorder = false ) { $filter_field = $this->pod->fields[ $filter ]; if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) { - $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] ); + $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] ); } } elseif ( isset( $this->fields['manage'][ $filter ] ) ) { $filter_field = $this->fields['manage'][ $filter ]; @@ -3044,11 +2739,11 @@ public function manage( $reorder = false ) { } if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) { - if ( '' == pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true ) && '' == pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true ) ) { + if ( '' == pods_v( 'filter_' . $filter . '_start', 'get', '', true ) && '' == pods_v( 'filter_' . $filter . '_end', 'get', '', true ) ) { unset( $filters[ $k ] ); continue; } - } elseif ( '' === pods_var_raw( 'filter_' . $filter, 'get', '' ) ) { + } elseif ( '' === pods_v( 'filter_' . $filter, 'get', '' ) ) { unset( $filters[ $k ] ); continue; } @@ -3088,24 +2783,26 @@ public function manage( $reorder = false ) { if ( isset( $this->pod->fields[ $filter ] ) ) { $filter_field = $this->pod->fields[ $filter ]; - if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) { - $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] ); + if ( isset( $this->fields['manage'][ $filter ] ) ) { + $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] ); } } elseif ( isset( $this->fields['manage'][ $filter ] ) ) { $filter_field = $this->fields['manage'][ $filter ]; } else { continue; } + + $filter_field[ 'disable_dfv' ] = true; ?> fields['search'], array(), null, true ), array(), null, true ), '', null, true ); - $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true ); + $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true ); + $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true ); - $options = array_merge( $filter_field, $filter_field['options'] ); + $options = $filter_field; ?> pod->fields[ $filter ] ) ) { $filter_field = $this->pod->fields[ $filter ]; - if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) { - $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] ); + if ( isset( $this->fields['manage'][ $filter ] ) ) { + $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] ); } } elseif ( isset( $this->fields['manage'][ $filter ] ) ) { $filter_field = $this->fields['manage'][ $filter ]; @@ -3444,10 +3142,10 @@ public function filters() { } if ( isset( $filter_field ) && in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) { - if ( '' == pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true ) && '' == pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true ) ) { + if ( '' == pods_v( 'filter_' . $filter . '_start', 'get', '', true ) && '' == pods_v( 'filter_' . $filter . '_end', 'get', '', true ) ) { unset( $filters[ $k ] ); } - } elseif ( '' === pods_var_raw( 'filter_' . $filter, 'get', '' ) ) { + } elseif ( '' === pods_v( 'filter_' . $filter, 'get', '' ) ) { unset( $filters[ $k ] ); } } @@ -3505,7 +3203,7 @@ public function filters() { ?>

fields['search'], array(), null, true ), array(), null, true ), '', null, true ); - $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true ); + $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true ); + $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true ); - $options = array_merge( $filter_field, $filter_field['options'] ); + $options = $filter_field; ?> + @@ -3842,7 +3542,7 @@ public function filters_popup() { - + pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ), - '0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ), + $filter_field['pick_object'] = 'custom-simple'; + $filter_field['pick_custom'] = array( + '1' => pods_v( 'boolean_yes_label', $filter_field, __( 'Yes', 'pods' ), true ), + '0' => pods_v( 'boolean_no_label', $filter_field, __( 'No', 'pods' ), true ), ); - $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true ); - $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true ); + $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true ); + $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true ); - $options = array_merge( $filter_field, $filter_field['options'] ); + $options = $filter_field; ?> + @@ -3891,7 +3591,7 @@ public function filters_popup() { - + pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true ), + 'input_helper' => pods_v( 'ui_input_helper', pods_v( 'options', pods_v( $filter, $this->fields['search'], array(), true ), array(), true ), '', true ), ); - if ( empty( $options['input_helper'] ) && isset( $filter_field['options'] ) && isset( $filter_field['options']['input_helper'] ) ) { - $options['input_helper'] = $filter_field['options']['input_helper']; + if ( empty( $options['input_helper'] ) && isset( $filter_field['input_helper'] ) ) { + $options['input_helper'] = $filter_field['input_helper']; } ?> + @@ -3957,7 +3657,7 @@ public function filters_popup() {

- num_prefix . 'search' . $this->num, pods_var_raw( $this->num_prefix . 'search' . $this->num ), 'text' ); ?> + num_prefix . 'search' . $this->num, pods_v( $this->num_prefix . 'search' . $this->num ), 'text', [ 'disable_dfv' => true ] ); ?>

@@ -4048,7 +3748,7 @@ public function table( $reorder = false ) { array( $this->num_prefix . 'action' . $this->num => 'reorder', $this->num_prefix . 'do' . $this->num => 'save', - 'page' => pods_var_raw( 'page' ), + 'page' => pods_v( 'page' ), ), self::$allowed, $this->exclusion() ) ); @@ -4246,6 +3946,12 @@ public function table( $reorder = false ) { $toggle_class = ''; + $field_id = ''; + + if ( ! empty( $row[ $this->sql['field_id'] ] ) ) { + $field_id = $row[ $this->sql['field_id'] ]; + } + if ( is_array( $this->actions_custom ) && isset( $this->actions_custom['toggle'] ) ) { $toggle_class = ' pods-toggled-on'; @@ -4254,12 +3960,12 @@ public function table( $reorder = false ) { } } ?> - + actions_bulk ) ) { ?> - + pod ) && class_exists( 'Pods_Helpers' ) ) { - $row_value = $this->pod->helper( $attributes['custom_display'], $row_value, $field ); } } else { ob_start(); - $field_value = PodsForm::field_method( $attributes['type'], 'ui', $this->id, $row_value, $field, array_merge( $attributes, pods_var_raw( 'options', $attributes, array(), null, true ) ), $fields, $this->pod ); + $field_value = PodsForm::field_method( $attributes['type'], 'ui', $this->id, $row_value, $field, $attributes, $fields, $this->pod ); $field_output = trim( (string) ob_get_clean() ); @@ -4311,7 +4015,7 @@ public function table( $reorder = false ) { global $wpdb; $table = $attributes['custom_relate']; $on = $this->sql['field_id']; - $is = $row[ $this->sql['field_id'] ]; + $is = $field_id; $what = array( 'name' ); if ( is_array( $table ) ) { if ( isset( $table['on'] ) ) { @@ -4473,7 +4177,7 @@ public function table( $reorder = false ) { $link = pods_query_arg( array( $this->num_prefix . 'action' . $this->num => 'edit', - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, ), self::$allowed, $this->exclusion() ); @@ -4493,7 +4197,7 @@ public function table( $reorder = false ) { $link = pods_query_arg( array( $this->num_prefix . 'action' . $this->num => 'view', - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, ), self::$allowed, $this->exclusion() ); @@ -4528,7 +4232,7 @@ public function table( $reorder = false ) { $toggle = false; $actions = $this->get_actions( $row ); - $actions = $this->do_hook( 'row_actions', $actions, $row[ $this->sql['field_id'] ] ); + $actions = $this->do_hook( 'row_actions', $actions, $field_id ); if ( ! empty( $actions ) ) { ?> @@ -4545,7 +4249,7 @@ public function table( $reorder = false ) { } } else { ?> - + sql['field_id'] ] ) ) { + $field_id = $row[ $this->sql['field_id'] ]; + } + $actions = array(); if ( ! in_array( 'view', $this->actions_disabled ) && ! in_array( 'view', $this->actions_hidden ) ) { $link = pods_query_arg( array( $this->num_prefix . 'action' . $this->num => 'view', - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, ), self::$allowed, $this->exclusion() ); @@ -4675,7 +4385,7 @@ public function get_actions( $row ) { $link = pods_query_arg( array( $this->num_prefix . 'action' . $this->num => 'edit', - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, ), self::$allowed, $this->exclusion() ); @@ -4690,7 +4400,7 @@ public function get_actions( $row ) { $link = pods_query_arg( array( $this->num_prefix . 'action' . $this->num => 'duplicate', - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, ), self::$allowed, $this->exclusion() ); @@ -4705,7 +4415,7 @@ public function get_actions( $row ) { $link = pods_query_arg( array( $this->num_prefix . 'action' . $this->num => 'delete', - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, $this->num_prefix . '_wpnonce' . $this->num => wp_create_nonce( 'pods-ui-action-delete' ), ), self::$allowed, $this->exclusion() ); @@ -4751,7 +4461,7 @@ public function get_actions( $row ) { if ( ! isset( $custom_data['link'] ) ) { $vars = array( $this->num_prefix . 'action' . $this->num => $custom_action, - $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ], + $this->num_prefix . 'id' . $this->num => $field_id, $this->num_prefix . '_wpnonce' . $this->num => wp_create_nonce( 'pods-ui-action-' . $custom_action ), ); @@ -4777,7 +4487,15 @@ public function get_actions( $row ) { continue; } - $actions[ $custom_action ] = '' . $custom_data['label'] . ''; + $span_class = 'edit'; + + if ( isset( $custom_data['span_class'] ) ) { + $span_class = $custom_data['span_class']; + } + + $span_class .= ' action-' . $custom_action; + + $actions[ $custom_action ] = '' . $custom_data['label'] . ''; }//end if }//end if }//end foreach @@ -5281,9 +4999,9 @@ public function restricted( $action = 'edit', $row = null ) { // @todo Build 'edit', 'duplicate', 'delete' action support for 'where' which runs another find() query /* if ( !in_array( $action, array( 'manage', 'reorder' ) ) ) { - $where = pods_var_raw( $action, $this->where, null, null, true ); + $where = pods_v( $action, $this->where, null, true ); - if ( !empty( $where ) ) { + if ( ! empty( $where ) ) { $restricted = true; $old_where = $this->where[ $action ]; @@ -5291,13 +5009,14 @@ public function restricted( $action = 'edit', $row = null ) { $id = $this->row[ $this->sql[ 'field_id' ] ]; if ( is_array( $where ) ) { - if ( 'OR' == pods_var( 'relation', $where ) ) + if ( 'OR' == pods_v( 'relation', $where ) ) { $where = array( $where ); + } - $where[] = "`t`.`" . $this->sql[ 'field_id' ] . "` = " . (int) $id; - } - else - $where = "( {$where} ) AND `t`.`" . $this->sql[ 'field_id' ] . "` = " . (int) $id; + $where[] = "`t`.`" . $this->sql['field_id'] . "` = " . (int) $id; + } else { + $where = "( {$where} ) AND `t`.`" . $this->sql['field_id'] . "` = " . (int) $id; + } $this->where[ $action ] = $where; @@ -5307,8 +5026,9 @@ public function restricted( $action = 'edit', $row = null ) { $this->where[ $action ] = $old_where; - if ( empty( $data ) ) + if ( empty( $data ) ) { $restricted = true; + } } }*/ @@ -5559,14 +5279,14 @@ public function restricted( $action = 'edit', $row = null ) { * * @since 2.7.28 * - * @param string|array $field The field data. + * @param string|array|Field $field The field data. * - * @return array|false The field data or false if invalid / not found. + * @return array|Field|false The field data or false if invalid / not found. */ public function get_field_data( $field, $which = 'manage' ) { $field_data = $field; - if ( ! is_array( $field_data ) ) { + if ( ! is_array( $field_data ) && ! $field_data instanceof Field ) { // Field is not set. if ( ! isset( $this->fields[ $which ][ $field ] ) ) { return false; @@ -5586,7 +5306,7 @@ public function get_field_data( $field, $which = 'manage' ) { * * @since 2.7.28 * - * @param string|array $field The field data. + * @param string|array|Field $field The field data. * * @return bool Whether a field is searchable. */ @@ -5606,7 +5326,7 @@ public function is_field_searchable( $field ) { } // Search is turned on individually and we don't have a list of search-only fields. - return ! empty( $field_data['options']['search'] ) && empty( $this->fields['search'] ); + return ! empty( $field_data['search'] ) && empty( $this->fields['search'] ); } /** @@ -5614,7 +5334,7 @@ public function is_field_searchable( $field ) { * * @since 2.7.28 * - * @param string|array $field The field data. + * @param string|array|Field $field The field data. * * @return bool Whether a field is sortable. */ diff --git a/classes/PodsView.php b/classes/PodsView.php index c0b9d13864..5863b893b3 100644 --- a/classes/PodsView.php +++ b/classes/PodsView.php @@ -1,5 +1,7 @@ get( $key, ( empty( $group ) ? 'pods_view' : $group ) ); } else { $value = false; }//end if @@ -358,6 +364,10 @@ public static function set( $key, $value, $expires = 0, $cache_mode = null, $gro do_action( "set_transient_{$key}" ); do_action( 'setted_transient', $key ); } + } elseif ( 'static-cache' === $cache_mode ) { + $static_cache = tribe( Static_Cache::class ); + + $static_cache->set( $key, $value, ( empty( $group ) ? 'pods_view' : $group ) ); }//end if do_action( "pods_view_set_{$cache_mode}", $original_key, $value, $expires, $group ); @@ -463,6 +473,14 @@ public static function clear( $key = true, $cache_mode = null, $group = '' ) { if ( $result ) { do_action( 'deleted_transient', $key ); } + } elseif ( 'static-cache' === $cache_mode ) { + $static_cache = tribe( Static_Cache::class ); + + if ( true === $key ) { + $static_cache->flush( ( empty( $group ) ? 'pods_view' : $group ) ); + } else { + $static_cache->delete( ( empty( $key ) ? 'pods_view' : $key ), ( empty( $group ) ? 'pods_view' : $group ) ); + } }//end if do_action( "pods_view_clear_{$cache_mode}", $original_key, $group ); diff --git a/classes/fields/avatar.php b/classes/fields/avatar.php index 7ba6e15f8e..5e29c371f1 100644 --- a/classes/fields/avatar.php +++ b/classes/fields/avatar.php @@ -1,5 +1,4 @@ __( 'Radio Buttons', 'pods' ), 'dropdown' => __( 'Drop Down', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_yes_label' => array( @@ -113,7 +114,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -132,7 +133,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'select'; } - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; } else { @@ -148,7 +149,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $value = 0; } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -242,4 +254,38 @@ public function ui( $id, $value, $name = null, $options = null, $fields = null, return $value; } + + /** + * {@inheritdoc} + */ + public function build_dfv_field_item_data( $args ) { + if ( empty( $args->options['data'] ) || ! is_array( $args->options['data'] ) ) { + return []; + } + + $boolean_data = $args->options['data']; + + $value = 0; + + // If we have values, let's cast them. + if ( isset( $args->value ) ) { + $value = (int) $args->value; + } + + $data = []; + + foreach ( $boolean_data as $key => $label ) { + $data[] = [ + 'id' => esc_html( $key ), + 'icon' => '', + 'name' => wp_strip_all_tags( html_entity_decode( $label ) ), + 'edit_link' => '', + 'link' => '', + 'download' => '', + 'selected' => (int) $key === $value, + ]; + } + + return $data; + } } diff --git a/classes/fields/code.php b/classes/fields/code.php index 52a2625bec..440a27d1e4 100644 --- a/classes/fields/code.php +++ b/classes/fields/code.php @@ -32,7 +32,8 @@ class PodsField_Code extends PodsField { */ public function setup() { - self::$label = __( 'Code (Syntax Highlighting)', 'pods' ); + static::$group = __( 'Paragraph', 'pods' ); + static::$label = __( 'Code (Syntax Highlighting)', 'pods' ); } /** @@ -52,9 +53,16 @@ public function options() { ), 'output_options' => array( 'label' => __( 'Output Options', 'pods' ), - 'group' => array( + 'type' => 'boolean_group', + 'boolean_group' => array( + static::$type . '_trim' => array( + 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + 'dependency' => true, + ), static::$type . '_allow_shortcode' => array( - 'label' => __( 'Allow Shortcodes?', 'pods' ), + 'label' => __( 'Allow Shortcodes', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, @@ -63,7 +71,7 @@ public function options() { ), static::$type . '_max_length' => array( 'label' => __( 'Maximum Length', 'pods' ), - 'default' => 0, + 'default' => -1, 'type' => 'number', 'help' => __( 'Set to -1 for no limit', 'pods' ), ), @@ -105,7 +113,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -117,13 +125,25 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = do_action( "pods_form_ui_field_code_{$field_type}", $name, $value, $options, $pod, $id ); do_action( 'pods_form_ui_field_code', $field_type, $name, $value, $options, $pod, $id ); - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { + $value = $this->trim_whitespace( $value, $options ); $length = (int) pods_v( static::$type . '_max_length', $options, 0 ); diff --git a/classes/fields/color.php b/classes/fields/color.php index 5f4bc4bd8c..a081bf4358 100644 --- a/classes/fields/color.php +++ b/classes/fields/color.php @@ -25,7 +25,7 @@ class PodsField_Color extends PodsField { */ public function setup() { - self::$label = __( 'Color Picker', 'pods' ); + static::$label = __( 'Color Picker', 'pods' ); } /** @@ -63,7 +63,7 @@ public function schema( $options = null ) { */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -73,7 +73,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = // WP Color Picker for 3.5+ $field_type = 'color'; - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; @@ -87,7 +87,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'text'; } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -133,7 +144,7 @@ public function validate( $value, $name = null, $options = null, $fields = null, */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $value = str_replace( '#', '', $value ); diff --git a/classes/fields/comment.php b/classes/fields/comment.php index bd61574b4b..0f7d69d467 100644 --- a/classes/fields/comment.php +++ b/classes/fields/comment.php @@ -1,5 +1,4 @@ __( 'Freeform Number', 'pods' ), 'slider' => __( 'Slider', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_format_sign' => array( @@ -83,6 +85,7 @@ public function options() { 'default' => apply_filters( 'pods_form_ui_field_number_currency_default', 'usd' ), 'type' => 'pick', 'data' => apply_filters( 'pods_form_ui_field_number_currency_options', $currency_options ), + 'pick_show_select_text' => 0, ), static::$type . '_format_placement' => array( 'label' => __( 'Currency Placement', 'pods' ), @@ -97,25 +100,28 @@ public function options() { 'beforeaftercode' => __( 'Before with Currency Code after (ex. $100 USD)', 'pods' ), 'beforeaftercode_space' => __( 'Before with space and with Currency Code after (ex. $ 100 USD)', 'pods' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_format' => array( - 'label' => __( 'Format', 'pods' ), + 'label' => __( 'Number Format', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_number_currency_format_default', 'i18n' ), 'type' => 'pick', 'data' => array( 'i18n' => __( 'Localized Default', 'pods' ), '9,999.99' => '1,234.00', - '9\'999.99' => '1\'234.00', - '9.999,99' => '1.234,00', - '9 999,99' => '1 234,00', '9999.99' => '1234.00', + '9.999,99' => '1.234,00', '9999,99' => '1234,00', + '9 999,99' => '1 234,00', + '9\'999.99' => '1\'234.00', ), + 'pick_show_select_text' => 0, ), static::$type . '_decimals' => array( 'label' => __( 'Decimals', 'pods' ), 'default' => 2, 'type' => 'number', + 'help' => __( 'Set to a positive number to enable decimals. The upper limit in the database for this field is 30 decimals.', 'pods' ), ), static::$type . '_decimal_handling' => array( 'label' => __( 'Decimal handling when zero', 'pods' ), @@ -126,6 +132,7 @@ public function options() { 'remove' => __( 'Remove decimals', 'pods' ), 'dash' => __( 'Convert to dash', 'pods' ) . ' (-)', ), + 'pick_show_select_text' => 0, ), static::$type . '_step' => array( 'label' => __( 'Slider Increment (Step)', 'pods' ), @@ -135,21 +142,32 @@ public function options() { ), static::$type . '_min' => array( 'label' => __( 'Minimum Number', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'slider' ), + 'depends-on-any' => array( + static::$type . '_format_type' => 'slider', + static::$type . '_html5' => true, + ), 'default' => 0, 'type' => 'text', ), static::$type . '_max' => array( 'label' => __( 'Maximum Number', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'slider' ), + 'depends-on-any' => array( + static::$type . '_format_type' => 'slider', + static::$type . '_html5' => true, + ), 'default' => 1000, 'type' => 'text', ), static::$type . '_max_length' => array( - 'label' => __( 'Maximum Length', 'pods' ), + 'label' => __( 'Maximum Digits', 'pods' ), 'default' => 12, 'type' => 'number', - 'help' => __( 'Set to -1 for no limit', 'pods' ), + 'help' => __( 'Set to -1 for no limit. The upper limit in the database for this field is 64 digits.', 'pods' ), + ), + static::$type . '_html5' => array( + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), + 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), + 'type' => 'boolean', ), static::$type . '_placeholder' => array( 'label' => __( 'HTML Placeholder', 'pods' ), diff --git a/classes/fields/date.php b/classes/fields/date.php index d4de4fc925..2ce5a55d57 100644 --- a/classes/fields/date.php +++ b/classes/fields/date.php @@ -1,5 +1,4 @@ __( 'Predefined format', 'pods' ), 'custom' => __( 'Custom format', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_format_custom' => array( @@ -109,6 +110,7 @@ public function options() { 'fjsy' => date_i18n( 'F jS, Y' ), 'y' => date_i18n( 'Y' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_year_range_custom' => array( @@ -126,12 +128,12 @@ public function options() { ), ), static::$type . '_allow_empty' => array( - 'label' => __( 'Allow empty value?', 'pods' ), + 'label' => __( 'Allow empty value', 'pods' ), 'default' => 1, 'type' => 'boolean', ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', ), diff --git a/classes/fields/datetime.php b/classes/fields/datetime.php index 958cb7422e..d7f664530b 100644 --- a/classes/fields/datetime.php +++ b/classes/fields/datetime.php @@ -46,6 +46,7 @@ class PodsField_DateTime extends PodsField { */ public function setup() { + static::$group = __( 'Date / Time', 'pods' ); static::$label = __( 'Date / Time', 'pods' ); } @@ -75,31 +76,32 @@ public function options() { 'format' => __( 'Predefined format', 'pods' ), 'custom' => __( 'Custom format', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_format_custom' => array( - 'label' => __( 'Date format for display', 'pods' ), + 'label' => __( 'Date Format for Display', 'pods' ), 'depends-on' => array( static::$type . '_type' => 'custom' ), 'default' => '', 'type' => 'text', 'help' => sprintf( - '%s', - esc_html__( 'PHP date documentation', 'pods' ) + '%1$s', + esc_html__( 'Date / Time field documentation', 'pods' ) ), ), static::$type . '_format_custom_js' => array( - 'label' => __( 'Date format for input', 'pods' ), + 'label' => __( 'Date Format for Input', 'pods' ), 'depends-on' => array( static::$type . '_type' => 'custom' ), 'default' => '', 'type' => 'text', 'help' => sprintf( - '%1$s
%2$s', - esc_html__( 'jQuery UI datepicker documentation', 'pods' ), + '%1$s
%2$s', + esc_html__( 'Date / Time field documentation', 'pods' ), esc_html__( 'Leave empty to auto-generate from PHP format.', 'pods' ) ), ), static::$type . '_format' => array( - 'label' => __( 'Date Format', 'pods' ), + 'label' => __( 'Date Format (predefined)', 'pods' ), 'depends-on' => array( static::$type . '_type' => 'format' ), 'default' => 'mdy', 'type' => 'pick', @@ -114,6 +116,7 @@ public function options() { 'fjsy' => date_i18n( 'F jS, Y' ), 'c' => date_i18n( 'c' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_time_type' => array( @@ -129,30 +132,34 @@ public function options() { '24' => __( '24 hour', 'pods' ), 'custom' => __( 'Custom', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_time_format_custom' => array( - 'label' => __( 'Time format', 'pods' ), + 'label' => __( 'Time Format for Display', 'pods' ), 'depends-on' => array( static::$type . '_time_type' => 'custom' ), 'excludes-on' => array( static::$type . '_format' => 'c' ), 'default' => '', 'type' => 'text', - 'help' => '' . __( 'PHP date documentation', 'pods' ) . '', + 'help' => sprintf( + '%1$s', + esc_html__( 'Date / Time field documentation', 'pods' ) + ), ), static::$type . '_time_format_custom_js' => array( - 'label' => __( 'Time format field input', 'pods' ), + 'label' => __( 'Time Format for Input', 'pods' ), 'depends-on' => array( static::$type . '_time_type' => 'custom' ), 'excludes-on' => array( static::$type . '_format' => 'c' ), 'default' => '', 'type' => 'text', - 'help' => sprintf( - '%1$s
%2$s', - esc_html__( 'jQuery UI timepicker documentation', 'pods' ), + 'help' => sprintf( + '%1$s
%2$s', + esc_html__( 'Date / Time field documentation', 'pods' ), esc_html__( 'Leave empty to auto-generate from PHP format.', 'pods' ) ), ), static::$type . '_time_format' => array( - 'label' => __( 'Time Format', 'pods' ), + 'label' => __( 'Time Format (12 hour)', 'pods' ), 'depends-on' => array( static::$type . '_time_type' => '12' ), 'excludes-on' => array( static::$type . '_format' => 'c' ), 'default' => 'h_mma', @@ -169,9 +176,10 @@ public function options() { 'hh_mm' => date_i18n( 'h:i' ), 'hh_mm_ss' => date_i18n( 'h:i:s' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_time_format_24' => array( - 'label' => __( 'Time Format', 'pods' ), + 'label' => __( 'Time Format (24 hour)', 'pods' ), 'depends-on' => array( static::$type . '_time_type' => '24' ), 'excludes-on' => array( static::$type . '_format' => 'c' ), 'default' => 'hh_mm', @@ -180,28 +188,29 @@ public function options() { 'hh_mm' => date_i18n( 'H:i' ), 'hh_mm_ss' => date_i18n( 'H:i:s' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_year_range_custom' => array( - 'label' => __( 'Year range', 'pods' ), + 'label' => __( 'Year Range', 'pods' ), 'default' => '', 'type' => 'text', 'help' => sprintf( - '%1$s
%2$s', + '%1$s
%2$s', sprintf( esc_html__( 'Example: %1$s for specifying a hard coded year range or %2$s for the last and next 10 years.', 'pods' ), '2010:2030', '-10:+10' ), - esc_html__( 'jQuery UI datepicker documentation', 'pods' ) + esc_html__( 'Date / Time field documentation', 'pods' ) ), ), static::$type . '_allow_empty' => array( - 'label' => __( 'Allow empty value?', 'pods' ), + 'label' => __( 'Allow empty value', 'pods' ), 'default' => 1, 'type' => 'boolean', ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', ), @@ -274,7 +283,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -286,21 +295,34 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = static::$type; - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { - if ( pods_v( 'read_only', $options, false ) ) { + $is_read_only = (boolean) pods_v( 'read_only', $options, false ); + + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { + if ( $is_read_only ) { $options['readonly'] = true; $field_type = 'text'; } else { return; } - } elseif ( ! pods_has_permissions( $options ) && pods_v( 'read_only', $options, false ) ) { + } elseif ( ! pods_has_permissions( $options ) && $is_read_only ) { $options['readonly'] = true; $field_type = 'text'; } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -951,49 +973,61 @@ public function convert_format( $source_format, $args = array() ) { * @since 2.7.0 */ public function enqueue_jquery_ui_i18n() { + $static_cache = tribe( Static_Cache::class ); - static $done = array(); + $done = (array) $static_cache->get( 'done', __METHOD__ ); $types = array(); switch ( static::$type ) { case 'time': - $types[] = 'time'; + $types['time'] = true; break; case 'date': - $types[] = 'date'; + $types['date'] = true; break; case 'datetime': - $types[] = 'time'; - $types[] = 'date'; + $types['time'] = true; + $types['date'] = true; break; } - if ( in_array( 'date', $types, true ) && ! in_array( 'date', $done, true ) ) { + $locale = str_replace( '_', '-', get_locale() ); + + if ( isset( $types['date'] ) && ! isset( $done[ 'date-' . $locale ] ) ) { if ( function_exists( 'wp_localize_jquery_ui_datepicker' ) ) { wp_localize_jquery_ui_datepicker(); } - $done[] = 'date'; + $done['date'] = true; } - if ( in_array( 'time', $types, true ) && ! in_array( 'time', $done, true ) ) { - $locale = str_replace( '_', '-', get_locale() ); + if ( isset( $types['time'] ) && ! isset( $done[ 'time-' . $locale ] ) ) { + /** + * @var $wp_filesystem WP_Filesystem_Base + */ + global $wp_filesystem; + + WP_Filesystem(); + + $locale_exists = $wp_filesystem->exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' ); // Local files. - if ( ! file_exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' ) ) { + if ( ! $locale_exists ) { // Fallback to the base language (non-region specific). $locale = substr( $locale, 0, strpos( $locale, '-' ) ); + + $locale_exists = $wp_filesystem->exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' ); } - if ( ! wp_script_is( 'jquery-ui-timepicker-i18n-' . $locale, 'registered' ) && file_exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' ) ) { - wp_enqueue_script( 'jquery-ui-timepicker-i18n-' . $locale, PODS_URL . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js', array( 'jquery-ui-timepicker' ), '1.6.3' ); + if ( $locale_exists && ! wp_script_is( 'jquery-ui-timepicker-i18n-' . $locale ) ) { + wp_enqueue_script( 'jquery-ui-timepicker-i18n-' . $locale, PODS_URL . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js', [ 'jquery-ui-timepicker' ], '1.6.3' ); } - $done[] = 'time'; + $done[ 'time-' . $locale ] = true; } } } diff --git a/classes/fields/email.php b/classes/fields/email.php index 9e8f72e90a..3dbfa8eda9 100644 --- a/classes/fields/email.php +++ b/classes/fields/email.php @@ -30,7 +30,8 @@ class PodsField_Email extends PodsField { */ public function setup() { - self::$label = __( 'E-mail', 'pods' ); + static::$group = __( 'Text', 'pods' ); + static::$label = __( 'E-mail', 'pods' ); } /** @@ -55,7 +56,7 @@ public function options() { 'help' => __( 'Set to -1 for no limit', 'pods' ), ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', ), @@ -94,7 +95,7 @@ public function schema( $options = null ) { */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -103,7 +104,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'email'; - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; @@ -117,7 +118,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'text'; } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/email.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -160,7 +172,7 @@ public function validate( $value, $name = null, $options = null, $fields = null, */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; if ( ! is_email( $value ) ) { $value = ''; diff --git a/classes/fields/file.php b/classes/fields/file.php index fe1b240f54..2902090187 100644 --- a/classes/fields/file.php +++ b/classes/fields/file.php @@ -36,7 +36,8 @@ class PodsField_File extends PodsField { */ public function setup() { - self::$label = __( 'File / Image / Video', 'pods' ); + static::$group = __( 'Relationships / Media', 'pods' ); + static::$label = __( 'File / Image / Video', 'pods' ); } @@ -75,6 +76,7 @@ public function options() { 'single' => __( 'Single File', 'pods' ), 'multi' => __( 'Multiple Files', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_uploader' => array( @@ -88,10 +90,11 @@ public function options() { 'plupload' => __( 'Upload only (Plupload)', 'pods' ), ) ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_attachment_tab' => array( - 'label' => __( 'Attachments Default Tab', 'pods' ), + 'label' => __( 'Media Library Default Tab', 'pods' ), 'depends-on' => array( static::$type . '_uploader' => 'attachment' ), 'default' => 'upload', 'type' => 'pick', @@ -100,20 +103,22 @@ public function options() { 'upload' => __( 'Upload File', 'pods' ), 'browse' => __( 'Media Library', 'pods' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_upload_dir' => array( - 'label' => __( 'Upload directory', 'pods' ), + 'label' => __( 'Upload Directory', 'pods' ), 'default' => 'wp', 'type' => 'pick', 'data' => array( - 'wp' => __( 'WordPress Default', 'pods' ) . ' (/yyyy/mm/)', + 'wp' => __( 'WordPress Default', 'pods' ) . ' (/wp-content/uploads/yyyy/mm/)', 'uploads' => __( 'Custom directory within the default uploads directory', 'pods' ), ), + 'pick_show_select_text' => 0, 'depends-on' => array( static::$type . '_uploader' => 'plupload' ), 'dependency' => true, ), static::$type . '_upload_dir_custom' => array( - 'label' => __( 'Custom upload directory', 'pods' ), + 'label' => __( 'Custom Upload Directory', 'pods' ), 'help' => __( 'Magic tags are allowed for this field. The path is relative to the /wp-content/uploads/ folder on your site.', 'pods' ), 'placeholder' => 'my-custom-folder', 'depends-on' => array( @@ -155,7 +160,8 @@ public function options() { 'label' => __( 'Restrict File Size', 'pods' ), 'help' => __( 'Valid size suffixes are: GB (gigabytes), MB (megabytes), KB (kilobytes), or B (bytes). Defaults to the wp_max_upload_size setting.', 'pods' ), 'depends-on' => array( static::$type . '_uploader' => 'plupload' ), - 'default' => '10MB', + 'default' => '', + 'text_placeholder' => '10MB', 'type' => 'text', ), static::$type . '_type' => array( @@ -173,6 +179,7 @@ public function options() { 'other' => __( 'Other (customize allowed extensions)', 'pods' ), ) ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_allowed_extensions' => array( @@ -180,6 +187,7 @@ public function options() { 'description' => __( 'Separate file extensions with a comma (ex. jpg,png,mp4,mov)', 'pods' ), 'depends-on' => array( static::$type . '_type' => 'other' ), 'default' => apply_filters( "pods_form_ui_field_{$type}_extensions_default", '' ), + 'text_placeholder' => 'jpg,png,mp4,mov', 'type' => 'text', ), static::$type . '_field_template' => array( @@ -195,6 +203,7 @@ public function options() { 'tiles' => __( 'Tiles', 'pods' ), ) ), + 'pick_show_select_text' => 0, ), static::$type . '_add_button' => array( 'label' => __( 'Add Button Text', 'pods' ), @@ -223,41 +232,44 @@ public function options() { 'type' => 'boolean', ), static::$type . '_wp_gallery_link' => array( - 'label' => __( 'Gallery image links', 'pods' ), - 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ), + 'label' => __( 'Gallery Image Links', 'pods' ), + 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), 'type' => 'pick', 'data' => array( 'post' => __( 'Attachment Page', 'pods' ), 'file' => __( 'Media File', 'pods' ), 'none' => __( 'None', 'pods' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_wp_gallery_columns' => array( - 'label' => __( 'Gallery image columns', 'pods' ), - 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ), + 'label' => __( 'Gallery Image Columns', 'pods' ), + 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), 'type' => 'pick', 'data' => array( - '1' => 1, - '2' => 2, - '3' => 3, - '4' => 4, - '5' => 5, - '6' => 6, - '7' => 7, - '8' => 8, - '9' => 9, + '1' => '1', + '2' => '2', + '3' => '3', + '4' => '4', + '5' => '5', + '6' => '6', + '7' => '7', + '8' => '8', + '9' => '9', ), + 'pick_show_select_text' => 0, ), static::$type . '_wp_gallery_random_sort' => array( - 'label' => __( 'Gallery randomized order', 'pods' ), - 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ), + 'label' => __( 'Gallery Randomized Order', 'pods' ), + 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), 'type' => 'boolean', ), static::$type . '_wp_gallery_size' => array( - 'label' => __( 'Gallery image size', 'pods' ), - 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ), + 'label' => __( 'Gallery Image Size', 'pods' ), + 'depends-on' => array( static::$type . '_wp_gallery_output' => true ), 'type' => 'pick', 'data' => $this->data_image_sizes(), + 'pick_show_select_text' => 0, ), ); @@ -311,7 +323,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $type = pods_v( 'type', $options, static::$type ); @@ -351,14 +363,6 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = // Ensure the media library is initialized $this->render_input_script( $args ); - - // @todo: we're short-circuiting for prototyping above. The actions below will need to be woven in somehow. - /** - * $form_field_type . '_uploader' != attachment, plupload, media - * Run this action 'pods_form_ui_field_' . static::$type . '_uploader_' . static::$type . '_uploader' - * Run this action 'pods_form_ui_field_' . static::$type . '_uploader', static::$type . '_uploader' - * Pass these args $name, $value, $options, $pod, $id - */ } /** @@ -374,11 +378,26 @@ public function build_dfv_field_options( $options, $args ) { } } + // Enforce defaults. + $all_options = static::options(); + + foreach ( $all_options as $option_name => $option ) { + $default = pods_v( 'default', $option, '' ); + + $options[ $option_name ] = pods_v( $option_name, $options, $default ); + + if ( '' === $options[ $option_name ] ) { + $options[ $option_name ] = $default; + } + } + // Handle default template setting. - $file_field_template = pods_v( $args->type . '_field_template', $options, 'rows', true ); + $file_field_template = pods_v( $args->type . '_field_template', $options ); // Get which file types the field is limited to. - $limit_file_type = pods_v( $args->type . '_type', $options, 'images' ); + $limit_file_type = pods_v( $args->type . '_type', $options ); + + $options[ $args->type . '_type' ] = $limit_file_type; // Non-image file types are forced to rows template right now. if ( 'images' !== $limit_file_type ) { @@ -488,25 +507,23 @@ public function build_dfv_field_options( $options, $args ) { $is_user_logged_in = is_user_logged_in(); // @todo: plupload specific options need accommodation - if ( 'plupload' === $options[ static::$type . '_uploader' ] ) { + if ( 'plupload' === pods_v( static::$type . '_uploader', $options ) ) { wp_enqueue_script( 'plupload-all' ); + $pod_id = (int) pods_v( 'pod_id', $args->pod, 0 ); + $field_id = (int) pods_v( 'id', $options, 0 ); + $item_id = (int) pods_v( 'id', $args, 0 ); + if ( $is_user_logged_in ) { $uid = 'user_' . get_current_user_id(); } else { $uid = pods_session_id(); } - $pod_id = '0'; - - if ( is_object( $args->pod ) ) { - $pod_id = $args->pod->pod_id; - } - $uri_hash = wp_create_nonce( 'pods_uri_' . $_SERVER['REQUEST_URI'] ); - $field_nonce = wp_create_nonce( 'pods_upload_' . $pod_id . '_' . $uid . '_' . $uri_hash . '_' . $options['id'] ); + $field_nonce = wp_create_nonce( 'pods_upload_' . $pod_id . '_' . $uid . '_' . $uri_hash . '_' . $field_id ); - $options['plupload_init'] = array( + $plupload_init = [ 'runtimes' => 'html5,silverlight,flash,html4', 'url' => admin_url( 'admin-ajax.php?pods_ajax=1', 'relative' ), 'file_data_name' => 'Filedata', @@ -514,31 +531,37 @@ public function build_dfv_field_options( $options, $args ) { 'max_file_size' => wp_max_upload_size() . 'b', 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), - 'filters' => array( - array( + 'filters' => [ + [ 'title' => __( 'Allowed Files', 'pods' ), 'extensions' => '*', - ), - ), + ], + ], 'multipart' => true, 'urlstream_upload' => true, - 'multipart_params' => array( + 'multipart_params' => [ '_wpnonce' => $field_nonce, 'action' => 'pods_upload', 'method' => 'upload', 'pod' => $pod_id, - 'field' => $options['id'], + 'field' => $field_id, + 'item_id' => $item_id, 'uri' => $uri_hash, - ), - ); + ], + ]; - // Pass post ID if we're in an add or edit post screen. - $post = get_post(); + // Disable multi selection if only one is allowed. + if ( 1 === $file_limit ) { + $plupload_init['multi_selection'] = false; + } + // Backwards compatibility: Pass post ID if we're in an add or edit post screen. + $post = get_post(); if ( $post instanceof WP_Post ) { - $options['plupload_init']['multipart_params']['post_id'] = $post->ID; + $plupload_init['multipart_params']['post_id'] = $post->ID; } + $options['plupload_init'] = $plupload_init; }//end if return $options; @@ -608,6 +631,7 @@ public function build_dfv_field_item_data( $args ) { 'edit_link' => html_entity_decode( esc_url( $edit_link ) ), 'link' => html_entity_decode( esc_url( $link ) ), 'download' => html_entity_decode( esc_url( $download ) ), + 'selected' => true, ); }//end foreach @@ -1038,7 +1062,7 @@ public function admin_ajax_upload() { // Cleaning up $params unset( $params->action, $params->method, $params->_wpnonce ); - $params->post_id = (int) pods_v( 'post_id', $params, 0 ); + $params->item_id = (int) pods_v( 'item_id', $params, 0 ); /** * Upload a new file (advanced - returns URL and ID) @@ -1181,7 +1205,7 @@ public function admin_ajax_upload() { } }//end if - $custom_handler = apply_filters( 'pods_upload_handle', null, 'Filedata', $params->post_id, $params, $field ); + $custom_handler = apply_filters( 'pods_upload_handle', null, 'Filedata', $params->item_id, $params, $field ); if ( null === $custom_handler ) { @@ -1192,15 +1216,11 @@ public function admin_ajax_upload() { $custom_dir = pods_v( $field['type'] . '_upload_dir_custom', $field['options'], '' ); $context_pod = null; - if ( $params->post_id ) { - $post = get_post( $params->post_id ); - - if ( $post ) { - $post_pod = pods( $post->post_type, $post->ID ); + if ( $params->item_id ) { + $context_pod = pods( pods_v( 'name', $pod, false ), $params->item_id ); - if ( $post_pod->exists() ) { - $context_pod = $post_pod; - } + if ( ! $context_pod->exists() ) { + $context_pod = null; } } @@ -1237,7 +1257,12 @@ public function admin_ajax_upload() { } // Upload file. - $attachment_id = media_handle_upload( 'Filedata', $params->post_id ); + $post_id = 0; + if ( 'post_type' === pods_v( 'type', $pod, null ) ) { + $post_id = $params->item_id; + } + + $attachment_id = media_handle_upload( 'Filedata', $post_id ); // End custom directory. if ( 'wp' !== $upload_dir ) { @@ -1271,7 +1296,7 @@ public function admin_ajax_upload() { $attachment['edit_link'] = get_edit_post_link( $attachment['ID'] ); $attachment['download'] = wp_get_attachment_url( $attachment['ID'] ); - $attachment = apply_filters( 'pods_upload_attachment', $attachment, $params->post_id ); + $attachment = apply_filters( 'pods_upload_attachment', $attachment, $params->item_id ); wp_send_json( $attachment ); }//end if @@ -1316,4 +1341,32 @@ public function filter_upload_dir( $uploads ) { return $uploads; } + /** + * Build field data for Pods DFV. + * + * @param object $args { + * Field information arguments. + * + * @type string $name Field name. + * @type string $type Field type. + * @type array $options Field options. + * @type mixed $value Current value. + * @type array $pod Pod information. + * @type int|string $id Current item ID. + * @type string $form_field_type HTML field type. + * } + * + * @return array + */ + public function build_dfv_field_data( $args ) { + $data = parent::build_dfv_field_data( $args ); + + // Normalize arrays for multiple select. + if ( is_array( $data['fieldValue'] ) ) { + $data['fieldValue'] = array_values( $data['fieldValue'] ); + } + + return $data; + } + } diff --git a/classes/fields/heading.php b/classes/fields/heading.php new file mode 100644 index 0000000000..dfcc6ade18 --- /dev/null +++ b/classes/fields/heading.php @@ -0,0 +1,133 @@ + [ + 'label' => __( 'Heading HTML Tag', 'pods' ), + 'type' => 'text', + 'default' => '', + 'description' => __( 'Leave this empty to use the default heading tag for the form context the heading appears in.', 'pods' ), + 'help' => __( 'This is the heading HTML tag to use for the heading text. Example "h2" will output your heading as <h2>Heading Text</h2>', 'pods' ), + ], + 'output_options' => [ + 'label' => __( 'Output Options', 'pods' ), + 'type' => 'boolean_group', + 'boolean_group' => [ + static::$type . '_allow_html' => [ + 'label' => __( 'Allow HTML', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + 'dependency' => true, + ], + static::$type . '_wptexturize' => [ + 'label' => __( 'Enable wptexturize', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + 'help' => [ + __( 'Transforms less-beautiful text characters into stylized equivalents.', 'pods' ), + 'http://codex.wordpress.org/Function_Reference/wptexturize', + ], + ], + static::$type . '_allow_shortcode' => [ + 'label' => __( 'Allow Shortcodes', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + 'help' => [ + __( 'Embed [shortcodes] that help transform your static content into dynamic content.', 'pods' ), + 'http://codex.wordpress.org/Shortcode_API', + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function schema( $options = null ) { + return false; + } + + /** + * {@inheritdoc} + */ + public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; + + // @codingStandardsIgnoreLine + echo $this->display( $value, $name, $options, $pod, $id ); + } + + /** + * {@inheritdoc} + */ + public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { + // Support passing html_content into the options for custom HTML option layouts. + if ( empty( $value ) && ! empty( $options[ static::$type . '_content' ] ) ) { + $value = $options[ static::$type . '_content' ]; + } + + $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); + + if ( 1 === (int) pods_v( static::$type . '_wptexturize', $options, 1 ) ) { + $value = wptexturize( $value ); + } + + if ( 1 === (int) pods_v( static::$type . '_allow_shortcode', $options, 0 ) ) { + $value = do_shortcode( $value ); + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { + $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); + + return wp_trim_words( $value ); + } +} diff --git a/classes/fields/html.php b/classes/fields/html.php index 886e8195a2..9a523c3113 100644 --- a/classes/fields/html.php +++ b/classes/fields/html.php @@ -8,7 +8,7 @@ class PodsField_HTML extends PodsField { /** * {@inheritdoc} */ - public static $group = 'Layout Blocks'; + public static $group = 'Layout Elements'; /** * {@inheritdoc} @@ -18,7 +18,7 @@ class PodsField_HTML extends PodsField { /** * {@inheritdoc} */ - public static $label = 'HTML'; + public static $label = 'HTML Content'; /** * {@inheritdoc} @@ -29,92 +29,119 @@ class PodsField_HTML extends PodsField { * {@inheritdoc} */ public function setup() { - - self::$label = __( 'HTML', 'pods' ); + static::$group = __( 'Layout Elements', 'pods' ); + static::$label = __( 'HTML Content', 'pods' ); } /** * {@inheritdoc} */ public function options() { - - $options = array( - 'output_options' => array( + return [ + static::$type . '_content' => [ + 'label' => __( 'HTML Content', 'pods' ), + 'type' => 'code', + ], + static::$type . '_no_label' => [ + 'label' => __( 'Disable the form label', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + 'help' => __( 'By disabling the form label, the HTML will show as full width without the label text. Only the HTML content will be displayed in the form.', 'pods' ), + ], + 'output_options' => [ 'label' => __( 'Output Options', 'pods' ), - 'group' => array( - static::$type . '_allow_html' => array( - 'label' => __( 'Allow HTML?', 'pods' ), + 'type' => 'boolean_group', + 'boolean_group' => [ + static::$type . '_trim' => array( + 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ), 'default' => 1, 'type' => 'boolean', 'dependency' => true, ), - static::$type . '_oembed' => array( - 'label' => __( 'Enable oEmbed?', 'pods' ), + static::$type . '_oembed' => [ + 'label' => __( 'Enable oEmbed', 'pods' ), 'default' => 0, 'type' => 'boolean', - 'help' => array( + 'help' => [ __( 'Embed videos, images, tweets, and other content.', 'pods' ), 'http://codex.wordpress.org/Embeds', - ), - ), - static::$type . '_wptexturize' => array( - 'label' => __( 'Enable wptexturize?', 'pods' ), + ], + ], + static::$type . '_wptexturize' => [ + 'label' => __( 'Enable wptexturize', 'pods' ), 'default' => 1, 'type' => 'boolean', - 'help' => array( - __( 'Transforms less-beautfiul text characters into stylized equivalents.', 'pods' ), + 'help' => [ + __( 'Transforms less-beautiful text characters into stylized equivalents.', 'pods' ), 'http://codex.wordpress.org/Function_Reference/wptexturize', - ), - ), - static::$type . '_convert_chars' => array( - 'label' => __( 'Enable convert_chars?', 'pods' ), + ], + ], + static::$type . '_convert_chars' => [ + 'label' => __( 'Enable convert_chars', 'pods' ), 'default' => 1, 'type' => 'boolean', - 'help' => array( + 'help' => [ __( 'Converts text into valid XHTML and Unicode', 'pods' ), 'http://codex.wordpress.org/Function_Reference/convert_chars', - ), - ), - static::$type . '_wpautop' => array( - 'label' => __( 'Enable wpautop?', 'pods' ), + ], + ], + static::$type . '_wpautop' => [ + 'label' => __( 'Enable wpautop', 'pods' ), 'default' => 1, 'type' => 'boolean', - 'help' => array( + 'help' => [ __( 'Changes double line-breaks in the text into HTML paragraphs.', 'pods' ), 'http://codex.wordpress.org/Function_Reference/wpautop', - ), - ), - static::$type . '_allow_shortcode' => array( - 'label' => __( 'Allow Shortcodes?', 'pods' ), + ], + ], + static::$type . '_allow_shortcode' => [ + 'label' => __( 'Allow Shortcodes', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, - 'help' => array( + 'help' => [ __( 'Embed [shortcodes] that help transform your static content into dynamic content.', 'pods' ), 'http://codex.wordpress.org/Shortcode_API', - ), - ), - ), - ), - ); - - return $options; + ], + ], + ], + ], + ]; } /** * {@inheritdoc} */ public function schema( $options = null ) { - return false; } + /** + * {@inheritdoc} + */ + public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; + + // @codingStandardsIgnoreLine + echo $this->display( $value, $name, $options, $pod, $id ); + } + /** * {@inheritdoc} */ public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { + // Support passing html_content into the options for custom HTML option layouts. + if ( in_array( $value, [ '', null ], true ) ) { + $value = pods_v( static::$type . '_content', $options, '' ); + } + + if ( $options ) { + $options[ static::$type . '_allow_html' ] = 1; + } $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); if ( 1 === (int) pods_v( static::$type . '_oembed', $options, 0 ) ) { $embed = $GLOBALS['wp_embed']; @@ -145,26 +172,18 @@ public function display( $value = null, $name = null, $options = null, $pod = nu return $value; } - /** - * {@inheritdoc} - */ - public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - - $options = (array) $options; - - // @codingStandardsIgnoreLine - echo $this->display( $value, $name, $options, $pod, $id ); - } - /** * {@inheritdoc} */ public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { + if ( $options ) { + $options[ static::$type . '_allow_html' ] = 1; + } $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); - $value = wp_trim_words( $value ); - - return $value; + return wp_trim_words( $value ); } } diff --git a/classes/fields/link.php b/classes/fields/link.php index 4730495cc8..0310729222 100644 --- a/classes/fields/link.php +++ b/classes/fields/link.php @@ -1,5 +1,6 @@ __( 'example.com (force removal of www)', 'pods' ), 'no-http-force-www' => __( 'www.example.com (force www if no sub-domain provided)', 'pods' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_select_existing' => array( - 'label' => __( 'Enable Selecting from Existing Links?', 'pods' ), + 'label' => __( 'Enable Selecting from Existing Links', 'pods' ), 'default' => 1, 'type' => 'boolean', 'dependency' => true, ), static::$type . '_new_window' => array( - 'label' => __( 'Open link in new window by default?', 'pods' ), + 'label' => __( 'Open link in new window by default', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_link_new_window', 0, static::$type ), 'type' => 'boolean', 'dependency' => false, ), 'output_options' => array( 'label' => __( 'Link Text Output Options', 'pods' ), - 'group' => array( + 'type' => 'boolean_group', + 'boolean_group' => array( static::$type . '_allow_shortcode' => array( - 'label' => __( 'Allow Shortcodes?', 'pods' ), + 'label' => __( 'Allow Shortcodes', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, ), static::$type . '_allow_html' => array( - 'label' => __( 'Allow HTML?', 'pods' ), + 'label' => __( 'Allow HTML', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, @@ -90,7 +94,7 @@ public function options() { 'type' => 'text', ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', ), @@ -126,6 +130,8 @@ public function display( $value = null, $name = null, $options = null, $pod = nu if ( ! empty( $value['text'] ) ) { $value['text'] = $this->strip_html( $value['text'], $options ); + $value['text'] = $this->strip_shortcodes( $value['text'], $options ); + $value['text'] = $this->trim_whitespace( $value['text'], $options ); } if ( ! empty( $value['url'] ) ) { @@ -191,15 +197,25 @@ public function display_list( $value = null, $name = null, $options = null, $pod */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; $field_type = 'link'; // Ensure proper format $value = $this->pre_save( $value, $id, $name, $options, null, $pod ); - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -244,7 +260,7 @@ public function validate( $value, $name = null, $options = null, $fields = null, */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; // Update from a single (non array) input field (like website) if the field updates if ( is_string( $value ) ) { @@ -267,6 +283,8 @@ public function pre_save( $value, $id = null, $name = null, $options = null, $fi // Start Title format if ( ! empty( $value['text'] ) ) { $value['text'] = $this->strip_html( $value['text'], $options ); + $value['text'] = $this->strip_shortcodes( $value['text'], $options ); + $value['text'] = $this->trim_whitespace( $value['text'], $options ); } // Start Target format @@ -284,17 +302,19 @@ public function pre_save( $value, $id = null, $name = null, $options = null, $fi * Init the editor needed for WP Link modal to work */ public function validate_link_modal() { + $static_cache = tribe( Static_Cache::class ); - static $init; + $init = (boolean) $static_cache->get( 'init', __METHOD__ ); - if ( empty( $init ) ) { - if ( ! did_action( 'wp_enqueue_editor' ) ) { - add_action( 'shutdown', array( $this, 'add_link_modal' ) ); - } + if ( $init ) { + return; } - $init = true; + if ( ! did_action( 'wp_enqueue_editor' ) && ! has_action( 'shutdown', [ $this, 'add_link_modal' ] ) ) { + add_action( 'shutdown', [ $this, 'add_link_modal' ] ); + } + $static_cache->set( 'init', 1, __METHOD__ ); } /** diff --git a/classes/fields/number.php b/classes/fields/number.php index a8517cef68..8ea145e019 100644 --- a/classes/fields/number.php +++ b/classes/fields/number.php @@ -30,7 +30,8 @@ class PodsField_Number extends PodsField { */ public function setup() { - self::$label = __( 'Plain Number', 'pods' ); + static::$group = __( 'Number', 'pods' ); + static::$label = __( 'Plain Number', 'pods' ); } /** @@ -56,29 +57,33 @@ public function options() { 'number' => __( 'Freeform Number', 'pods' ), 'slider' => __( 'Slider', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_format' => array( - 'label' => __( 'Format', 'pods' ), + 'label' => __( 'Number Format', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_number_format_default', 'i18n' ), 'type' => 'pick', 'data' => array( - 'i18n' => __( 'Localized Default', 'pods' ), - '9,999.99' => '1,234.00', - '9.999,99' => '1.234,00', - '9 999,99' => '1 234,00', - '9999.99' => '1234.00', - '9999,99' => '1234,00', + 'i18n' => __( 'Localized Default', 'pods' ), + '9,999.99' => '1,234.00', + '9999.99' => '1234.00', + '9.999,99' => '1.234,00', + '9999,99' => '1234,00', + '9 999,99' => '1 234,00', + '9\'999.99' => '1\'234.00', ), + 'pick_show_select_text' => 0, ), static::$type . '_decimals' => array( 'label' => __( 'Decimals', 'pods' ), 'default' => 0, 'type' => 'number', 'dependency' => true, + 'help' => __( 'Set to a positive number to enable decimals. The upper limit in the database for this field is 30 decimals.', 'pods' ), ), static::$type . '_format_soft' => array( - 'label' => __( 'Soft format?', 'pods' ), + 'label' => __( 'Soft Formatting', 'pods' ), 'help' => __( 'Remove trailing decimals (0)', 'pods' ), 'default' => 0, 'type' => 'boolean', @@ -92,21 +97,33 @@ public function options() { ), static::$type . '_min' => array( 'label' => __( 'Minimum Number', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'slider' ), - 'default' => 0, + 'depends-on-any' => array( + static::$type . '_format_type' => 'slider', + static::$type . '_html5' => true, + ), + 'default' => '', 'type' => 'text', ), static::$type . '_max' => array( 'label' => __( 'Maximum Number', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'slider' ), - 'default' => 100, + 'depends-on-any' => array( + static::$type . '_format_type' => 'slider', + static::$type . '_html5' => true, + ), + 'default' => '', 'type' => 'text', ), static::$type . '_max_length' => array( - 'label' => __( 'Maximum Length', 'pods' ), + 'label' => __( 'Maximum Digits', 'pods' ), 'default' => 12, 'type' => 'number', - 'help' => __( 'Set to -1 for no limit', 'pods' ), + 'help' => __( 'Set to -1 for no limit. The upper limit in the database for this field is 64 digits.', 'pods' ), + ), + static::$type . '_html5' => array( + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), + 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), + 'depends-on' => array( static::$type . '_format_type' => 'number' ), + 'type' => 'boolean', ), static::$type . '_placeholder' => array( 'label' => __( 'HTML Placeholder', 'pods' ), @@ -194,7 +211,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; $is_read_only = false; @@ -208,7 +225,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = static::$type; } - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $is_read_only = true; } else { @@ -226,8 +243,22 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $value = $this->format( $value, $name, $options, $pod, $id ); } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + // Enforce boolean. + $options[ static::$type . '_html5' ] = filter_var( pods_v( static::$type . '_html5', $options, false ), FILTER_VALIDATE_BOOLEAN ); + $options[ static::$type . '_format_soft' ] = filter_var( pods_v( static::$type . '_format_soft', $options, false ), FILTER_VALIDATE_BOOLEAN ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/number.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -263,6 +294,7 @@ public function validate( $value, $name = null, $options = null, $fields = null, array( '', '.', '' ), $value ); + $check = trim( $check ); $check = preg_replace( '/[0-9\.\-\s]/', '', $check ); diff --git a/classes/fields/oembed.php b/classes/fields/oembed.php index 44deb8d79a..45f15a3313 100644 --- a/classes/fields/oembed.php +++ b/classes/fields/oembed.php @@ -54,7 +54,8 @@ class PodsField_OEmbed extends PodsField { */ public function setup() { - self::$label = __( 'oEmbed', 'pods' ); + static::$group = __( 'Relationships / Media', 'pods' ); + static::$label = __( 'oEmbed', 'pods' ); } /** @@ -120,12 +121,13 @@ public function options() { ); $options[ static::$type . '_enable_providers' ] = array( 'label' => __( 'Select enabled providers', 'pods' ), + 'type' => 'boolean_group', 'depends-on' => array( static::$type . '_restrict_providers' => true ), - 'group' => array(), + 'boolean_group' => array(), ); // Add all the oEmbed providers foreach ( $unique_providers as $provider ) { - $options[ static::$type . '_enable_providers' ]['group'][ static::$type . '_enabled_providers_' . tag_escape( $provider ) ] = array( + $options[ static::$type . '_enable_providers' ]['boolean_group'][ static::$type . '_enabled_providers_' . tag_escape( $provider ) ] = array( 'label' => $provider, 'type' => 'boolean', 'default' => 0, @@ -173,14 +175,14 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { $value = implode( ' ', $value ); } - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; } else { @@ -190,7 +192,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $options['readonly'] = true; } - pods_view( PODS_DIR . 'ui/fields/oembed.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/oembed.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -228,8 +241,9 @@ public function validate( $value, $name = null, $options = null, $fields = null, * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); // Only allow ONE URL if ( ! empty( $value ) ) { @@ -477,13 +491,14 @@ public function admin_ajax_oembed_update_preview() { $params = pods_unslash( (array) $_POST ); if ( ! empty( $params['_nonce_pods_oembed'] ) && ! empty( $params['pods_field_oembed_value'] ) && wp_verify_nonce( $params['_nonce_pods_oembed'], 'pods_field_oembed_preview' ) ) { - $value = $this->strip_html( $params['pods_field_oembed_value'] ); - $name = ''; $options = array(); if ( ! empty( $params['pods_field_oembed_name'] ) ) { - $name = $this->strip_html( $params['pods_field_oembed_name'] ); + $name = $params['pods_field_oembed_value']; + $name = $this->strip_html( $name ); + $name = $this->strip_shortcodes( $name ); + $name = $this->trim_whitespace( $name ); } if ( ! empty( $params['pods_field_oembed_options'] ) ) { @@ -491,7 +506,7 @@ public function admin_ajax_oembed_update_preview() { } // Load the field to get it's options. - $options = pods_api()->load_field( (object) $options ); + $options = pods_api()->load_field( $options ); // Field options are stored here, if not, just stay with the full options array. if ( ! empty( $options['options'] ) ) { diff --git a/classes/fields/paragraph.php b/classes/fields/paragraph.php index b135582768..648124ed7a 100644 --- a/classes/fields/paragraph.php +++ b/classes/fields/paragraph.php @@ -34,7 +34,8 @@ class PodsField_Paragraph extends PodsField { */ public function setup() { - self::$label = __( 'Plain Paragraph Text', 'pods' ); + static::$group = __( 'Paragraph', 'pods' ); + static::$label = __( 'Plain Paragraph Text', 'pods' ); } /** @@ -54,57 +55,64 @@ public function options() { ), 'output_options' => array( 'label' => __( 'Output Options', 'pods' ), - 'group' => array( + 'type' => 'boolean_group', + 'boolean_group' => array( + static::$type . '_trim' => array( + 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + 'dependency' => true, + ), static::$type . '_allow_html' => array( - 'label' => __( 'Allow HTML?', 'pods' ), + 'label' => __( 'Allow HTML', 'pods' ), 'default' => 1, 'type' => 'boolean', 'dependency' => true, ), static::$type . '_oembed' => array( - 'label' => __( 'Enable oEmbed?', 'pods' ), + 'label' => __( 'Enable oEmbed', 'pods' ), 'default' => 0, 'type' => 'boolean', 'help' => array( __( 'Embed videos, images, tweets, and other content.', 'pods' ), - 'http://codex.wordpress.org/Embeds', + 'https://wordpress.org/support/article/embeds/', ), ), static::$type . '_wptexturize' => array( - 'label' => __( 'Enable wptexturize?', 'pods' ), + 'label' => __( 'Enable wptexturize', 'pods' ), 'default' => 1, 'type' => 'boolean', 'help' => array( - __( 'Transforms less-beautfiul text characters into stylized equivalents.', 'pods' ), - 'http://codex.wordpress.org/Function_Reference/wptexturize', + __( 'Transforms less-beautiful text characters into stylized equivalents.', 'pods' ), + 'https://developer.wordpress.org/reference/functions/wptexturize/', ), ), static::$type . '_convert_chars' => array( - 'label' => __( 'Enable convert_chars?', 'pods' ), + 'label' => __( 'Enable convert_chars', 'pods' ), 'default' => 1, 'type' => 'boolean', 'help' => array( __( 'Converts text into valid XHTML and Unicode', 'pods' ), - 'http://codex.wordpress.org/Function_Reference/convert_chars', + 'https://developer.wordpress.org/reference/functions/convert_chars/', ), ), static::$type . '_wpautop' => array( - 'label' => __( 'Enable wpautop?', 'pods' ), + 'label' => __( 'Enable wpautop', 'pods' ), 'default' => 1, 'type' => 'boolean', 'help' => array( __( 'Changes double line-breaks in the text into HTML paragraphs', 'pods' ), - 'http://codex.wordpress.org/Function_Reference/wpautop', + 'https://developer.wordpress.org/reference/functions/wpautop/', ), ), static::$type . '_allow_shortcode' => array( - 'label' => __( 'Allow Shortcodes?', 'pods' ), + 'label' => __( 'Allow Shortcodes', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, 'help' => array( __( 'Embed [shortcodes] that help transform your static content into dynamic content.', 'pods' ), - 'http://codex.wordpress.org/Shortcode_API', + 'https://codex.wordpress.org/Shortcode_API', ), ), ), @@ -118,7 +126,7 @@ public function options() { ), static::$type . '_max_length' => array( 'label' => __( 'Maximum Length', 'pods' ), - 'default' => 0, + 'default' => -1, 'type' => 'number', 'help' => __( 'Set to -1 for no limit', 'pods' ), ), @@ -134,8 +142,8 @@ public function options() { ); if ( function_exists( 'Markdown' ) ) { - $options['output_options']['group'][ static::$type . '_allow_markdown' ] = array( - 'label' => __( 'Allow Markdown Syntax?', 'pods' ), + $options['output_options']['boolean_group'][ static::$type . '_allow_markdown' ] = array( + 'label' => __( 'Allow Markdown Syntax', 'pods' ), 'default' => 0, 'type' => 'boolean', ); @@ -164,8 +172,9 @@ public function schema( $options = null ) { * {@inheritdoc} */ public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); if ( 1 === (int) pods_v( static::$type . '_oembed', $options, 0 ) ) { $embed = $GLOBALS['wp_embed']; @@ -205,14 +214,14 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { $value = implode( "\n", $value ); } - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; } else { @@ -222,15 +231,28 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $options['readonly'] = true; } - pods_view( PODS_DIR . 'ui/fields/textarea.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/textarea.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); + } /** * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); $length = (int) pods_v( static::$type . '_max_length', $options, 0 ); @@ -245,11 +267,10 @@ public function pre_save( $value, $id = null, $name = null, $options = null, $fi * {@inheritdoc} */ public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); - $value = wp_trim_words( $value ); - - return $value; + return wp_trim_words( $value ); } } diff --git a/classes/fields/password.php b/classes/fields/password.php index 3f59c80a4f..27e1721ff2 100644 --- a/classes/fields/password.php +++ b/classes/fields/password.php @@ -30,31 +30,40 @@ class PodsField_Password extends PodsField { */ public function setup() { - self::$label = __( 'Password', 'pods' ); + static::$group = __( 'Text', 'pods' ); + static::$label = __( 'Password', 'pods' ); } /** * {@inheritdoc} */ public function options() { - - $options = array( - static::$type . '_max_length' => array( + $options = [ + static::$type . '_repeatable' => [ + 'label' => __( 'Repeatable Field', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'help' => __( 'Making a field repeatable will add controls next to the field which allows users to Add/Remove/Reorder additional values. These values are saved in the database as an array, so searching and filtering by them may require further adjustments".', 'pods' ), + 'boolean_yes_label' => '', + 'dependency' => true, + 'developer_mode' => true, + ], + static::$type . '_max_length' => [ 'label' => __( 'Maximum Length', 'pods' ), 'default' => 255, 'type' => 'number', 'help' => __( 'Set to -1 for no limit', 'pods' ), - ), - static::$type . '_placeholder' => array( + ], + static::$type . '_placeholder' => [ 'label' => __( 'HTML Placeholder', 'pods' ), 'default' => '', 'type' => 'text', - 'help' => array( + 'help' => [ __( 'Placeholders can provide instructions or an example of the required data format for a field. Please note: It is not a replacement for labels or description text, and it is less accessible for people using screen readers.', 'pods' ), 'https://www.w3.org/WAI/tutorials/forms/instructions/#placeholder-text', - ), - ), - ); + ], + ], + ]; return $options; } @@ -80,14 +89,14 @@ public function schema( $options = null ) { */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { $value = implode( ' ', $value ); } - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; } else { @@ -97,7 +106,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $options['readonly'] = true; } - pods_view( PODS_DIR . 'ui/fields/password.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/password.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** diff --git a/classes/fields/phone.php b/classes/fields/phone.php index fa90d98b5d..e0f5cf9ed6 100644 --- a/classes/fields/phone.php +++ b/classes/fields/phone.php @@ -30,7 +30,8 @@ class PodsField_Phone extends PodsField { */ public function setup() { - self::$label = __( 'Phone', 'pods' ); + static::$group = __( 'Text', 'pods' ); + static::$label = __( 'Phone', 'pods' ); } /** @@ -62,12 +63,14 @@ public function options() { 'international' => __( 'Any (no validation available)', 'pods' ), ), ), + 'pick_show_select_text' => 0, ), static::$type . '_options' => array( 'label' => __( 'Phone Options', 'pods' ), - 'group' => array( + 'type' => 'boolean_group', + 'boolean_group' => array( static::$type . '_enable_phone_extension' => array( - 'label' => __( 'Enable Phone Extension?', 'pods' ), + 'label' => __( 'Enable Phone Extension', 'pods' ), 'default' => 1, 'type' => 'boolean', ), @@ -80,7 +83,7 @@ public function options() { 'help' => __( 'Set to -1 for no limit', 'pods' ), ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', ), @@ -119,7 +122,7 @@ public function schema( $options = null ) { */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -128,7 +131,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'phone'; - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; @@ -142,7 +145,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'text'; } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/phone.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -163,13 +177,11 @@ public function validate( $value, $name = null, $options = null, $fields = null, if ( is_array( $check ) ) { $errors = $check; - } else { - if ( 0 < strlen( $value ) && '' === $check ) { - if ( $this->is_required( $options ) ) { - $errors[] = sprintf( __( 'The %s field is required.', 'pods' ), $label ); - } else { - $errors[] = sprintf( __( 'Invalid phone number provided for the field %s.', 'pods' ), $label ); - } + } elseif ( '' === $check && 0 < strlen( $value ) ) { + if ( $this->is_required( $options ) ) { + $errors[] = sprintf( __( 'The %s field is required.', 'pods' ), $label ); + } else { + $errors[] = sprintf( __( 'Invalid phone number provided for the field %s.', 'pods' ), $label ); } } @@ -184,38 +196,45 @@ public function validate( $value, $name = null, $options = null, $fields = null, * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; - $options = (array) $options; + $phone_format = pods_v( static::$type . '_format', $options, '999-999-9999 x999', true ); - if ( 'international' !== pods_v( static::$type . '_format', $options ) ) { + if ( 'international' !== $phone_format ) { // Clean input - $number = preg_replace( '/([^0-9ext])/', '', $value ); + $number = preg_replace( '/(\+\d+)/', '', $value ); + $number = preg_replace( '/([^0-9ext])/', '', $number ); $number = str_replace( - array( '-', '.', 'ext', 'x', 't', 'e', '(', ')' ), array( - '', - '', + [ + 'ext', + 'x', + 't', + 'e' + ], + [ '|', '|', '', '', - '', - '', - ), $number + ], + $number ); + $extension = ''; + // Get extension - $extension = explode( '|', $number ); - if ( 1 < count( $extension ) ) { - $number = preg_replace( '/([^0-9])/', '', $extension[0] ); - $extension = preg_replace( '/([^0-9])/', '', $extension[1] ); - } else { - $extension = ''; + $extension_data = explode( '|', $number ); + + if ( 1 < count( $extension_data ) ) { + $number = $extension_data[0]; + $extension = $extension_data[1]; } // Build number array $numbers = str_split( $number, 3 ); + // Split up the numbers: 123-456-7890: 123[0] 456[1] 789[2]0[3] if ( isset( $numbers[3] ) ) { $numbers[2] .= $numbers[3]; $numbers = array( $numbers[0], $numbers[1], $numbers[2] ); @@ -224,17 +243,20 @@ public function pre_save( $value, $id = null, $name = null, $options = null, $fi } // Format number - if ( '(999) 999-9999 x999' === pods_v( static::$type . '_format', $options ) ) { + if ( '(999) 999-9999 x999' === $phone_format ) { $number_count = count( $numbers ); if ( 1 === $number_count ) { + // Invalid number. $value = ''; } elseif ( 2 === $number_count ) { + // Basic number, no area code! $value = implode( '-', $numbers ); } else { + // Full number. $value = '(' . $numbers[0] . ') ' . $numbers[1] . '-' . $numbers[2]; } - } elseif ( '999.999.9999 x999' === pods_v( static::$type . '_format', $options ) ) { + } elseif ( '999.999.9999 x999' === $phone_format ) { $value = implode( '.', $numbers ); } else { $value = implode( '-', $numbers ); diff --git a/classes/fields/pick.php b/classes/fields/pick.php index 1add3bd1d3..8a7e410ed7 100644 --- a/classes/fields/pick.php +++ b/classes/fields/pick.php @@ -1,5 +1,10 @@ array( - 'label' => __( 'Selection Type', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'default' => 'single', - 'type' => 'pick', - 'data' => array( + 'label' => __( 'Selection Type', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'default' => 'single', + 'type' => 'pick', + 'data' => array( 'single' => __( 'Single Select', 'pods' ), 'multi' => __( 'Multiple Select', 'pods' ), ), - 'dependency' => true, + 'pick_show_select_text' => 0, + 'dependency' => true, ), static::$type . '_format_single' => array( - 'label' => __( 'Format', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'single' ), - 'default' => 'dropdown', - 'type' => 'pick', - 'data' => apply_filters( + 'label' => __( 'Input Type', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'depends-on' => array( static::$type . '_format_type' => 'single' ), + 'default' => 'dropdown', + 'type' => 'pick', + 'data' => apply_filters( 'pods_form_ui_field_pick_format_single_options', array( 'dropdown' => __( 'Drop Down', 'pods' ), 'radio' => __( 'Radio Buttons', 'pods' ), 'autocomplete' => __( 'Autocomplete', 'pods' ), - 'list' => __( 'List view', 'pods' ), + 'list' => __( 'List View (with reordering)', 'pods' ), ) ), - 'dependency' => true, + 'pick_show_select_text' => 0, + 'dependency' => true, ), static::$type . '_format_multi' => array( - 'label' => __( 'Format', 'pods' ), - 'help' => __( 'help', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'multi' ), - 'default' => 'checkbox', - 'type' => 'pick', - 'data' => apply_filters( + 'label' => __( 'Input Type', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'depends-on' => array( static::$type . '_format_type' => 'multi' ), + 'default' => 'checkbox', + 'type' => 'pick', + 'data' => apply_filters( 'pods_form_ui_field_pick_format_multi_options', array( 'checkbox' => __( 'Checkboxes', 'pods' ), - 'multiselect' => __( 'Multi Select', 'pods' ), + 'multiselect' => __( 'Multi Select (basic selection)', 'pods' ), 'autocomplete' => __( 'Autocomplete', 'pods' ), - 'list' => __( 'List view', 'pods' ), + 'list' => __( 'List View (with reordering)', 'pods' ), ) ), - 'dependency' => true, + 'pick_show_select_text' => 0, + 'dependency' => true, ), static::$type . '_display_format_multi' => array( - 'label' => __( 'Display Format', 'pods' ), - 'help' => __( 'Used as format for front-end display', 'pods' ), - 'depends-on' => array( static::$type . '_format_type' => 'multi' ), - 'default' => 'default', - 'type' => 'pick', - 'data' => array( + 'label' => __( 'Display Format', 'pods' ), + 'help' => __( 'Used as format for front-end display', 'pods' ), + 'depends-on' => array( static::$type . '_format_type' => 'multi' ), + 'default' => 'default', + 'type' => 'pick', + 'data' => array( 'default' => __( 'Item 1, Item 2, and Item 3', 'pods' ), 'non_serial' => __( 'Item 1, Item 2 and Item 3', 'pods' ), 'custom' => __( 'Custom separator (without "and")', 'pods' ), ), - 'dependency' => true, + 'pick_show_select_text' => 0, + 'dependency' => true, ), static::$type . '_display_format_separator' => array( 'label' => __( 'Display Format Separator', 'pods' ), @@ -203,7 +213,12 @@ public function options() { 'label' => __( 'Allow Add New', 'pods' ), 'help' => __( 'Allow new related records to be created in a modal window', 'pods' ), 'wildcard-on' => array( - static::$type . '_object' => array( '^post-type-(?!(custom-css|customize-changeset)).*$', '^taxonomy-.*$', '^user$', '^pod-.*$' ), + static::$type . '_object' => array( + '^post_type-(?!(custom_css|customize_changeset)).*$', + '^taxonomy-.*$', + '^user$', + '^pod-.*$' + ), ), 'type' => 'boolean', 'default' => 1, @@ -211,19 +226,27 @@ public function options() { static::$type . '_taggable' => array( 'label' => __( 'Taggable', 'pods' ), 'help' => __( 'Allow new values to be inserted when using an Autocomplete field', 'pods' ), + 'depends-on-any' => array( + static::$type . '_format_single' => 'autocomplete', + static::$type . '_format_multi' => 'autocomplete', + ), 'excludes-on' => array( - static::$type . '_format_single' => array( 'dropdown', 'radio', 'list' ), - static::$type . '_format_multi' => array( 'checkbox', 'multiselect', 'list' ), - static::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ), + static::$type . '_object' => array_merge( array( + 'site', + 'network', + ), self::simple_objects() ), + static::$type . '_allow_add_new' => false, ), 'type' => 'boolean', 'default' => 0, ), static::$type . '_show_icon' => array( 'label' => __( 'Show Icons', 'pods' ), + 'depends-on-any' => array( + static::$type . '_format_single' => 'list', + static::$type . '_format_multi' => 'list', + ), 'excludes-on' => array( - static::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ), - static::$type . '_format_multi' => array( 'checkbox', 'multiselect', 'autocomplete' ), static::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ), ), 'type' => 'boolean', @@ -231,9 +254,11 @@ public function options() { ), static::$type . '_show_edit_link' => array( 'label' => __( 'Show Edit Links', 'pods' ), + 'depends-on-any' => array( + static::$type . '_format_single' => 'list', + static::$type . '_format_multi' => 'list', + ), 'excludes-on' => array( - static::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ), - static::$type . '_format_multi' => array( 'checkbox', 'multiselect', 'autocomplete' ), static::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ), ), 'type' => 'boolean', @@ -241,9 +266,11 @@ public function options() { ), static::$type . '_show_view_link' => array( 'label' => __( 'Show View Links', 'pods' ), + 'depends-on-any' => array( + static::$type . '_format_single' => 'list', + static::$type . '_format_multi' => 'list', + ), 'excludes-on' => array( - static::$type . '_format_single' => array( 'dropdown', 'radio', 'autocomplete' ), - static::$type . '_format_multi' => array( 'checkbox', 'multiselect', 'autocomplete' ), static::$type . '_object' => array_merge( array( 'site', 'network' ), self::simple_objects() ), ), 'type' => 'boolean', @@ -251,17 +278,18 @@ public function options() { ), static::$type . '_select_text' => array( 'label' => __( 'Default Select Text', 'pods' ), - 'help' => __( 'This is the text use for the default "no selection" dropdown item, if empty, it will default to "-- Select One --"', 'pods' ), + 'help' => __( 'This is the text used for the default "no selection" dropdown item. If left empty, it will default to "-- Select One --"', 'pods' ), 'depends-on' => array( static::$type . '_format_type' => 'single', static::$type . '_format_single' => 'dropdown', ), 'default' => '', + 'text_placeholder' => __( '-- Select One --', 'pods' ), 'type' => 'text', ), static::$type . '_limit' => array( 'label' => __( 'Selection Limit', 'pods' ), - 'help' => __( 'help', 'pods' ), + 'help' => __( 'Default is "0" for no limit, but you can enter 1 or more to limit the number of items that can be selected.', 'pods' ), 'depends-on' => array( static::$type . '_format_type' => 'multi' ), 'default' => 0, 'type' => 'number', @@ -292,8 +320,8 @@ public function options() { 'type' => 'text', ), static::$type . '_user_role' => array( - 'label' => __( 'Limit list to Role(s)', 'pods' ), - 'help' => __( 'help', 'pods' ), + 'label' => __( 'Limit list by Role(s)', 'pods' ), + 'help' => __( 'You can choose to limit Users available for selection by specific role(s).', 'pods' ), 'depends-on' => array( static::$type . '_object' => 'user' ), 'default' => '', 'type' => 'pick', @@ -332,13 +360,13 @@ public function options() { $post_type_pick_objects = array(); foreach ( get_post_types( '', 'names' ) as $post_type ) { - $post_type_pick_objects[] = 'post-type_' . $post_type; + $post_type_pick_objects[] = 'post_type-' . $post_type; } $options[ static::$type . '_post_status' ] = array( 'name' => 'post_status', - 'label' => __( 'Post Status', 'pods' ), - 'help' => __( 'help', 'pods' ), + 'label' => __( 'Limit list by Post Status', 'pods' ), + 'help' => __( 'You can choose to limit Posts available for selection by one or more specific post status.', 'pods' ), 'type' => 'pick', 'pick_object' => 'post-status', 'pick_format_type' => 'multi', @@ -379,6 +407,10 @@ public function register_related_object( $name, $label, $options = null ) { $related_object = array_merge( $related_object, $options ); + if ( $related_object['data_callback'] instanceof Closure ) { + return pods_error( 'Pods does not support closures for data callbacks' ); + } + self::$custom_related_objects[ $name ] = $related_object; return true; @@ -433,12 +465,14 @@ public function setup_related_objects( $force = false ) { $pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')'; } - // Settings pods for relationships. - $_pods = PodsMeta::$settings; - - foreach ( $_pods as $pod ) { - $pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')'; - } + /** + * Allow filtering the list of Pods to show in the list of relationship objects. + * + * @since 2.8.0 + * + * @param array $pod_options List of Pods to show in the list of relationship objects. + */ + $pod_options = apply_filters( 'pods_field_pick_setup_related_objects_pods', $pod_options ); asort( $pod_options ); @@ -450,18 +484,36 @@ public function setup_related_objects( $force = false ) { ); } - // Post Types for relationships. - $post_types = get_post_types(); + /** + * Prevent ability to extend core Pods content types. + * + * @param bool $ignore_internal Default is true, when set to false Pods internal content types can not be extended. + * + * @since 2.3.19 + */ + $ignore_internal = apply_filters( 'pods_pick_ignore_internal', true ); + + // Public Post Types for relationships. + $post_types = get_post_types( [ 'public' => true ] ); asort( $post_types ); - $ignore = array( 'attachment', 'revision', 'nav_menu_item' ); + $ignored_post_types = [ + 'attachment', + 'revision', + 'nav_menu_item', + 'custom_css', + 'customize_changeset', + 'oembed_cache', + 'user_request', + 'wp_template', + ]; foreach ( $post_types as $post_type => $label ) { - if ( in_array( $post_type, $ignore, true ) || empty( $post_type ) ) { + if ( empty( $post_type ) || in_array( $post_type, $ignored_post_types, true ) ) { unset( $post_types[ $post_type ] ); continue; - } elseif ( 0 === strpos( $post_type, '_pods_' ) && apply_filters( 'pods_pick_ignore_internal', true ) ) { + } elseif ( $ignore_internal && 0 === strpos( $post_type, '_pods_' ) ) { unset( $post_types[ $post_type ] ); continue; @@ -476,27 +528,47 @@ public function setup_related_objects( $force = false ) { ); } + // Post Types for relationships. + $post_types = get_post_types( [ 'public' => false ] ); + asort( $post_types ); + + foreach ( $post_types as $post_type => $label ) { + if ( empty( $post_type ) || in_array( $post_type, $ignored_post_types, true ) ) { + unset( $post_types[ $post_type ] ); + + continue; + } elseif ( $ignore_internal && 0 === strpos( $post_type, '_pods_' ) ) { + unset( $post_types[ $post_type ] ); + + continue; + } + + $post_type = get_post_type_object( $post_type ); + + self::$related_objects[ 'post_type-' . $post_type->name ] = array( + 'label' => $post_type->label . ' (' . $post_type->name . ')', + 'group' => __( 'Post Types (Private)', 'pods' ), + 'bidirectional' => true, + ); + } + // Taxonomies for relationships. $taxonomies = get_taxonomies(); asort( $taxonomies ); - $ignore = array( 'nav_menu', 'post_format' ); + $ignored_taxonomies = [ + 'nav_menu', + 'post_format', + 'wp_theme', + ]; foreach ( $taxonomies as $taxonomy => $label ) { - /** - * Prevent ability to extend core Pods content types. - * - * @param bool $ignore_internal Default is true, when set to false Pods internal content types can not be extended. - * - * @since 2.3.19 - */ - $ignore_internal = apply_filters( 'pods_pick_ignore_internal', true ); - - if ( in_array( $taxonomy, $ignore, true ) || empty( $taxonomy ) ) { + + if ( empty( $taxonomy ) || in_array( $taxonomy, $ignored_taxonomies, true ) ) { unset( $taxonomies[ $taxonomy ] ); continue; - } elseif ( 0 === strpos( $taxonomy, '_pods_' ) && $ignore_internal ) { + } elseif ( $ignore_internal && 0 === strpos( $taxonomy, '_pods_' ) ) { unset( $taxonomies[ $taxonomy ] ); continue; @@ -608,7 +680,7 @@ public function setup_related_objects( $force = false ) { do_action( 'pods_form_ui_field_pick_related_objects_predefined' ); if ( did_action( 'init' ) ) { - pods_transient_set( 'pods_related_objects', self::$related_objects ); + pods_transient_set( 'pods_related_objects', self::$related_objects, WEEK_IN_SECONDS ); } }//end if @@ -625,7 +697,16 @@ public function setup_related_objects( $force = false ) { } } - return $new_data_loaded; + if ( $new_data_loaded ) { + /** + * Allow hooking in when new data has been loaded. + * + * @since 2.8.0 + */ + do_action( 'pods_form_ui_field_pick_related_objects_new_data_loaded' ); + } + + return true; } @@ -737,17 +818,9 @@ public function display( $value = null, $name = null, $options = null, $pod = nu /** * @var $pod Pods Pods object. */ - $fields = $pod->fields; - - if ( ! empty( $pod->pod_data['object_fields'] ) ) { - $fields = array_merge( $fields, $pod->pod_data['object_fields'] ); - } + $fields = pods_config_get_all_fields( $pod ); } elseif ( is_array( $pod ) && isset( $pod['fields'] ) ) { - $fields = $pod['fields']; - - if ( ! empty( $pod['object_fields'] ) ) { - $fields = array_merge( $fields, $pod['object_fields'] ); - } + $fields = pods_config_get_all_fields( $pod ); } $args = array( @@ -781,7 +854,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $type = pods_v( 'type', $options, static::$type ); @@ -794,117 +867,139 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = wp_enqueue_script( 'pods-select2' ); $this->render_input_script( $args ); - - /** - * @todo Support custom integrations. - * - * Run the action 'pods_form_ui_field_pick_input_' . pods_v( static::$type . '_format_type', $options, 'single' ) . '_' . pods_v( static::$type . '_format_multi', $options, 'checkbox' ) - * Run the action 'pods_form_ui_field_pick_input' - * Pass the arguments: $name, $value, $options, $pod, $id - */ - } /** * {@inheritdoc} */ public function build_dfv_field_options( $options, $args ) { + // Use field object if it was provided. + if ( isset( $options['_field_object'] ) ) { + $field = $options['_field_object']; + + unset( $options['_field_object'] ); + + $options = pods_config_merge_data( $field, $options ); + } + + $field_options = $options instanceof \Pods\Whatsit ? $options->export() : $options; + + if ( ! isset( $field_options['id'] ) ) { + $field_options['id'] = 0; + } - $options['grouped'] = 1; + // Enforce defaults. + $all_options = static::options(); - if ( empty( $options[ $args->type . '_object' ] ) ) { - $options[ $args->type . '_object' ] = ''; + foreach ( $all_options as $option_name => $option ) { + $default = pods_v( 'default', $option, '' ); + + $field_options[ $option_name ] = pods_v( $option_name, $field_options, $default ); + + if ( '' === $field_options[ $option_name ] ) { + $field_options[ $option_name ] = $default; + } + } + + $field_options['grouped'] = 1; + + if ( empty( $field_options[ $args->type . '_object' ] ) ) { + $field_options[ $args->type . '_object' ] = ''; } - if ( empty( $options[ $args->type . '_val' ] ) ) { - $options[ $args->type . '_val' ] = ''; + if ( empty( $field_options[ $args->type . '_val' ] ) ) { + $field_options[ $args->type . '_val' ] = ''; } - $options['table_info'] = array(); + // Unset the table info for now. + $field_options['table_info'] = []; - $custom = pods_v( $args->type . '_custom', $options, false ); + $custom = pods_v( $args->type . '_custom', $field_options, false ); - $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $args->name, $args->value, $options, $args->pod, $args->id ); + $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $args->name, $args->value, $field_options, $args->pod, $args->id ); $ajax = false; - if ( $this->can_ajax( $args->type, $options ) ) { + if ( $this->can_ajax( $args->type, $field_options ) ) { $ajax = true; - if ( ! empty( self::$field_data ) && self::$field_data['id'] === $options['id'] ) { - $ajax = (boolean) self::$field_data['autocomplete']; + $static_cache = tribe( Static_Cache::class ); + + $field_data = $static_cache->get( $field_options['name'] . '/' . $field_options['id'], __CLASS__ . '/field_data' ) ?: []; + + if ( isset( $field_data['autocomplete'] ) ) { + $ajax = (boolean) $field_data['autocomplete']; } } - $ajax = apply_filters( 'pods_form_ui_field_pick_ajax', $ajax, $args->name, $args->value, $options, $args->pod, $args->id ); + $ajax = apply_filters( 'pods_form_ui_field_pick_ajax', $ajax, $args->name, $args->value, $field_options, $args->pod, $args->id ); - if ( 0 === (int) pods_v( $args->type . '_ajax', $options, 1 ) ) { + if ( 0 === (int) pods_v( $args->type . '_ajax', $field_options, 1 ) ) { $ajax = false; } - $options[ $args->type . '_ajax' ] = (int) $ajax; + $field_options[ $args->type . '_ajax' ] = (int) $ajax; - $format_type = pods_v( $args->type . '_format_type', $options, 'single', true ); + $format_type = pods_v( $args->type . '_format_type', $field_options, 'single', true ); $limit = 1; if ( 'single' === $format_type ) { - $format_single = pods_v( $args->type . '_format_single', $options, 'dropdown', true ); + $format_single = pods_v( $args->type . '_format_single', $field_options, 'dropdown', true ); if ( 'dropdown' === $format_single ) { - $options['view_name'] = 'select'; + $field_options['view_name'] = 'select'; } elseif ( 'radio' === $format_single ) { - $options['view_name'] = 'radio'; + $field_options['view_name'] = 'radio'; } elseif ( 'autocomplete' === $format_single ) { - $options['view_name'] = 'select2'; + $field_options['view_name'] = 'select2'; } elseif ( 'list' === $format_single ) { - $options['view_name'] = 'list'; + $field_options['view_name'] = 'list'; } else { - $options['view_name'] = $format_single; + $field_options['view_name'] = $format_single; } } elseif ( 'multi' === $format_type ) { - $format_multi = pods_v( $args->type . '_format_multi', $options, 'checkbox', true ); + $format_multi = pods_v( $args->type . '_format_multi', $field_options, 'checkbox', true ); if ( ! empty( $args->value ) && ! is_array( $args->value ) ) { $args->value = explode( ',', $args->value ); } if ( 'checkbox' === $format_multi ) { - $options['view_name'] = 'checkbox'; + $field_options['view_name'] = 'checkbox'; } elseif ( 'multiselect' === $format_multi ) { - $options['view_name'] = 'select'; + $field_options['view_name'] = 'select'; } elseif ( 'autocomplete' === $format_multi ) { - $options['view_name'] = 'select2'; + $field_options['view_name'] = 'select2'; } elseif ( 'list' === $format_multi ) { - $options['view_name'] = 'list'; + $field_options['view_name'] = 'list'; } else { - $options['view_name'] = $format_multi; + $field_options['view_name'] = $format_multi; } $limit = 0; - if ( ! empty( $options[ $args->type . '_limit' ] ) ) { - $limit = absint( $options[ $args->type . '_limit' ] ); + if ( ! empty( $field_options[ $args->type . '_limit' ] ) ) { + $limit = absint( $field_options[ $args->type . '_limit' ] ); } } else { - $options['view_name'] = $format_type; - }//end if + $field_options['view_name'] = $format_type; + } - $options[ $args->type . '_limit' ] = $limit; + $field_options[ $args->type . '_limit' ] = $limit; - $options['ajax_data'] = $this->build_dfv_autocomplete_ajax_data( $options, $args, $ajax ); + $field_options['ajax_data'] = $this->build_dfv_autocomplete_ajax_data( $field_options, $args, $ajax ); /** * Allow overriding some of the Select2 options used in the JS init. * - * @param array|null $select2_overrides Override options for Select2/SelectWoo. - * * @since 2.7.0 + * + * @param array|null $select2_overrides Override options for Select2/SelectWoo. */ - $options['select2_overrides'] = apply_filters( 'pods_pick_select2_overrides', null ); - - return $options; + $field_options['select2_overrides'] = apply_filters( 'pods_pick_select2_overrides', null ); + return $field_options; } /** @@ -933,7 +1028,7 @@ public function build_dfv_autocomplete_ajax_data( $options, $args, $ajax = false $pod_id = 0; } - $field_id = (int) $options['id']; + $field_id = (int) pods_v( 'id', $options ); $id = (int) $args->id; @@ -968,6 +1063,12 @@ public function build_dfv_field_config( $args ) { $config = parent::build_dfv_field_config( $args ); + // Ensure data is passed in for relationship fields. + if ( ! isset( $config['data'] ) && ! empty( $args->options['data'] ) ) { + $config['data'] = $args->options['data']; + } + + // Default optgroup handling to off. if ( ! isset( $config['optgroup'] ) ) { $config['optgroup'] = false; } @@ -1000,6 +1101,9 @@ public function build_dfv_field_config( $args ) { $config[ $args->type . '_show_edit_link' ] = false; } + $config[ $args->type . '_allow_add_new' ] = filter_var( pods_v( $args->type . '_allow_add_new', $config ), FILTER_VALIDATE_BOOLEAN ); + $config[ $args->type . '_show_edit_link' ] = filter_var( pods_v( $args->type . '_show_edit_link', $config ), FILTER_VALIDATE_BOOLEAN ); + $iframe = array( 'src' => '', 'url' => '', @@ -1110,7 +1214,6 @@ public function build_dfv_field_config( $args ) { if ( ! empty( $iframe['src'] ) ) { // We extend wp.media.view.Modal for modal add/edit, we must ensure we load the template for it wp_enqueue_media(); - } $config['iframe_src'] = $iframe['src']; @@ -1128,10 +1231,17 @@ public function build_dfv_field_item_data( $args ) { $args->options['supports_thumbnails'] = null; - $item_data = array(); + $item_data = []; + $data = []; if ( ! empty( $args->options['data'] ) ) { - $item_data = $this->build_dfv_field_item_data_recurse( $args->options['data'], $args ); + $data = $args->options['data']; + } elseif ( ! empty( $args->data ) ) { + $data = $args->data; + } + + if ( [] !== $data ) { + $item_data = $this->build_dfv_field_item_data_recurse( $data, $args ); } return $item_data; @@ -1441,17 +1551,15 @@ public function validate( $value, $name = null, $options = null, $fields = null, $options['id'] = (int) $options['id']; - if ( ! isset( self::$related_data[ $options['id'] ] ) || empty( self::$related_data[ $options['id'] ] ) ) { - self::$related_data[ $options['id'] ] = array(); - } + $static_cache = tribe( Static_Cache::class ); + + $related_data = $static_cache->get( $options['name'] . '/' . $options['id'], __CLASS__ . '/related_data' ) ?: []; if ( ! empty( $related_sister_id ) && ! in_array( $related_object, $simple_tableless_objects, true ) ) { - $related_pod = self::$api->load_pod( - array( - 'name' => $related_val, - 'table_info' => false, - ), false - ); + $related_pod = self::$api->load_pod( [ + 'name' => $related_val, + 'auto_setup' => true, + ] ); if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) { $related_field = false; @@ -1466,9 +1574,9 @@ public function validate( $value, $name = null, $options = null, $fields = null, } if ( ! empty( $related_field ) ) { - $current_ids = self::$api->lookup_related_items( $fields[ $name ]['id'], $pod['id'], $id, $fields[ $name ], $pod ); + $current_ids = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod ); - self::$related_data[ $options['id'] ]['current_ids'] = $current_ids; + $related_data[ 'current_ids_' . $id ] = $current_ids; $value_ids = $value; @@ -1482,10 +1590,12 @@ public function validate( $value, $name = null, $options = null, $fields = null, // Get ids to remove. $remove_ids = array_diff( $current_ids, $value_ids ); - $related_required = (boolean) pods_v( 'required', $related_field['options'], 0 ); - $related_pick_limit = (int) pods_v( static::$type . '_limit', $related_field['options'], 0 ); + $related_data[ 'remove_ids_' . $id ] = $remove_ids; + + $related_required = (boolean) pods_v( 'required', $related_field, 0 ); + $related_pick_limit = (int) pods_v( static::$type . '_limit', $related_field, 0 ); - if ( 'single' === pods_v( static::$type . '_format_type', $related_field['options'] ) ) { + if ( 'single' === pods_v( static::$type . '_format_type', $related_field ) ) { $related_pick_limit = 1; } @@ -1494,7 +1604,7 @@ public function validate( $value, $name = null, $options = null, $fields = null, foreach ( $remove_ids as $related_id ) { $bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); - self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] = $bidirectional_ids; + $related_data[ 'related_ids_' . $related_id ] = $bidirectional_ids; if ( empty( $bidirectional_ids ) || ( in_array( (int) $id, $bidirectional_ids, true ) && 1 === count( $bidirectional_ids ) ) ) { // Translators: %1$s and %2$s stand for field labels. @@ -1511,27 +1621,31 @@ public function validate( $value, $name = null, $options = null, $fields = null, }//end if }//end if - if ( empty( self::$related_data[ $options['id'] ] ) ) { - unset( self::$related_data[ $options['id'] ] ); - } else { - self::$related_data[ $options['id'] ]['related_pod'] = $related_pod; - self::$related_data[ $options['id'] ]['related_field'] = $related_field; - self::$related_data[ $options['id'] ]['related_pick_limit'] = $related_pick_limit; + if ( ! empty( $related_data ) ) { + $related_data['related_pod'] = $related_pod; + $related_data['related_field'] = $related_field; + $related_data['related_pick_limit'] = $related_pick_limit; + + $static_cache->set( $options['name'] . '/' . $options['id'], $related_data, __CLASS__ . '/related_data' ); - $pick_limit = (int) pods_v( static::$type . '_limit', $options['options'], 0 ); + $pick_limit = (int) pods_v( static::$type . '_limit', $options, 0 ); - if ( 'single' === pods_v( static::$type . '_format_type', $options['options'] ) ) { + if ( 'single' === pods_v( static::$type . '_format_type', $options ) ) { $pick_limit = 1; } $related_field['id'] = (int) $related_field['id']; - if ( ! isset( self::$related_data[ $related_field['id'] ] ) || empty( self::$related_data[ $related_field['id'] ] ) ) { - self::$related_data[ $related_field['id'] ] = array( + $bidirectional_related_data = $static_cache->get( $related_field['name'] . '/' . $related_field['id'], __CLASS__ . '/related_data' ) ?: []; + + if ( empty( $bidirectional_related_data ) ) { + $bidirectional_related_data = [ 'related_pod' => $pod, 'related_field' => $options, 'related_pick_limit' => $pick_limit, - ); + ]; + + $static_cache->set( $related_field['name'] . '/' . $related_field['id'], $bidirectional_related_data, __CLASS__ . '/related_data' ); } }//end if @@ -1554,77 +1668,116 @@ public function save( $value, $id = null, $name = null, $options = null, $fields $options['id'] = (int) $options['id']; - if ( ! isset( self::$related_data[ $options['id'] ] ) ) { + $related_pod = null; + $related_field = null; + $related_pick_limit = 0; + $current_ids = []; + $remove_ids = []; + + $value_ids = array_unique( array_filter( $value ) ); + + $static_cache = tribe( Static_Cache::class ); + + $related_data = $static_cache->get( $options['name'] . '/' . $options['id'], __CLASS__ . '/related_data' ) ?: []; + + if ( ! empty( $related_data ) ) { + $related_pod = $related_data['related_pod']; + $related_field = $related_data['related_field']; + $related_pick_limit = $related_data['related_pick_limit']; + $current_ids = $related_data[ 'current_ids_' . $id ]; + $remove_ids = $related_data[ 'remove_ids_' . $id ]; + } elseif ( $options instanceof Field || $options instanceof Value_Field ) { + $related_field = $options->get_bidirectional_field(); + + if ( ! $related_field ) { + return; + } + + $related_pod = $related_field->get_parent_object(); + $related_pick_limit = $related_field->get_arg( 'related_pick_limit', 0 ); + $current_ids = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod ); + + // Get ids to remove. + $remove_ids = array_diff( $current_ids, $value_ids ); + } + + if ( empty( $related_field ) || empty( $related_pod ) ) { return; } - $related_pod = self::$related_data[ $options['id'] ]['related_pod']; - $related_field = self::$related_data[ $options['id'] ]['related_field']; - $related_pick_limit = self::$related_data[ $options['id'] ]['related_pick_limit']; + // Handle the bi-directional relationship updates. - // Bidirectional relationship updates. - if ( ! empty( $related_field ) ) { - // Don't use no conflict mode unless this isn't the current pod type. - $no_conflict = true; + $no_conflict = true; - if ( $related_pod['type'] !== $pod['type'] ) { - $no_conflict = pods_no_conflict_check( $related_pod['type'] ); + // Only check no conflict mode if this isn't the current pod type. + if ( $related_pod['type'] !== $pod['type'] ) { + $no_conflict = pods_no_conflict_check( $related_pod['type'] ); + } + + if ( ! $no_conflict ) { + pods_no_conflict_on( $related_pod['type'] ); + } + + if ( empty( $value_ids ) ) { + // Remove all bidirectional relationships. + if ( ! empty( $remove_ids ) ) { + self::$api->delete_relationships( $remove_ids, $id, $related_pod, $related_field ); + self::$api->delete_relationships( $id, $remove_ids, $pod, $options ); } if ( ! $no_conflict ) { - pods_no_conflict_on( $related_pod['type'] ); + pods_no_conflict_off( $related_pod['type'] ); } - $value = array_filter( $value ); + return; + } - foreach ( $value as $related_id ) { - if ( isset( self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] ) && ! empty( self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ] ) ) { - $bidirectional_ids = self::$related_data[ $options['id'] ][ 'related_ids_' . $related_id ]; - } else { - $bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); - } + foreach ( $value_ids as $related_id ) { + if ( ! empty( $related_data[ 'related_ids_' . $related_id ] ) ) { + $bidirectional_ids = $related_data[ 'related_ids_' . $related_id ]; + } else { + $bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); + } - $bidirectional_ids = array_filter( $bidirectional_ids ); + $bidirectional_ids = array_filter( $bidirectional_ids ); - if ( empty( $bidirectional_ids ) ) { - $bidirectional_ids = array(); - } + if ( empty( $bidirectional_ids ) ) { + $bidirectional_ids = array(); + } - $remove_ids = array(); + $bidirectional_remove_ids = array(); - if ( 0 < $related_pick_limit && ! empty( $bidirectional_ids ) && ! in_array( $id, $bidirectional_ids, true ) ) { - $total_bidirectional_ids = count( $bidirectional_ids ); + if ( 0 < $related_pick_limit && ! empty( $bidirectional_ids ) && ! in_array( $id, $bidirectional_ids, true ) ) { + $total_bidirectional_ids = count( $bidirectional_ids ); - while ( $related_pick_limit <= $total_bidirectional_ids ) { - $remove_ids[] = (int) array_pop( $bidirectional_ids ); + while ( $related_pick_limit <= $total_bidirectional_ids ) { + $bidirectional_remove_ids[] = (int) array_pop( $bidirectional_ids ); - $total_bidirectional_ids = count( $bidirectional_ids ); - } + $total_bidirectional_ids = count( $bidirectional_ids ); } + } - // Remove this item from related items no longer related to. - $remove_ids = array_unique( array_filter( $remove_ids ) ); - - if ( ! in_array( $id, $bidirectional_ids, true ) ) { - // Add to related items. - $bidirectional_ids[] = $id; - } elseif ( empty( $remove_ids ) ) { - // Nothing to change. - continue; - } + // Remove this item from related items no longer related to. + $bidirectional_remove_ids = array_unique( array_filter( $bidirectional_remove_ids ) ); - self::$api->save_relationships( $related_id, $bidirectional_ids, $related_pod, $related_field ); + if ( ! in_array( $id, $bidirectional_ids, true ) ) { + // Add to related items. + $bidirectional_ids[] = $id; + } elseif ( empty( $remove_ids ) ) { + // Nothing to change. + continue; + } - if ( ! empty( $remove_ids ) ) { - self::$api->delete_relationships( $remove_ids, $related_id, $pod, $options ); - } - }//end foreach + self::$api->save_relationships( $related_id, $bidirectional_ids, $related_pod, $related_field ); - if ( ! $no_conflict ) { - pods_no_conflict_off( $related_pod['type'] ); + if ( ! empty( $bidirectional_remove_ids ) ) { + self::$api->delete_relationships( $bidirectional_remove_ids, $related_id, $pod, $options ); } - }//end if + }//end foreach + if ( ! $no_conflict ) { + pods_no_conflict_off( $related_pod['type'] ); + } } /** @@ -1653,12 +1806,10 @@ public function delete( $id = null, $name = null, $options = null, $pod = null ) $related_sister_id = (int) pods_v( 'sister_id', $options, 0 ); if ( ! empty( $related_sister_id ) && ! in_array( $related_object, $simple_tableless_objects, true ) ) { - $related_pod = self::$api->load_pod( - array( - 'name' => $related_val, - 'table_info' => false, - ), false - ); + $related_pod = self::$api->load_pod( [ + 'name' => $related_val, + 'auto_setup' => true, + ] ); if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) { $related_field = false; @@ -1709,13 +1860,6 @@ public function ui( $id, $value, $name = null, $options = null, $fields = null, * {@inheritdoc} */ public function data( $name, $value = null, $options = null, $pod = null, $id = null, $in_form = true ) { - - if ( isset( $options['options'] ) ) { - $options = array_merge( $options, $options['options'] ); - - unset( $options['options'] ); - } - $data = pods_v( 'data', $options, null, true ); $object_params = array( @@ -1739,8 +1883,23 @@ public function data( $name, $value = null, $options = null, $pod = null, $id = $data = $this->get_object_data( $object_params ); } - if ( 'single' === pods_v( static::$type . '_format_type', $options, 'single' ) && 'dropdown' === pods_v( static::$type . '_format_single', $options, 'dropdown' ) ) { - $data = array( '' => pods_v( static::$type . '_select_text', $options, __( '-- Select One --', 'pods' ), true ) ) + $data; + if ( + 'single' === pods_v( static::$type . '_format_type', $options, 'single' ) + && 'dropdown' === pods_v( static::$type . '_format_single', $options, 'dropdown' ) + //&& 0 !== (int) pods_v( static::$type . '_show_select_text', $options, 1 ) + && 0 === (int) pods_v( 'required', $options, 0 ) + ) { + $default_select = [ + '' => pods_v( static::$type . '_select_text', $options, __( '-- Select One --', 'pods' ), true ), + ]; + + // Unset to prevent conflict. + if ( isset( $data[''] ) ) { + unset( $data[''] ); + } + + // Prevent resetting the numeric ID keys when adding the empty option via array_merge, use union instead. + $data = $default_select + $data; } $data = apply_filters( 'pods_field_pick_data', $data, $name, $value, $options, $pod, $id ); @@ -1764,17 +1923,11 @@ public function data( $name, $value = null, $options = null, $pod = null, $id = public function simple_value( $name, $value = null, $options = null, $pod = null, $id = null, $raw = false ) { if ( in_array( pods_v( static::$type . '_object', $options ), self::simple_objects(), true ) ) { - if ( isset( $options['options'] ) ) { - $options = array_merge( $options, $options['options'] ); - - unset( $options['options'] ); - } - if ( ! is_array( $value ) && 0 < strlen( $value ) ) { $simple = @json_decode( $value, true ); if ( is_array( $simple ) ) { - $value = $simple; + $value = (array) $simple; } } @@ -1866,13 +2019,6 @@ public function simple_value( $name, $value = null, $options = null, $pod = null * @since 2.2.0 */ public function value_to_label( $name, $value = null, $options = null, $pod = null, $id = null ) { - - if ( isset( $options['options'] ) ) { - $options = array_merge( $options, $options['options'] ); - - unset( $options['options'] ); - } - $data = pods_v( 'data', $options, null, true ); $object_params = array( @@ -1916,16 +2062,18 @@ public function value_to_label( $name, $value = null, $options = null, $pod = nu * Get available items from a relationship field. * * @param array|string $field Field array or field name. - * @param array $options Field options array overrides. + * @param array $deprecated Field options array overrides. * @param array $object_params Additional get_object_data options. * * @return array An array of available items from a relationship field */ - public function get_field_data( $field, $options = array(), $object_params = array() ) { + public function get_field_data( $field, $deprecated = null, $object_params = array() ) { + $options = array(); + + $is_field_object = $field instanceof Field; - // Handle field array overrides. - if ( is_array( $field ) ) { - $options = array_merge( $field, $options ); + if ( is_array( $field ) || $is_field_object ) { + $options = $field; } // Get field name from array. @@ -1936,9 +2084,6 @@ public function get_field_data( $field, $options = array(), $object_params = arr return array(); } - // Options normalization. - $options = array_merge( $options, pods_v( 'options', $options, array(), true ) ); - // Setup object params. $object_params = array_merge( array( @@ -2025,7 +2170,6 @@ public function get_object_data( $object_params = null ) { */ $object_params = apply_filters( 'pods_field_pick_object_data_params', $object_params ); - $object_params['options'] = (array) $object_params['options']; $object_params['data_params'] = (array) $object_params['data_params']; $name = $object_params['name']; @@ -2039,17 +2183,18 @@ public function get_object_data( $object_params = null ) { $limit = (int) $object_params['limit']; $autocomplete = false; - if ( isset( $options['options'] ) ) { - $options = array_merge( $options, $options['options'] ); + // Use field object if it was provided. + if ( isset( $options['_field_object'] ) ) { + $options = $options['_field_object']; - unset( $options['options'] ); + $name = $options->get_name(); } $data = apply_filters( 'pods_field_pick_object_data', null, $name, $value, $options, $pod, $id, $object_params ); $items = array(); if ( ! isset( $options[ static::$type . '_object' ] ) ) { - $data = pods_v( 'data', $options, array(), true ); + $data = pods_v( 'data', $options ); } $simple = false; @@ -2057,7 +2202,14 @@ public function get_object_data( $object_params = null ) { if ( null === $data ) { $data = array(); - if ( 'custom-simple' === $options[ static::$type . '_object' ] ) { + $pick_object = pods_v( static::$type . '_object', $options, null, true ); + + // No pick object means this has no configuration to work from. + if ( empty( $pick_object ) ) { + return $data; + } + + if ( 'custom-simple' === $pick_object ) { $custom = pods_v( static::$type . '_custom', $options, '' ); $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $name, $value, $options, $pod, $id, $object_params ); @@ -2069,6 +2221,7 @@ public function get_object_data( $object_params = null ) { $custom = explode( "\n", trim( $custom ) ); foreach ( $custom as $custom_value ) { + $custom_value = trim( trim( $custom_value, '|' ) ); $custom_label = explode( '|', $custom_value ); if ( empty( $custom_label ) ) { @@ -2093,27 +2246,38 @@ public function get_object_data( $object_params = null ) { $simple = true; }//end if - } elseif ( isset( self::$related_objects[ $options[ static::$type . '_object' ] ] ) && isset( self::$related_objects[ $options[ static::$type . '_object' ] ]['data'] ) && ! empty( self::$related_objects[ $options[ static::$type . '_object' ] ]['data'] ) ) { + } elseif ( + $pick_object + && $this->setup_related_objects() + && isset( self::$related_objects[ $pick_object ] ) + && ! empty( self::$related_objects[$pick_object ]['data'] ) + ) { $data = self::$related_objects[ $options[ static::$type . '_object' ] ]['data']; $simple = true; - } elseif ( isset( self::$related_objects[ $options[ static::$type . '_object' ] ] ) && isset( self::$related_objects[ $options[ static::$type . '_object' ] ]['data_callback'] ) && is_callable( self::$related_objects[ $options[ static::$type . '_object' ] ]['data_callback'] ) ) { + } elseif ( + $pick_object + && $this->setup_related_objects() + && isset( self::$related_objects[ $pick_object ] ) + && isset( self::$related_objects[ $pick_object ]['data_callback'] ) + && is_callable( self::$related_objects[ $pick_object ]['data_callback'] ) + ) { $data = call_user_func_array( - self::$related_objects[ $options[ static::$type . '_object' ] ]['data_callback'], array( + self::$related_objects[ $options[ static::$type . '_object' ] ]['data_callback'], [ $name, $value, $options, $pod, $id, - ) + ] ); if ( 'data' === $context ) { - self::$field_data = array( - 'field' => $name, - 'id' => $options['id'], + $static_cache = tribe( Static_Cache::class ); + + $static_cache->set( $name . '/' . $options['id'], [ 'autocomplete' => false, - ); + ], __CLASS__ . '/field_data' ); } $simple = true; @@ -2125,13 +2289,21 @@ public function get_object_data( $object_params = null ) { } elseif ( 'simple_value' !== $context ) { $pick_val = pods_v( static::$type . '_val', $options ); - if ( 'table' === pods_v( static::$type . '_object', $options ) ) { + if ( 'table' === $pick_object ) { $pick_val = pods_v( static::$type . '_table', $options, $pick_val, true ); } + $related_pod = null; + if ( '__current__' === $pick_val ) { - if ( is_object( $pod ) ) { + if ( $pod instanceof Pod ) { + $pick_val = $pod->get_name(); + + $related_pod = $pod; + } elseif ( $pod instanceof Pods ) { $pick_val = $pod->pod; + + $related_pod = $pod->pod_data; } elseif ( is_array( $pod ) ) { $pick_val = $pod['name']; } elseif ( 0 < strlen( $pod ) ) { @@ -2139,23 +2311,27 @@ public function get_object_data( $object_params = null ) { } } - $options['table_info'] = pods_api()->get_table_info( pods_v( static::$type . '_object', $options ), $pick_val, null, null, $object_params ); + $table_info = pods_v( 'table_info', $options ); - $search_data = pods_data(); - $search_data->table( $options['table_info'] ); - - $default_field_index = $search_data->field_index; + if ( empty( $table_info ) && ! empty( $pick_object ) ) { + $table_info = pods_api()->get_table_info( $pick_object, $pick_val, null, null, $object_params ); + } - if ( isset( $options['table_info']['pod'] ) && ! empty( $options['table_info']['pod'] ) && isset( $options['table_info']['pod']['name'] ) ) { - $search_data->pod = $options['table_info']['pod']['name']; - $search_data->fields = $options['table_info']['pod']['fields']; + if ( null === $related_pod && $table_info && $table_info['pod'] ) { + $related_pod = $table_info['pod']; } + $search_data = pods_data( $related_pod ); + $search_data->table( $table_info ); + + $default_field_index = $search_data->field_index; + $params = array( 'select' => "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`", 'table' => $search_data->table, - 'where' => pods_v( static::$type . '_where', $options, (array) $options['table_info']['where_default'], true ), + 'where' => pods_v( static::$type . '_where', $options, (array) $table_info['where_default'], true ), 'orderby' => pods_v( static::$type . '_orderby', $options, null, true ), + 'having' => pods_v( static::$type . '_having', $options, null, true ), 'groupby' => pods_v( static::$type . '_groupby', $options, null, true ), 'pagination' => false, 'search' => false, @@ -2165,10 +2341,14 @@ public function get_object_data( $object_params = null ) { $params['select'] .= ', `t`.`path`'; } - if ( ! empty( $params['where'] ) && (array) $options['table_info']['where_default'] !== $params['where'] ) { + if ( ! empty( $params['where'] ) && (array) $table_info['where_default'] !== $params['where'] ) { $params['where'] = pods_evaluate_tags( $params['where'], true ); } + if ( ! empty( $params['having'] ) ) { + $params['having'] = pods_evaluate_tags( $params['having'], true ); + } + if ( empty( $params['where'] ) || ( ! is_array( $params['where'] ) && '' === trim( $params['where'] ) ) ) { $params['where'] = array(); } elseif ( ! is_array( $params['where'] ) ) { @@ -2182,29 +2362,29 @@ public function get_object_data( $object_params = null ) { $display = trim( pods_v( static::$type . '_display', $options ), ' {@}' ); if ( 0 < strlen( $display ) ) { - if ( isset( $options['table_info']['pod'] ) && ! empty( $options['table_info']['pod'] ) ) { - if ( isset( $options['table_info']['pod']['object_fields'] ) && isset( $options['table_info']['pod']['object_fields'][ $display ] ) ) { + if ( isset( $table_info['pod'] ) && ! empty( $table_info['pod'] ) ) { + if ( isset( $table_info['pod']['object_fields'] ) && isset( $table_info['pod']['object_fields'][ $display ] ) ) { $search_data->field_index = $display; $params['select'] .= ", `t`.`{$search_data->field_index}`"; } else { $search_data->field_index = sanitize_key( $display ); - if ( isset( $options['table_info']['pod']['fields'][ $display ] ) && 'table' === $options['table_info']['pod']['storage'] && ! in_array( - $options['table_info']['pod']['type'], array( + if ( isset( $table_info['pod']['fields'][ $display ] ) && 'table' === $table_info['pod']['storage'] && ! in_array( + $table_info['pod']['type'], array( 'pod', 'table', ), true ) ) { $params['select'] .= ", `d`.`{$search_data->field_index}`"; - } elseif ( 'meta' === $options['table_info']['pod']['storage'] ) { + } elseif ( 'meta' === $table_info['pod']['storage'] ) { $params['select'] .= ", `{$search_data->field_index}`.`meta_value` AS {$search_data->field_index}"; } else { $params['select'] .= ", `t`.`{$search_data->field_index}`"; } }//end if - } elseif ( isset( $options['table_info']['object_fields'] ) && isset( $options['table_info']['object_fields'][ $display ] ) ) { + } elseif ( isset( $table_info['object_fields'] ) && isset( $table_info['object_fields'][ $display ] ) ) { $search_data->field_index = $display; $params['select'] .= ", `t`.`{$search_data->field_index}`"; @@ -2235,8 +2415,8 @@ public function get_object_data( $object_params = null ) { } } - if ( $hierarchy && $options['table_info']['object_hierarchical'] && ! empty( $options['table_info']['field_parent'] ) ) { - $params['select'] .= ', ' . $options['table_info']['field_parent_select']; + if ( $hierarchy && $table_info['object_hierarchical'] && ! empty( $table_info['field_parent'] ) ) { + $params['select'] .= ', ' . $table_info['field_parent_select']; } if ( $autocomplete ) { @@ -2339,22 +2519,29 @@ public function get_object_data( $object_params = null ) { }//end if }//end if + if ( empty( $params['where'] ) ) { + $params['where'] = null; + } + $results = $search_data->select( $params ); - if ( $autocomplete && $params['limit'] < $search_data->total_found() ) { + if ( $autocomplete && 0 < $params['limit'] && $params['limit'] < $search_data->total_found() ) { if ( ! empty( $value ) ) { $ids = $value; - if ( is_array( $ids ) && isset( $ids[0] ) && is_array( $ids[0] ) ) { - $ids = wp_list_pluck( $ids, $search_data->field_id ); - } + if ( is_array( $ids ) ) { + if ( isset( $ids[0] ) && is_array( $ids[0] ) ) { + $ids = wp_list_pluck( $ids, $search_data->field_id ); + } - if ( $params['limit'] < count( $ids ) ) { - $params['limit'] = count( $ids ); - } + if ( $params['limit'] < count( $ids ) ) { + $params['limit'] = count( $ids ); + } - if ( is_array( $ids ) ) { + $ids = array_map( 'absint', $ids ); $ids = implode( ', ', $ids ); + } else { + $ids = (int) $ids; } if ( is_array( $params['where'] ) ) { @@ -2373,18 +2560,18 @@ public function get_object_data( $object_params = null ) { }//end if if ( 'data' === $context ) { - self::$field_data = array( - 'field' => $name, - 'id' => $options['id'], + $static_cache = tribe( Static_Cache::class ); + + $static_cache->set( $name . '/' . $options['id'], [ 'autocomplete' => $autocomplete, - ); + ], __CLASS__ . '/field_data' ); } - if ( $hierarchy && ! $autocomplete && ! empty( $results ) && $options['table_info']['object_hierarchical'] && ! empty( $options['table_info']['field_parent'] ) ) { + if ( $hierarchy && ! $autocomplete && ! empty( $results ) && $table_info['object_hierarchical'] && ! empty( $table_info['field_parent'] ) ) { $select_args = array( - 'id' => $options['table_info']['field_id'], - 'index' => $options['table_info']['field_index'], - 'parent' => $options['table_info']['field_parent'], + 'id' => $table_info['field_id'], + 'index' => $table_info['field_index'], + 'parent' => $table_info['field_parent'], ); $results = pods_hierarchical_select( $results, $select_args ); @@ -2393,7 +2580,7 @@ public function get_object_data( $object_params = null ) { $ids = array(); if ( ! empty( $results ) ) { - $display_filter = pods_v( 'display_filter', pods_v( 'options', pods_v( $search_data->field_index, $search_data->pod_data['object_fields'] ) ) ); + $display_filter = pods_v( 'display_filter', pods_v( $search_data->field_index, $search_data->object_fields ) ); foreach ( $results as $result ) { $result = get_object_vars( $result ); @@ -2421,7 +2608,7 @@ public function get_object_data( $object_params = null ) { } if ( 0 < strlen( $display_filter ) ) { - $display_filter_args = pods_v( 'display_filter_args', pods_v( 'options', pods_v( $field_index, $search_data->pod_data['object_fields'] ) ) ); + $display_filter_args = pods_v( 'display_filter_args', pods_v( $field_index, $search_data->pod_data['object_fields'] ) ); $filter_args = array( $display_filter, @@ -2430,6 +2617,11 @@ public function get_object_data( $object_params = null ) { if ( ! empty( $display_filter_args ) ) { foreach ( (array) $display_filter_args as $display_filter_arg ) { + // Manual solution to a problem that won't map correctly. + if ( 'post_ID' === $display_filter_arg ) { + $display_filter_arg = 'ID'; + } + if ( isset( $result[ $display_filter_arg ] ) ) { $filter_args[] = $result[ $display_filter_arg ]; } @@ -2603,15 +2795,20 @@ public function admin_ajax_relationship() { $page = (int) $params->page; } + $autocomplete_formats = [ + 'autocomplete', + 'list', + ]; + if ( ! isset( $params->query ) || '' === trim( $params->query ) ) { pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin ); } elseif ( empty( $pod ) || empty( $field ) || (int) $pod['id'] !== (int) $field['pod_id'] || ! isset( $pod['fields'][ $field['name'] ] ) ) { pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin ); } elseif ( 'pick' !== $field['type'] || empty( $field['table_info'] ) ) { pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin ); - } elseif ( 'single' === pods_v( static::$type . '_format_type', $field ) && 'autocomplete' === pods_v( static::$type . '_format_single', $field ) ) { + } elseif ( 'single' === pods_v( static::$type . '_format_type', $field ) && ! in_array( pods_v( static::$type . '_format_single', $field ), $autocomplete_formats, true ) ) { pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin ); - } elseif ( 'multi' === pods_v( static::$type . '_format_type', $field ) && 'autocomplete' === pods_v( static::$type . '_format_multi', $field ) ) { + } elseif ( 'multi' === pods_v( static::$type . '_format_type', $field ) && ! in_array( pods_v( static::$type . '_format_multi', $field ), $autocomplete_formats, true ) ) { pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin ); } @@ -2621,7 +2818,7 @@ public function admin_ajax_relationship() { // The value of the field. 'value' => null, // Field options. - 'options' => array_merge( $field, $field['options'] ), + 'options' => $field, // Pod data. 'pod' => $pod, // Item ID. @@ -3247,7 +3444,7 @@ public function data_ca_provinces( $name = null, $value = null, $options = null, } /** - * Data callback for US States. + * Data callback for Days of the Week. * * @param string|null $name The name of the field. * @param string|array|null $value The value of the field. @@ -3271,7 +3468,7 @@ public function data_days_of_week( $name = null, $value = null, $options = null, } /** - * Data callback for US States. + * Data callback for Months of the Year. * * @param string|null $name The name of the field. * @param string|array|null $value The value of the field. @@ -3319,10 +3516,10 @@ public function admin_modal_bail( $item_id, $item_title, $field_args ) { $model_data = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $field_args ); ?> render_input_script( $args ); } /** diff --git a/classes/fields/taxonomy.php b/classes/fields/taxonomy.php index 757a0171dc..ed28d22363 100644 --- a/classes/fields/taxonomy.php +++ b/classes/fields/taxonomy.php @@ -1,5 +1,4 @@ array( 'label' => __( 'Output Options', 'pods' ), - 'group' => array( - static::$type . '_allow_shortcode' => array( - 'label' => __( 'Allow Shortcodes?', 'pods' ), - 'default' => 0, + 'type' => 'boolean_group', + 'boolean_group' => array( + static::$type . '_trim' => array( + 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ), + 'default' => 1, 'type' => 'boolean', 'dependency' => true, ), static::$type . '_allow_html' => array( - 'label' => __( 'Allow HTML?', 'pods' ), + 'label' => __( 'Allow HTML', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + ), + static::$type . '_allow_shortcode' => array( + 'label' => __( 'Allow Shortcodes', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, @@ -111,8 +119,9 @@ public function schema( $options = null ) { * {@inheritdoc} */ public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); if ( 1 === (int) pods_v( static::$type . '_allow_shortcode', $options ) ) { $value = do_shortcode( $value ); @@ -126,7 +135,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { @@ -135,7 +144,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $is_read_only = (boolean) pods_v( 'read_only', $options, false ); - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( $is_read_only ) { $options['readonly'] = true; } else { @@ -145,7 +154,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $options['readonly'] = true; } - pods_view( PODS_DIR . 'ui/fields/text.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/text.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -183,8 +203,9 @@ public function validate( $value, $name = null, $options = null, $fields = null, * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); $length = (int) pods_v( static::$type . '_max_length', $options, 255 ); @@ -199,8 +220,9 @@ public function pre_save( $value, $id = null, $name = null, $options = null, $fi * {@inheritdoc} */ public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); if ( 0 === (int) pods_v( static::$type . '_allow_html', $options, 0, true ) ) { $value = wp_trim_words( $value ); diff --git a/classes/fields/time.php b/classes/fields/time.php index 362ec1ee88..052c9778ce 100644 --- a/classes/fields/time.php +++ b/classes/fields/time.php @@ -1,5 +1,4 @@ __( '24 hour', 'pods' ), 'custom' => __( 'Custom format', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_format_custom' => array( @@ -117,6 +118,7 @@ public function options() { 'hh_mm' => date_i18n( 'h:i' ), 'hh_mm_ss' => date_i18n( 'h:i:s' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_format_24' => array( @@ -128,14 +130,15 @@ public function options() { 'hh_mm' => date_i18n( 'H:i' ), 'hh_mm_ss' => date_i18n( 'H:i:s' ), ), + 'pick_show_select_text' => 0, ), static::$type . '_allow_empty' => array( - 'label' => __( 'Allow empty value?', 'pods' ), + 'label' => __( 'Allow empty value', 'pods' ), 'default' => 1, 'type' => 'boolean', ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', ), diff --git a/classes/fields/website.php b/classes/fields/website.php index 84fc1aa7b9..fc8b0ce7bf 100644 --- a/classes/fields/website.php +++ b/classes/fields/website.php @@ -29,7 +29,8 @@ class PodsField_Website extends PodsField { */ public function setup() { - self::$label = __( 'Website', 'pods' ); + static::$group = __( 'Text', 'pods' ); + static::$label = __( 'Website', 'pods' ); } @@ -52,30 +53,31 @@ public function options() { 'default' => 'normal', 'type' => 'pick', 'data' => array( - 'normal' => __( 'http://example.com/', 'pods' ), - 'no-www' => __( 'http://example.com/ (remove www)', 'pods' ), - 'force-www' => __( 'http://www.example.com/ (force www if no sub-domain provided)', 'pods' ), + 'normal' => __( 'https://example.com/', 'pods' ), + 'no-www' => __( 'https://example.com/ (remove www)', 'pods' ), + 'force-www' => __( 'https://www.example.com/ (force www if no sub-domain provided)', 'pods' ), 'no-http' => __( 'example.com', 'pods' ), 'no-http-no-www' => __( 'example.com (force removal of www)', 'pods' ), 'no-http-force-www' => __( 'www.example.com (force www if no sub-domain provided)', 'pods' ), 'none' => __( 'No format', 'pods' ), ), + 'pick_show_select_text' => 0, 'dependency' => true, ), static::$type . '_allow_port' => array( - 'label' => __( 'Allow port in URL?', 'pods' ), + 'label' => __( 'Allow port in URL', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_website_port', 0, static::$type ), 'type' => 'boolean', 'dependency' => true, ), static::$type . '_clickable' => array( - 'label' => __( 'Output as a link?', 'pods' ), + 'label' => __( 'Output as a link', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_website_clickable', 0, static::$type ), 'type' => 'boolean', 'dependency' => true, ), static::$type . '_new_window' => array( - 'label' => __( 'Open link in new window?', 'pods' ), + 'label' => __( 'Open link in new window', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_website_new_window', 0, static::$type ), 'type' => 'boolean', 'depends-on' => array( static::$type . '_clickable' => true ), @@ -87,7 +89,7 @@ public function options() { 'help' => __( 'Set to -1 for no limit', 'pods' ), ), static::$type . '_html5' => array( - 'label' => __( 'Enable HTML5 Input Field?', 'pods' ), + 'label' => __( 'Enable HTML5 Input Field', 'pods' ), 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ), 'type' => 'boolean', 'excludes-on' => array( static::$type . '_format' => array( 'no-http', 'no-http-no-www', 'no-http-force-www' ) ), @@ -146,7 +148,7 @@ public function display( $value = null, $name = null, $options = null, $pod = nu * {@inheritdoc} */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; // Ensure proper format @@ -154,7 +156,7 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'website'; - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; @@ -168,7 +170,18 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'text'; } - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** @@ -210,7 +223,7 @@ public function validate( $value, $name = null, $options = null, $fields = null, * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; // Update from a array input field (like link) if the field updates if ( is_array( $value ) ) { @@ -248,7 +261,11 @@ public function validate_url( $value, $options = null ) { } if ( 'none' === pods_v( static::$type . '_format', $options ) ) { - return $this->strip_html( $value, $options ); + $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); + + return $value; } if ( is_array( $value ) ) { diff --git a/classes/fields/wysiwyg.php b/classes/fields/wysiwyg.php index c218dca08b..d497a75261 100644 --- a/classes/fields/wysiwyg.php +++ b/classes/fields/wysiwyg.php @@ -30,7 +30,8 @@ class PodsField_WYSIWYG extends PodsField { */ public function setup() { - self::$label = __( 'WYSIWYG (Visual Editor)', 'pods' ); + static::$group = __( 'Paragraph', 'pods' ); + static::$label = __( 'WYSIWYG (Visual Editor)', 'pods' ); } /** @@ -55,17 +56,20 @@ public function options() { 'data' => apply_filters( 'pods_form_ui_field_wysiwyg_editors', array( 'tinymce' => __( 'TinyMCE (WP Default)', 'pods' ), - 'cleditor' => __( 'CLEditor', 'pods' ), + 'quill' => __( 'Quill Editor', 'pods' ), + 'cleditor' => __( 'CLEditor (No longer available, now using Quill Editor)', 'pods' ), ) ), + 'pick_show_select_text' => 0, 'dependency' => true, ), 'editor_options' => array( 'label' => __( 'Editor Options', 'pods' ), + 'type' => 'boolean_group', 'depends-on' => array( static::$type . '_editor' => 'tinymce' ), - 'group' => array( + 'boolean_group' => array( static::$type . '_media_buttons' => array( - 'label' => __( 'Enable Media Buttons?', 'pods' ), + 'label' => __( 'Enable Media Buttons', 'pods' ), 'default' => 1, 'type' => 'boolean', ), @@ -81,51 +85,58 @@ public function options() { ), 'output_options' => array( 'label' => __( 'Output Options', 'pods' ), - 'group' => array( + 'type' => 'boolean_group', + 'boolean_group' => array( + static::$type . '_trim' => array( + 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + 'dependency' => true, + ), static::$type . '_oembed' => array( - 'label' => __( 'Enable oEmbed?', 'pods' ), + 'label' => __( 'Enable oEmbed', 'pods' ), 'default' => 0, 'type' => 'boolean', 'help' => array( __( 'Embed videos, images, tweets, and other content.', 'pods' ), - 'http://codex.wordpress.org/Embeds', + 'https://wordpress.org/support/article/embeds/', ), ), static::$type . '_wptexturize' => array( - 'label' => __( 'Enable wptexturize?', 'pods' ), + 'label' => __( 'Enable wptexturize', 'pods' ), 'default' => 1, 'type' => 'boolean', 'help' => array( - __( 'Transforms less-beautfiul text characters into stylized equivalents.', 'pods' ), - 'http://codex.wordpress.org/Function_Reference/wptexturize', + __( 'Transforms less-beautiful text characters into stylized equivalents.', 'pods' ), + 'https://developer.wordpress.org/reference/functions/wptexturize/', ), ), static::$type . '_convert_chars' => array( - 'label' => __( 'Enable convert_chars?', 'pods' ), + 'label' => __( 'Enable convert_chars', 'pods' ), 'default' => 1, 'type' => 'boolean', 'help' => array( __( 'Converts text into valid XHTML and Unicode', 'pods' ), - 'http://codex.wordpress.org/Function_Reference/convert_chars', + 'https://developer.wordpress.org/reference/functions/convert_chars/', ), ), static::$type . '_wpautop' => array( - 'label' => __( 'Enable wpautop?', 'pods' ), + 'label' => __( 'Enable wpautop', 'pods' ), 'default' => 1, 'type' => 'boolean', 'help' => array( __( 'Changes double line-breaks in the text into HTML paragraphs', 'pods' ), - 'http://codex.wordpress.org/Function_Reference/wpautop', + 'https://developer.wordpress.org/reference/functions/wpautop/', ), ), static::$type . '_allow_shortcode' => array( - 'label' => __( 'Allow Shortcodes?', 'pods' ), + 'label' => __( 'Allow Shortcodes', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, 'help' => array( __( 'Embed [shortcodes] that help transform your static content into dynamic content.', 'pods' ), - 'http://codex.wordpress.org/Shortcode_API', + 'https://codex.wordpress.org/Shortcode_API', ), ), ), @@ -139,8 +150,8 @@ public function options() { ); if ( function_exists( 'Markdown' ) ) { - $options['output_options']['group'][ static::$type . '_allow_markdown' ] = array( - 'label' => __( 'Allow Markdown Syntax?', 'pods' ), + $options['output_options']['boolean_group'][ static::$type . '_allow_markdown' ] = array( + 'label' => __( 'Allow Markdown Syntax', 'pods' ), 'default' => 0, 'type' => 'boolean', ); @@ -163,8 +174,9 @@ public function schema( $options = null ) { * {@inheritdoc} */ public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); if ( 1 === (int) pods_v( static::$type . '_oembed', $options, 0 ) ) { $post_temp = false; @@ -223,14 +235,14 @@ public function display( $value = null, $name = null, $options = null, $pod = nu */ public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; $form_field_type = PodsForm::$field_type; if ( is_array( $value ) ) { $value = implode( "\n", $value ); } - if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) { + if ( isset( $options['name'] ) && ! pods_permission( $options ) ) { if ( pods_v( 'read_only', $options, false ) ) { $options['readonly'] = true; @@ -244,8 +256,16 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = $field_type = 'textarea'; } elseif ( 'tinymce' === pods_v( static::$type . '_editor', $options ) ) { $field_type = 'tinymce'; + + // Enforce boolean. + $options[ static::$type . '_media_buttons' ] = filter_var( pods_v( static::$type . '_editor', $options, true ), FILTER_VALIDATE_BOOLEAN ); + + wp_tinymce_inline_scripts(); + wp_enqueue_editor(); + } elseif ( 'quill' === pods_v( static::$type . '_editor', $options ) ) { + $field_type = 'quill'; } elseif ( 'cleditor' === pods_v( static::$type . '_editor', $options ) ) { - $field_type = 'cleditor'; + $field_type = 'quill'; } else { // Support custom WYSIWYG integration $editor_type = pods_v( static::$type . '_editor', $options ); @@ -255,15 +275,27 @@ public function input( $name, $value = null, $options = null, $pod = null, $id = return; }//end if - pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + if ( ! empty( $options['disable_dfv'] ) ) { + return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) ); + } + + wp_enqueue_script( 'pods-dfv' ); + + $type = pods_v( 'type', $options, static::$type ); + + $args = compact( array_keys( get_defined_vars() ) ); + $args = (object) $args; + + $this->render_input_script( $args ); } /** * {@inheritdoc} */ public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); $length = (int) pods_v( static::$type . '_max_length', $options, 0 ); @@ -278,8 +310,9 @@ public function pre_save( $value, $id = null, $name = null, $options = null, $fi * {@inheritdoc} */ public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { - $value = $this->strip_html( $value, $options ); + $value = $this->strip_shortcodes( $value, $options ); + $value = $this->trim_whitespace( $value, $options ); $value = wp_trim_words( $value ); @@ -291,7 +324,7 @@ public function ui( $id, $value, $name = null, $options = null, $fields = null, */ public function strip_html( $value, $options = null ) { - $options = (array) $options; + $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; // Allow HTML tags. $options[ static::$type . '_allow_html' ] = 1; diff --git a/classes/widgets/PodsWidgetField.php b/classes/widgets/PodsWidgetField.php index 20fc0fa9ed..b432b49801 100644 --- a/classes/widgets/PodsWidgetField.php +++ b/classes/widgets/PodsWidgetField.php @@ -8,20 +8,17 @@ class PodsWidgetField extends WP_Widget { /** * {@inheritdoc} */ - public function __construct( $id_base = '', $name = '', $widget_options = array(), $control_options = array() ) { - - parent::__construct( 'pods_widget_field', __( 'Pods - Field Value', 'pods' ), array( + public function __construct( $id_base = '', $name = '', $widget_options = [], $control_options = [] ) { + parent::__construct( 'pods_widget_field', __( 'Pods - Field Value', 'pods' ), [ 'classname' => 'pods_widget_field', 'description' => __( "Display a single Pod item's field value", 'pods' ), - ), array( 'width' => 200 ) ); - + ], [ 'width' => 200 ] ); } /** * {@inheritdoc} */ public function widget( $args, $instance ) { - // Setup basic widget parameters. $before_widget = pods_v( 'before_widget', $args ); $after_widget = pods_v( 'after_widget', $args ); @@ -31,11 +28,11 @@ public function widget( $args, $instance ) { $before_content = pods_v( 'before_content', $instance ); $after_content = pods_v( 'after_content', $instance ); - $args = array( + $args = [ 'name' => trim( pods_v( 'pod_type', $instance, '' ) ), 'slug' => trim( pods_v( 'slug', $instance, '' ) ), 'field' => trim( pods_v( 'field', $instance, '' ) ), - ); + ]; if ( 0 < strlen( $args['name'] ) && 0 < strlen( $args['slug'] ) && 0 < strlen( $args['field'] ) ) { require PODS_DIR . 'ui/front/widgets.php'; @@ -46,7 +43,6 @@ public function widget( $args, $instance ) { * {@inheritdoc} */ public function update( $new_instance, $old_instance ) { - $instance = $old_instance; $instance['title'] = pods_v( 'title', $new_instance, '' ); @@ -61,7 +57,6 @@ public function update( $new_instance, $old_instance ) { * {@inheritdoc} */ public function form( $instance ) { - $title = pods_v( 'title', $instance, '' ); $pod_type = pods_v( 'pod_type', $instance, '' ); $slug = pods_v( 'slug', $instance, '' ); diff --git a/codeception.dist.yml b/codeception.dist.yml new file mode 100644 index 0000000000..3bd673a970 --- /dev/null +++ b/codeception.dist.yml @@ -0,0 +1,14 @@ +actor: Tester +paths: + tests: tests/codeception + log: tests/codeception/_output + data: tests/codeception/_data + helpers: tests/codeception/_support + wp_root: "%WP_ROOT_FOLDER%" +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +params: + # read dynamic configuration parameters from the .env file + - .env diff --git a/codeception.example.yml b/codeception.example.yml new file mode 100644 index 0000000000..571eaabb67 --- /dev/null +++ b/codeception.example.yml @@ -0,0 +1,3 @@ +params: + # read dynamic configuration parameters from the .env file + - .env.local diff --git a/codeception.tric.yml b/codeception.tric.yml new file mode 100644 index 0000000000..d0109a4cc7 --- /dev/null +++ b/codeception.tric.yml @@ -0,0 +1,3 @@ +params: + # read dynamic configuration parameters from the .env file + - .env.testing.tric \ No newline at end of file diff --git a/components/Helpers.php b/components/Helpers.php deleted file mode 100644 index 5d79d533dc..0000000000 --- a/components/Helpers.php +++ /dev/null @@ -1,521 +0,0 @@ - 'Pod Helpers', - 'labels' => array( 'singular_name' => 'Pod Helper' ), - 'public' => false, - 'can_export' => false, - 'show_ui' => true, - 'show_in_menu' => false, - 'query_var' => false, - 'rewrite' => false, - 'has_archive' => false, - 'hierarchical' => false, - 'supports' => array( 'title', 'author', 'revisions' ), - 'menu_icon' => 'dashicons-pods', - ); - - if ( ! pods_is_admin() ) { - $args['capability_type'] = 'pods_helper'; - } - - $args = PodsInit::object_label_fix( $args, 'post_type' ); - - register_post_type( $this->object_type, apply_filters( 'pods_internal_register_post_type_object_helper', $args ) ); - - if ( is_admin() ) { - add_filter( 'post_updated_messages', array( $this, 'setup_updated_messages' ), 10, 1 ); - - add_action( 'add_meta_boxes_' . $this->object_type, array( $this, 'edit_page_form' ) ); - - add_action( 'pods_meta_groups', array( $this, 'add_meta_boxes' ) ); - add_filter( 'get_post_metadata', array( $this, 'get_meta' ), 10, 4 ); - add_filter( 'update_post_metadata', array( $this, 'save_meta' ), 10, 4 ); - - add_action( 'pods_meta_save_pre_post__pods_helper', array( $this, 'fix_filters' ), 10, 5 ); - add_action( 'post_updated', array( $this, 'clear_cache' ), 10, 3 ); - add_action( 'delete_post', array( $this, 'clear_cache' ), 10, 1 ); - add_filter( 'post_row_actions', array( $this, 'remove_row_actions' ), 10, 2 ); - add_filter( 'bulk_actions-edit-' . $this->object_type, array( $this, 'remove_bulk_actions' ) ); - - add_filter( 'builder_layout_filter_non_layout_post_types', array( $this, 'disable_builder_layout' ) ); - } - - } - - public function disable_builder_layout( $post_types ) { - - $post_types[] = $this->object_type; - - return $post_types; - } - - /** - * Update Post Type messages - * - * @param array $messages - * - * @return array - * @since 2.0.2 - */ - public function setup_updated_messages( $messages ) { - - global $post, $post_ID; - - $post_type = get_post_type_object( $this->object_type ); - - $labels = $post_type->labels; - - $messages[ $post_type->name ] = array( - 1 => sprintf( __( '%1$s updated. %3$s', 'pods' ), $labels->singular_name, esc_url( get_permalink( $post_ID ) ), $labels->view_item ), - 2 => __( 'Custom field updated.', 'pods' ), - 3 => __( 'Custom field deleted.', 'pods' ), - 4 => sprintf( __( '%s updated.', 'pods' ), $labels->singular_name ), - /* translators: %s: date and time of the revision */ - 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'pods' ), $labels->singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - 6 => sprintf( __( '%1$s published. %3$s', 'pods' ), $labels->singular_name, esc_url( get_permalink( $post_ID ) ), $labels->view_item ), - 7 => sprintf( __( '%s saved.', 'pods' ), $labels->singular_name ), - 8 => sprintf( __( '%1$s submitted. Preview %3$s', 'pods' ), $labels->singular_name, esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ), $labels->singular_name ), - 9 => sprintf( - __( '%1$s scheduled for: %2$s. Preview %4$s', 'pods' ), $labels->singular_name, - // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ), $labels->singular_name - ), - 10 => sprintf( __( '%1$s draft updated. Preview %3$s', 'pods' ), $labels->singular_name, esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ), $labels->singular_name ), - ); - - if ( false === (boolean) $post_type->public ) { - $messages[ $post_type->name ][1] = sprintf( __( '%s updated.', 'pods' ), $labels->singular_name ); - $messages[ $post_type->name ][6] = sprintf( __( '%s published.', 'pods' ), $labels->singular_name ); - $messages[ $post_type->name ][8] = sprintf( __( '%s submitted.', 'pods' ), $labels->singular_name ); - $messages[ $post_type->name ][9] = sprintf( - __( '%1$s scheduled for: %2$s.', 'pods' ), $labels->singular_name, - // translators: Publish box date format, see http://php.net/date - date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) - ); - $messages[ $post_type->name ][10] = sprintf( __( '%s draft updated.', 'pods' ), $labels->singular_name ); - } - - return $messages; - } - - /** - * Enqueue styles - * - * @since 2.0.0 - */ - public function admin_assets() { - - wp_enqueue_style( 'pods-styles' ); - } - - /** - * Fix filters, specifically removing balanceTags - * - * @since 2.0.1 - */ - public function fix_filters( $data, $pod = null, $id = null, $groups = null, $post = null ) { - - remove_filter( 'content_save_pre', 'balanceTags', 50 ); - } - - /** - * Remove unused row actions - * - * @since 2.0.5 - */ - public function remove_row_actions( $actions, $post ) { - - global $current_screen; - - if ( ! is_object( $current_screen ) || $this->object_type != $current_screen->post_type ) { - return $actions; - } - - if ( isset( $actions['view'] ) ) { - unset( $actions['view'] ); - } - - if ( isset( $actions['inline hide-if-no-js'] ) ) { - unset( $actions['inline hide-if-no-js'] ); - } - - // W3 Total Cache - if ( isset( $actions['pgcache_purge'] ) ) { - unset( $actions['pgcache_purge'] ); - } - - return $actions; - } - - /** - * Remove unused bulk actions - * - * @since 2.0.5 - */ - public function remove_bulk_actions( $actions ) { - - if ( isset( $actions['edit'] ) ) { - unset( $actions['edit'] ); - } - - return $actions; - } - - /** - * Clear cache on save - * - * @since 2.0.0 - */ - public function clear_cache( $data, $pod = null, $id = null, $groups = null, $post = null ) { - - $old_post = $id; - - if ( ! is_object( $id ) ) { - $old_post = null; - } - - if ( is_object( $post ) && $this->object_type != $post->post_type ) { - return; - } - - if ( ! is_array( $data ) && 0 < $data ) { - $post = $data; - $post = get_post( $post ); - } - - if ( $this->object_type == $post->object_type ) { - pods_transient_clear( 'pods_object_helpers' ); - } - } - - /** - * Change post title placeholder text - * - * @since 2.0.0 - */ - public function set_title_text( $text, $post ) { - - return __( 'Enter helper name here', 'pods' ); - } - - /** - * Edit page form - * - * @since 2.0.0 - */ - public function edit_page_form() { - - global $post_type; - - if ( $this->object_type != $post_type ) { - return; - } - - add_filter( 'enter_title_here', array( $this, 'set_title_text' ), 10, 2 ); - } - - /** - * Add meta boxes to the page - * - * @since 2.0.0 - */ - public function add_meta_boxes() { - - $pod = array( - 'name' => $this->object_type, - 'type' => 'post_type', - ); - - if ( isset( PodsMeta::$post_types[ $pod['name'] ] ) ) { - return; - } - - $fields = array( - array( - 'name' => 'helper_type', - 'label' => __( 'Helper Type', 'pods' ), - 'type' => 'pick', - 'default' => 'display', - 'data' => array( - 'input' => 'Input (change form fields)', - 'display' => 'Display (change field output when using magic tags)', - 'pre_save' => 'Pre-Save (change form fields before saving)', - 'post_save' => 'Post-Save', - 'pre_delete' => 'Pre-Delete', - 'post_delete' => 'Post-Delete', - ), - ), - array( - 'name' => 'code', - 'label' => __( 'Code', 'pods' ), - 'type' => 'code', - ), - ); - - pods_group_add( $pod, __( 'Helper', 'pods' ), $fields, 'normal', 'high' ); - } - - /** - * Get the fields - * - * @param null $_null - * @param null $post_ID - * @param null $meta_key - * @param bool $single - * - * @return array|bool|int|mixed|null|string|void - */ - public function get_meta( $_null, $post_ID = null, $meta_key = null, $single = false ) { - - if ( 'code' == $meta_key ) { - $post = get_post( $post_ID ); - - if ( is_object( $post ) && $this->object_type == $post->post_type ) { - return $post->post_content; - } - } - - return $_null; - } - - /** - * Save the fields - * - * @param $_null - * @param int $post_ID - * @param string $meta_key - * @param string $meta_value - * - * @return bool|int|null - */ - public function save_meta( $_null, $post_ID = null, $meta_key = null, $meta_value = null ) { - - if ( 'code' == $meta_key ) { - $post = get_post( $post_ID ); - - if ( is_object( $post ) && $this->object_type == $post->post_type ) { - $postdata = array( - 'ID' => $post_ID, - 'post_content' => $meta_value, - ); - - remove_filter( current_filter(), array( $this, __FUNCTION__ ) ); - - $revisions = false; - - if ( has_action( 'pre_post_update', 'wp_save_post_revision' ) ) { - remove_action( 'pre_post_update', 'wp_save_post_revision' ); - - $revisions = true; - } - - wp_update_post( (object) $postdata ); - // objects will be automatically sanitized - if ( $revisions ) { - add_action( 'pre_post_update', 'wp_save_post_revision' ); - } - - return true; - }//end if - }//end if - - return $_null; - } - - /** - * @static - * - * Run a helper within a Pod Page or WP Template - * - * $params['helper'] string Helper name - * $params['value'] string Value to run Helper on - * $params['name'] string Field name - * - * @param array $params An associative array of parameters - * @param null $obj - * - * @return mixed Anything returned by the helper - * @since 2.0.0 - */ - public static function helper( $params, $obj = null ) { - - /** - * @var $obj Pods - */ - if ( ! empty( $obj ) ) { - self::$obj =& $obj; - } else { - $obj =& self::$obj; - } - - if ( empty( $obj ) || ! is_object( $obj ) ) { - return ''; - } - - $defaults = array( - 'helper' => '', - 'value' => '', - 'name' => '', - 'deprecated' => false, - ); - - if ( is_array( $params ) ) { - $params = array_merge( $defaults, $params ); - } else { - $params = $defaults; - } - - $params = (object) $params; - - if ( empty( $params->helper ) ) { - return pods_error( __( 'Helper name required', 'pods' ), $obj ); - } elseif ( ! is_array( $params->helper ) ) { - $params->helper = trim( $params->helper ); - } - - if ( ! isset( $params->value ) ) { - $params->value = null; - } - - if ( true === $params->deprecated && is_array( $params->value ) && ! empty( $params->value ) && ! isset( $params->value[0] ) ) { - $params->value = array( $params->value ); - } - - if ( ! isset( $params->name ) ) { - $params->name = null; - } - - $helper = $obj->api->load_helper( array( 'name' => $params->helper ) ); - - ob_start(); - - if ( ! empty( $helper ) && ! empty( $helper['code'] ) ) { - $code = $helper['code']; - - $code = str_replace( '$this->', '$obj->', $code ); - - $value =& $params->value; - $name =& $params->name; - - $_safe_params = $params; - - if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) { - eval( "?>{$code}" ); - } else { - echo $code; - } - - $params = $_safe_params; - } elseif ( is_callable( (string) $params->helper ) ) { - $params->helper = (string) $params->helper; - - $disallowed = array( - 'system', - 'exec', - 'popen', - 'eval', - 'preg_replace', - 'create_function', - 'include', - 'include_once', - 'require', - 'require_once', - ); - - $allowed = array(); - - /** - * Allows adjusting the disallowed callbacks as needed. - * - * @param array $disallowed List of callbacks not allowed. - * @param array $params Parameters used by Pods::helper() method. - * - * @since 2.7.0 - */ - $disallowed = apply_filters( 'pods_helper_disallowed_callbacks', $disallowed, get_object_vars( $params ) ); - - /** - * Allows adjusting the allowed allowed callbacks as needed. - * - * @param array $allowed List of callbacks explicitly allowed. - * @param array $params Parameters used by Pods::helper() method. - * - * @since 2.7.0 - */ - $allowed = apply_filters( 'pods_helper_allowed_callbacks', $allowed, get_object_vars( $params ) ); - - // Clean up helper callback (if string) - $params->helper = strip_tags( str_replace( array( '`', chr( 96 ) ), "'", $params->helper ) ); - - $is_allowed = false; - - if ( ! empty( $allowed ) ) { - if ( in_array( $params->helper, $allowed, true ) ) { - $is_allowed = true; - } - } elseif ( ! in_array( $params->helper, $disallowed, true ) ) { - $is_allowed = true; - } - - if ( $is_allowed ) { - echo call_user_func( $params->helper, $params->value, $params->name, $params, $obj ); - } - }//end if - - $slug = $helper['slug']; - - $out = ob_get_clean(); - - $out = apply_filters( 'pods_helpers_post_helper', $out, $params, $helper ); - $out = apply_filters( "pods_helpers_post_helper_{$slug}", $out, $params, $helper ); - - return $out; - } -} diff --git a/components/I18n/I18n-polylang.php b/components/I18n/I18n-polylang.php deleted file mode 100644 index 433481328b..0000000000 --- a/components/I18n/I18n-polylang.php +++ /dev/null @@ -1,70 +0,0 @@ -languages = pll_languages_list( array( 'fields' => 'locale' ) ); - - add_filter( 'pods_component_i18n_admin_data', array( $this, 'pods_component_i18n_admin_data' ) ); - add_filter( - 'pods_component_i18n_admin_ui_fields', array( - $this, - 'pods_component_i18n_admin_ui_fields', - ), 10, 2 - ); - } - - } - - /** - * @param $data - * - * @return mixed - */ - public function pods_component_i18n_admin_data( $data ) { - - foreach ( $data as $lang => $field_data ) { - if ( in_array( $lang, $this->languages, true ) ) { - $data[ $lang ]['polylang'] = true; - } else { - $data[ $lang ]['polylang'] = false; - } - } - - return $data; - } - - /** - * @param $fields - * @param $data - * - * @return mixed - */ - public function pods_component_i18n_admin_ui_fields( $fields, $data ) { - - $fields['manage']['polylang'] = array( - 'label' => __( 'Polylang', 'pods' ), - 'type' => 'boolean', - /* - 'options' => array( - 'text_allow_html' => 1, - 'text_allowed_html_tags' => 'br a', - )*/ - ); - - return $fields; - } - -} - -new Pods_I18n_Polylang(); diff --git a/components/I18n/I18n-wpml.php b/components/I18n/I18n-wpml.php deleted file mode 100644 index 098d1fbc89..0000000000 --- a/components/I18n/I18n-wpml.php +++ /dev/null @@ -1,76 +0,0 @@ - $lang_data ) { - if ( isset( $lang_data['default_locale'] ) ) { - $locale = $lang_data['default_locale']; - $this->languages[] = $locale; - } - } - - add_filter( 'pods_component_i18n_admin_data', array( $this, 'pods_component_i18n_admin_data' ) ); - add_filter( - 'pods_component_i18n_admin_ui_fields', array( - $this, - 'pods_component_i18n_admin_ui_fields', - ), 10, 2 - ); - } - - } - - /** - * @param $data - * - * @return mixed - */ - public function pods_component_i18n_admin_data( $data ) { - - foreach ( $data as $lang => $field_data ) { - if ( in_array( $lang, $this->languages, true ) ) { - $data[ $lang ]['wpml'] = true; - } else { - $data[ $lang ]['wpml'] = false; - } - } - - return $data; - } - - /** - * @param $fields - * @param $data - * - * @return mixed - */ - public function pods_component_i18n_admin_ui_fields( $fields, $data ) { - - $fields['manage']['wpml'] = array( - 'label' => __( 'WPML', 'pods' ), - 'type' => 'boolean', - /* - 'options' => array( - 'text_allow_html' => 1, - 'text_allowed_html_tags' => 'br a', - )*/ - ); - - return $fields; - } - -} - -new Pods_I18n_WPML(); diff --git a/components/I18n/I18n.php b/components/I18n/I18n.php index ea1b1fe604..5c3bc4f6d8 100644 --- a/components/I18n/I18n.php +++ b/components/I18n/I18n.php @@ -6,7 +6,7 @@ * * Description: Allow UI of Pods and fields to be translated. * - * Version: 0.2 + * Version: 1.0 * * Category: I18n * @@ -57,15 +57,6 @@ public function init() { $this->settings = get_option( $this->option_key, array() ); - // Polylang - if ( function_exists( 'PLL' ) && file_exists( plugin_dir_path( __FILE__ ) . 'I18n-polylang.php' ) ) { - include_once plugin_dir_path( __FILE__ ) . 'I18n-polylang.php'; - } - // WPML - elseif ( did_action( 'wpml_loaded' ) && file_exists( plugin_dir_path( __FILE__ ) . 'I18n-wpml.php' ) ) { - include_once plugin_dir_path( __FILE__ ) . 'I18n-wpml.php'; - } - $active = false; // Are there active languages? if ( ! empty( $this->settings['enabled_languages'] ) ) { @@ -82,7 +73,6 @@ public function init() { } $is_component_page = false; - $is_pods_edit_page = false; if ( is_admin() && isset( $_GET['page'] ) ) { @@ -91,12 +81,6 @@ public function init() { // Is the current page the admin page of this component or a Pods edit page? if ( $this->admin_page === $page ) { $is_component_page = true; - } elseif ( 'pods' === $page ) { - $is_pods_edit_page = true; - } - - if ( $is_component_page || ( $is_pods_edit_page && $active ) ) { - add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) ); } } @@ -105,65 +89,63 @@ public function init() { if ( pods_is_admin( $this->capability ) && isset( $_POST['_nonce_i18n'] ) && wp_verify_nonce( $_POST['_nonce_i18n'], $this->nonce ) ) { $this->admin_save(); } + + add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) ); } if ( $active ) { + + /** + * REGISTERING OBJ LABELS. + */ + // WP Object filters (post_type and taxonomy) - add_filter( 'pods_register_post_type', array( $this, 'pods_register_wp_object_i18n' ), 10, 2 ); - add_filter( 'pods_register_taxonomy', array( $this, 'pods_register_wp_object_i18n' ), 10, 2 ); + add_filter( 'pods_register_post_type', array( $this, 'translate_register_wp_object' ), 10, 2 ); + add_filter( 'pods_register_taxonomy', array( $this, 'translate_register_wp_object' ), 10, 2 ); // ACT's add_filter( 'pods_advanced_content_type_pod_data', - array( $this, 'pods_filter_object_strings_i18n' ), + array( $this, 'translate_object_options' ), 10, 2 ); - // Setting pages - add_filter( 'pods_admin_menu_page_title', array( $this, 'admin_menu_page_title_i18n' ), 10, 2 ); - add_filter( 'pods_admin_menu_label', array( $this, 'admin_menu_label_i18n' ), 10, 2 ); + /** + * LABEL REPLACEMENT. + */ + + // Setting pages. + add_filter( 'pods_admin_menu_page_title', array( $this, 'translate_admin_menu_page_title' ), 10, 2 ); + add_filter( 'pods_admin_menu_label', array( $this, 'translate_admin_menu_label' ), 10, 2 ); - // Default filters for all fields - add_filter( 'pods_form_ui_label_text', array( $this, 'fields_ui_label_text_i18n' ), 10, 4 ); - add_filter( 'pods_form_ui_comment_text', array( $this, 'fields_ui_comment_text_i18n' ), 10, 3 ); + // Pod Objects. + add_filter( 'pods_whatsit_get_label', array( $this, 'translate_label' ), 10, 2 ); + add_filter( 'pods_whatsit_get_description', array( $this, 'translate_description' ), 10, 2 ); foreach ( pods_form()->field_types() as $type => $data ) { add_filter( 'pods_form_ui_field_' . $type . '_options', - array( $this, 'form_ui_field_options_i18n' ), + array( $this, 'translate_field_options' ), 10, 5 ); } - // Field specific - // add_filter( 'pods_field_pick_data', array( $this, 'field_pick_data_i18n' ), 10, 6 ); - if ( $is_pods_edit_page ) { - - $pod = null; - // Get the pod if available - if ( isset( $_GET['id'] ) && is_numeric( $_GET['id'] ) ) { - $pod = pods_api()->load_pod( array( 'id' => $_GET['id'] ) ); - // Append options to root array for pods_v function to work - foreach ( $pod['options'] as $_option => $_value ) { - $pod[ $_option ] = $_value; - } - } - $this->cur_pod = $pod; - - // Add option tab for post types - // add_filter( 'pods_admin_setup_edit_tabs_post_type', array( $this, 'pod_tab' ), 11, 3 ); - // Add the same tab for taxonomies - // add_filter( 'pods_admin_setup_edit_tabs_taxonomy', array( $this, 'pod_tab' ), 11, 3 ); - // Add options to the new tab - // add_filter( 'pods_admin_setup_edit_options', array( $this, 'pod_options' ), 12, 2 ); - // Add options metabox to the pod edit screens - add_action( 'pods_add_meta_boxes', array( $this, 'admin_meta_box' ) ); - - // Add the i18n input fields based on existing fields - add_filter( 'pods_form_ui_field_text', array( $this, 'add_i18n_inputs' ), 10, 6 ); - }//end if + /** + * PODS ADMIN UI. + */ + + // Pod. + add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'pod_tab' ), 99, 2 ); + add_filter( 'pods_admin_setup_edit_options', array( $this, 'pod_options' ), 99, 2 ); + // Pod Fields. + add_filter( 'pods_admin_setup_edit_group_tabs', array( $this, 'pod_tab' ), 99, 2 ); + add_filter( 'pods_admin_setup_edit_group_options', array( $this, 'pod_options' ), 99, 2 ); + // Pod Fields. + add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'pod_tab' ), 99, 2 ); + add_filter( 'pods_admin_setup_edit_field_options', array( $this, 'pod_options' ), 99, 2 ); + }//end if } @@ -257,28 +239,27 @@ public function is_translatable_field( $name ) { } /** - * Get a translated option for a field key (if available) + * Get a translated option for a field key if available. * * @since 0.1.0 * * @param string $current Current value * @param string $key The key / opion name to search for - * @param array $data Pod data (can also be an options array of a pod or field) + * @param array|Pods\Whatsit $data Pod data (can also be an options array of a pod or field) * * @return string */ public function get_value_translation( $current, $key, $data ) { $locale = $this->locale; - // Validate locale and pod - if ( is_array( $data ) && array_key_exists( $locale, $this->languages ) && $this->obj_is_language_enabled( $locale, $data ) ) { - // Add option keys to $data array - if ( ! empty( $data['options'] ) ) { - $data = array_merge( $data, $data['options'] ); - } - // Check if the i18n option exists and isn't empty - if ( ! empty( $data[ $key . '_' . $locale ] ) ) { - return (string) $data[ $key . '_' . $locale ]; + if ( ! array_key_exists( $locale, $this->languages ) ) { + return $current; + } + + if ( $this->obj_is_language_enabled( $locale, $data ) ) { + $translation = pods_v( $key . '_' . $locale, $data, null ); + if ( $translation ) { + return $translation; } } @@ -286,78 +267,75 @@ public function get_value_translation( $current, $key, $data ) { } /** - * Page title for setting pages + * Page title for setting pages. * - * @since 0.1.0 - * @see PodsAdmin.php >> admin_menu() - * @see PodsAdmin.php >> admin_content_settings() + * @since 1.0.0 + * @see PodsAdmin.php >> admin_menu() + * @see PodsAdmin.php >> admin_content_settings() * * @param string $page_title Current page title * @param array $pod Pod data * * @return string */ - public function admin_menu_page_title_i18n( $page_title, $pod ) { + public function translate_admin_menu_page_title( $page_title, $pod ) { return (string) $this->get_value_translation( $page_title, 'label', $pod ); } /** - * Menu title for setting pages + * Menu title for setting pages. * - * @since 0.1.0 - * @see PodsAdmin.php >> admin_menu() + * @since 1.0.0 + * @see PodsAdmin.php >> admin_menu() * * @param string $menu_label Current menu label * @param array $pod Pod data * * @return string */ - public function admin_menu_label_i18n( $menu_label, $pod ) { + public function translate_admin_menu_label( $menu_label, $pod ) { return (string) $this->get_value_translation( $menu_label, 'menu_name', $pod ); } /** - * Returns the translated label if available + * Returns the translated label if available. * - * @since 0.1.0 - * @see PodsForm.php >> 'pods_form_ui_label_text' (filter) + * @since 1.0.0 + * @see \Pods\Whatsit >> 'pods_whatsit_get_label' (filter) * - * @param string $label The default label - * @param string $name The field name - * @param string $help The help text - * @param array $options The field options + * @param string $label The default label. + * @param Pods\Whatsit $object The Pod Object. * * @return string */ - public function fields_ui_label_text_i18n( $label, $name, $help, $options ) { + public function translate_label( $label, $object ) { - return (string) $this->get_value_translation( $label, 'label', $options ); + return (string) $this->get_value_translation( $label, 'label', $object ); } /** - * Returns the translated description if available + * Returns the translated description if available. * - * @since 0.1.0 - * @see PodsForm.php >> 'pods_form_ui_comment_text' (filter) + * @since 1.0.0 + * @see \Pods\Whatsit >> 'pods_whatsit_get_description' (filter) * - * @param string $message The default description - * @param string $name The field name - * @param array $options The field options + * @param string $description The default description. + * @param Pods\Whatsit $object The Pod Object. * * @return string */ - public function fields_ui_comment_text_i18n( $message, $name, $options ) { + public function translate_description( $description, $object ) { - return (string) $this->get_value_translation( $message, 'description', $options ); + return (string) $this->get_value_translation( $description, 'description', $object ); } /** - * Replaces the default selected text with a translation if available + * Replaces the default selected text with a translation if available. * - * @since 0.1.0 - * @see pick.php >> 'pods_field_pick_data' (filter) + * @since 1.0.0 + * @see pick.php >> 'pods_field_pick_data' (filter) * * @param array $data The default data of the field * @param string $name The field name @@ -368,7 +346,7 @@ public function fields_ui_comment_text_i18n( $message, $name, $options ) { * * @return array */ - public function field_pick_data_i18n( $data, $name, $value, $options, $pod, $id ) { + public function translate_field_pick_data( $data, $name, $value, $options, $pod, $id ) { if ( isset( $data[''] ) && isset( $options['pick_select_text'] ) ) { $locale = $this->locale; @@ -381,10 +359,10 @@ public function field_pick_data_i18n( $data, $name, $value, $options, $pod, $id } /** - * Replaces the default values with a translation if available + * Replaces the default values with a translation if available. * - * @since 0.1.0 - * @see PodsForm.php >> 'pods_form_ui_field_' . $type . '_options' (filter) + * @since 1.0.0 + * @see PodsForm.php >> 'pods_form_ui_field_' . $type . '_options' (filter) * * @param array $options The field options * @param string $name The field name @@ -394,12 +372,16 @@ public function field_pick_data_i18n( $data, $name, $value, $options, $pod, $id * * @return array */ - public function form_ui_field_options_i18n( $options, $name, $value, $pod, $id ) { + public function translate_field_options( $options, $name, $value, $pod, $id ) { + $locale = $this->locale; + if ( ! array_key_exists( $locale, $this->languages ) || ! $this->obj_is_language_enabled( $locale, $pod ) ) { + return $options; + } foreach ( $this->get_translatable_fields() as $field ) { - $locale = $this->locale; - if ( isset( $options[ $field . '_' . $locale ] ) && array_key_exists( $locale, $this->languages ) && $this->obj_is_language_enabled( $locale, $pod ) ) { - $options[ $field ] = $options[ $field . '_' . $locale ]; + $translation = pods_v( $field . '_' . $locale, $options, null ); + if ( $translation ) { + $options[ $field ] = $translation; } } @@ -409,15 +391,15 @@ public function form_ui_field_options_i18n( $options, $name, $value, $pod, $id ) /** * Filter hook function to overwrite the labels and description with translations (if available) * - * @since 0.1.0 - * @see PodsInit.php >> setup_content_types() + * @since 1.0.0 + * @see PodsInit.php >> setup_content_types() * * @param array $options The array of object options * @param string $object The object type name/slug * * @return array */ - public function pods_register_wp_object_i18n( $options, $object ) { + public function translate_register_wp_object( $options, $object ) { $locale = $this->locale; @@ -509,15 +491,15 @@ public function pods_register_wp_object_i18n( $options, $object ) { /** * Filter hook function to overwrite the labels and description with translations (if available) * - * @since 0.1.0 - * @see PodsInit.php >> admin_menu() + * @since 1.0.0 + * @see PodsInit.php >> admin_menu() * * @param array $options The array of object options * @param string $object The object type name/slug * * @return array */ - public function pods_filter_object_strings_i18n( $options, $object ) { + public function translate_object_options( $options, $object ) { /** * @todo allow labels to be set even if the default language isn't @@ -724,19 +706,15 @@ public function admin( $options, $component ) { /** * The i18n option tab. * - * @todo Remove if not used in final version - * - * @since 0.1.0 + * @since 1.0.0 * * @param array $tabs - * @param array $pod - * @param array $args * * @return array */ - public function pod_tab( $tabs, $pod, $args ) { + public function pod_tab( $tabs ) { - $tabs['pods-i18n'] = __( 'Translation Options', 'pods' ); + $tabs['i18n'] = __( 'Translations', 'pods' ); return $tabs; } @@ -744,16 +722,56 @@ public function pod_tab( $tabs, $pod, $args ) { /** * The i18n options * - * @todo Remove if not used in final version - * - * @since 0.1.0 + * @since 1.0.0 * * @param array $options - * @param array $pod * * @return array */ public function pod_options( $options, $pod ) { + $i18n_fields = []; + + foreach ( $options as $tab => $fields ) { + foreach ( $fields as $name => $field ) { + if ( ! $this->is_translatable_field( $name ) ) { + continue; + } + + // None of the i18n fields are required! + $field['required'] = false; + + $heading_field = $field; + $heading_field['type'] = 'heading'; + $heading_field['name'] = $name . '_i18n'; + + $i18n_fields[][ $name . '_i18n' ] = $heading_field; + + $default_field = $field; + $default_field['type'] = 'html'; + $default_field['name'] = $name . '_i18n_default'; + $default_field['label'] = __( 'Default', 'pods' ); + $default_field['html_content'] = '%s'; + $default_field['html_content_param'] = $name; + $default_field['html_content_param_default'] = '-'; + + $i18n_fields[][ $name . '_i18n_default' ] = $default_field; + + foreach ( $this->languages as $locale => $lang_data ) { + if ( ! $this->obj_is_language_enabled( $locale, (array) $pod ) ) { + continue; + } + + $locale_name = $name . '_' . $locale; + $locale_field = $field; + $locale_field['name'] = $locale_name; + $locale_field['label'] = $locale; + + $i18n_fields[][ $locale_name ] = $locale_field; + } + } + } + + $options['i18n'] = $i18n_fields; // if ( $pod['type'] === '' ) /* @@ -774,155 +792,6 @@ public function pod_options( $options, $pod ) { }*/ return $options; - - } - - /** - * Add the i18n metabox. - * - * @since 0.1.0 - */ - public function admin_meta_box() { - - add_meta_box( - 'pods_i18n', - // ID - __( 'Translation options', 'pods' ), - // Label - array( $this, 'meta_box' ), - // Callback - '_pods_pod', - // Screen - 'side', - // Context (side) - 'default' - // Priority - ); - } - - /** - * The i18n metabox. - * - * @todo Store enabled languages serialized instead of separate inputs - * - * @since 0.1.0 - */ - public function meta_box() { - - $pod = $this->cur_pod; - - if ( ! empty( $this->languages ) ) { - ?> -

-

- -

-
- languages as $locale => $lang_data ) { - - if ( ! isset( $pod['options']['enable_i18n'][ $locale ] ) ) { - // Enabled by default - $pod['options']['enable_i18n'][ $locale ] = 1; - } - ?> -
- '' . $locale . ' ' . $this->create_lang_label( $lang_data ), - 'boolean_no_label' => '', - ) - ); - ?> -
- -
-
-

- -

- > 'pods_form_ui_field_' . $type (filter) - * - * @param string $output The default output of the field - * @param string $name The field name - * @param string $value The field value - * @param array $options The field options - * @param array $pod The Pod - * @param int $id The field ID - * - * @return string - */ - public function add_i18n_inputs( $output, $name, $value, $options, $pod, $id ) { - - if ( ! empty( $pod ) || empty( $name ) || ! $this->is_translatable_field( $name ) ) { - return $output; - } - - $pod = $this->cur_pod; - // print_r( $pod ); - if ( empty( $pod ) ) { - // Setting the $pod var to a non-empty value is mandatory to prevent a loop - $pod = true; - } - - $output .= '
'; - $output .= '
'; - foreach ( $this->languages as $locale => $lang_data ) { - - if ( ! $this->obj_is_language_enabled( $locale, (array) $pod ) ) { - continue; - } - // Our own shiny label with language information - $lang_code = '' . $locale . ''; - /* - $lang_label = $this->create_lang_label( $lang_data ); - if ( ! empty( $lang_label ) ) { - $lang_label = $lang_code . ' ('. $lang_label .')'; - } else {*/ - $lang_label = $lang_code; - // } - $lang_label = '' . $lang_label . ''; - - $style = ''; - - // Add language data to name for normal strings and array formatted strings - if ( strpos( $name, ']' ) !== false ) { - // Hide the i18n options for fields by default if they are empty - $field_value = pods_v( $name, $pod ); - - if ( strpos( $name, 'field_data' ) !== false && empty( $field_value ) ) { - $style = ' style="display: none;"'; - } - - $field_name = rtrim( $name, ']' ); - $field_name .= '_' . $locale . ']'; - } else { - $field_name = $name . '_' . $locale; - } - - // Add the translation fields - $output .= '
'; - $output .= PodsForm::label( $field_name, $lang_label ); - $output .= PodsForm::field( $field_name, pods_v( $field_name, $pod ), 'text', null, $pod ); - $output .= '
'; - }//end foreach - $output .= '
'; - - return $output; } /** @@ -941,14 +810,15 @@ public function obj_is_language_enabled( $locale, $data ) { if ( ! array_key_exists( $locale, $this->languages ) ) { return false; } - $data = (array) $data; - $options = ( isset( $data['options'] ) ) ? $data['options'] : $data; - // If it doesn't exist in the object data then use the default (enabled) - if ( isset( $options['enable_i18n'][ $locale ] ) && false === (bool) $options['enable_i18n'][ $locale ] ) { - return false; + $options = pods_v( 'options', $data, $data ); + + $enable_i18n = pods_v( 'enable_i18n', $options, null ); + if ( null === $enable_i18n ) { + // If there are no i18n settings in the object data then assume it's enabled. + return true; } - return true; + return (bool) pods_v( $locale, $enable_i18n, true ); } /** diff --git a/components/I18n/pods-admin-i18n.js b/components/I18n/pods-admin-i18n.js index 8c17429dca..8cce85c9ab 100644 --- a/components/I18n/pods-admin-i18n.js +++ b/components/I18n/pods-admin-i18n.js @@ -23,138 +23,4 @@ PodsAdminI18n.init(); } - /** - * Pod edit page - */ - PodsEditI18n = { - i18nVisible : true, selector : '.pods-i18n-input', toggleSpeed : 100, - - init : function () { - this.toggleI18nInputs(); - this.dynamicAddRemoveInputs(); - }, - - validateI18nVisibility : function () { - /** - * Check if we're on the fields tab - * If we're on a fields tab, check if the first i18n input is visible and change this object's visibility property - */ - if ( $( '#pods-manage-fields' ).is( ':visible' ) && $( '#pods-manage-fields .pods-manage-list .pods-manage-row-expanded' ).length ) { - var first = $( '#pods-manage-fields .pods-manage-list .pods-manage-row-expanded' ).first().find( PodsEditI18n.selector ).first(); - if ( first.is( ':visible' ) ) { - PodsEditI18n.i18nVisible = true; - } - else { - PodsEditI18n.i18nVisible = false; - } - } - - }, - - toggleI18nInputs : function () { - - // Toggle i18n inputs for pod options - // @todo Enable auto-toggle when opening a field - $( document ).on( 'click', 'button#toggle_i18n', function ( e ) { - e.preventDefault(); - - PodsEditI18n.validateI18nVisibility(); - - if ( PodsEditI18n.i18nVisible ) { - - PodsEditI18n.i18nVisible = false; - $( PodsEditI18n.selector ).each( function () { - $( this ).slideUp( PodsEditI18n.toggleSpeed, function () { - // Fallback for hidden fields - $( this ).css( 'display', 'none' ); - } ); - } ); - - } - else { - - PodsEditI18n.i18nVisible = true; - $( PodsEditI18n.selector ).each( function () { - $( this ).slideDown( PodsEditI18n.toggleSpeed, function () { - // Fallback for hidden fields - $( this ).css( 'display', 'block' ); - } ); - } ); - - } - return false; - } ); - }, - - dynamicAddRemoveInputs : function () { - - $( document ).on( 'change', '#pods_i18n .pods-enable-disable-language input', function ( e ) { - - PodsEditI18n.validateI18nVisibility(); - - var locale = $( this ).parents( '.pods-enable-disable-language' ).attr( 'data-locale' ); - - if ( $( this ).is( ':checked' ) ) { - - // Get the index for this locale - var index = 0; - $( '#pods_i18n .pods-enable-disable-language input:checked' ).each( function () { - if ( $( this ).parents( '.pods-enable-disable-language' ).attr( 'data-locale' ) == locale ) { - return false; - } - index++; - } ); - - $( '.pods-i18n-field' ).each( function () { - if ( $( '.pods-i18n-input-' + locale, this ).length ) { - $( '.pods-i18n-input-' + locale, this ).slideDown( PodsEditI18n.toggleSpeed, function () { - $( 'input', this ).removeAttr( 'disabled' ); - } ); - } - else { - var name = $( this ).parent().children( 'input' ).first().attr( 'name' ); - // Place the new input on the right index - if ( $( '.pods-i18n-input:visible', this ).eq( index ).length ) { - $( '.pods-i18n-input:visible', this ).eq( index ).before( PodsEditI18n.i18nInputTemplate( name, locale ) ); - } - else { - $( this ).append( PodsEditI18n.i18nInputTemplate( name, locale ) ); - } - if ( PodsEditI18n.i18nVisible ) { - $( '.pods-i18n-input-' + locale, this ).slideDown( PodsEditI18n.toggleSpeed ); - } - } - } ); - - } - else { - $( '.pods-i18n-input-' + locale + ' input' ).each( function () { - $( this ).parent().slideUp( PodsEditI18n.toggleSpeed, function () { - $( 'input', this ).attr( 'disabled', 'disabled' ); - } ); - } ); - } - - } ); - - }, - - i18nInputTemplate : function ( name, locale ) { - - var locale_clean = locale.toLowerCase().replace( '_', '-' ); - var name_clean = name.toLowerCase().replace( '_', '-' ); - - html = ''; - return html; - } - - }; - - if ( $( '#post-body' ).length ) { - PodsEditI18n.init(); - } - })( jQuery ); diff --git a/components/Migrate-CPTUI/Migrate-CPTUI.php b/components/Migrate-CPTUI/Migrate-CPTUI.php index 94b596c7ef..60a67b0fa9 100644 --- a/components/Migrate-CPTUI/Migrate-CPTUI.php +++ b/components/Migrate-CPTUI/Migrate-CPTUI.php @@ -125,7 +125,7 @@ public function ajax_migrate( $params ) { } foreach ( $post_types as $k => $post_type ) { - if ( ! in_array( pods_var( 'name', $post_type ), $migrate_post_types, true ) ) { + if ( ! in_array( pods_v( 'name', $post_type ), $migrate_post_types, true ) ) { continue; } @@ -137,7 +137,7 @@ public function ajax_migrate( $params ) { } foreach ( $taxonomies as $k => $taxonomy ) { - if ( ! in_array( pods_var( 'name', $taxonomy ), $migrate_taxonomies, true ) ) { + if ( ! in_array( pods_v( 'name', $taxonomy ), $migrate_taxonomies, true ) ) { continue; } @@ -148,7 +148,7 @@ public function ajax_migrate( $params ) { } } - if ( 1 == pods_var( 'cleanup', $params, 0 ) ) { + if ( 1 === (int) pods_v( 'cleanup', $params, 0 ) ) { if ( ! empty( $post_types ) ) { if ( ! is_null( $this->post_option_name ) ) { update_option( $this->post_option_name, $post_types ); @@ -181,62 +181,122 @@ public function ajax_migrate( $params ) { * @return bool|int|mixed */ private function migrate_post_type( $post_type ) { + $supports = []; + + if ( isset( $post_type['supports'] ) && is_array( $post_type['supports'] ) ) { + // New style. + $supports = $post_type['supports']; + } elseif ( isset( $post_type[0] ) && is_array( $post_type[0] ) ) { + // Old style. + $supports = $post_type[0]; + } + + $taxonomies = []; - $params = array( - 'type' => 'post_type', - 'storage' => 'meta', - 'object' => '', - 'name' => pods_var_raw( 'name', $post_type ), - 'label' => pods_var_raw( 'label', $post_type ), - 'label_singular' => pods_var_raw( 'singular_label', $post_type ), - 'description' => pods_var_raw( 'description', $post_type ), - 'public' => pods_var_raw( 'public', $post_type ), - 'show_ui' => (int) pods_var_raw( 'show_ui', $post_type ), - 'has_archive' => (int) pods_var_raw( 'has_archive', $post_type ), - 'exclude_from_search' => (int) pods_var_raw( 'exclude_from_search', $post_type ), - 'capability_type' => pods_var_raw( 'capability_type', $post_type ), - // --!! Needs sanity checking? - 'hierarchical' => (int) pods_var_raw( 'hierarchical', $post_type ), - 'rewrite' => (int) pods_var_raw( 'rewrite', $post_type ), - 'rewrite_custom_slug' => pods_var_raw( 'rewrite_slug', $post_type ), - 'query_var' => (int) pods_var_raw( 'query_var', $post_type ), - 'menu_position' => (int) pods_var_raw( 'menu_position', $post_type ), - 'show_in_menu' => (int) pods_var_raw( 'show_in_menu', $post_type ), - 'menu_string' => pods_var_raw( 'show_in_menu_string', $post_type ), - - // 'supports' argument to register_post_type() - 'supports_title' => ( is_array( $post_type[0] ) && in_array( 'title', $post_type[0], true ) ), - 'supports_editor' => ( is_array( $post_type[0] ) && in_array( 'editor', $post_type[0], true ) ), - 'supports_excerpt' => ( is_array( $post_type[0] ) && in_array( 'excerpt', $post_type[0], true ) ), - 'supports_trackbacks' => ( is_array( $post_type[0] ) && in_array( 'trackbacks', $post_type[0], true ) ), - 'supports_custom_fields' => ( is_array( $post_type[0] ) && in_array( 'custom-fields', $post_type[0], true ) ), - 'supports_comments' => ( is_array( $post_type[0] ) && in_array( 'comments', $post_type[0], true ) ), - 'supports_revisions' => ( is_array( $post_type[0] ) && in_array( 'revisions', $post_type[0], true ) ), - 'supports_thumbnail' => ( is_array( $post_type[0] ) && in_array( 'thumbnail', $post_type[0], true ) ), - 'supports_author' => ( is_array( $post_type[0] ) && in_array( 'author', $post_type[0], true ) ), - 'supports_page_attributes' => ( is_array( $post_type[0] ) && in_array( 'page-attributes', $post_type[0], true ) ), - - // 'labels' argument to register_post_type() - 'menu_name' => pods_var_raw( 'menu_name', $post_type[2] ), - 'label_add_new' => pods_var_raw( 'add_new', $post_type[2] ), - 'label_add_new_item' => pods_var_raw( 'add_new_item', $post_type[2] ), - 'label_edit' => pods_var_raw( 'edit', $post_type[2] ), - 'label_edit_item' => pods_var_raw( 'edit_item', $post_type[2] ), - 'label_new_item' => pods_var_raw( 'new_item', $post_type[2] ), - 'label_view' => pods_var_raw( 'view', $post_type[2] ), - 'label_view_item' => pods_var_raw( 'view_item', $post_type[2] ), - 'label_search_items' => pods_var_raw( 'search_items', $post_type[2] ), - 'label_not_found' => pods_var_raw( 'not_found', $post_type[2] ), - 'label_not_found_in_trash' => pods_var_raw( 'not_found_in_trash', $post_type[2] ), - 'label_parent' => pods_var_raw( 'parent', $post_type[2] ), - ); + if ( isset( $post_type['taxonomies'] ) && is_array( $post_type['taxonomies'] ) ) { + // New style. + $taxonomies = $post_type['taxonomies']; + } elseif ( isset( $post_type[1] ) && is_array( $post_type[1] ) ) { + // Old style. + $taxonomies = $post_type[1]; + } + + $labels = []; + + if ( isset( $post_type['labels'] ) && is_array( $post_type['labels'] ) ) { + // New style. + $labels = $post_type['labels']; + } elseif ( isset( $post_type[2] ) && is_array( $post_type[2] ) ) { + // Old style. + $labels = $post_type[2]; + } + + $params = [ + 'type' => 'post_type', + 'storage' => 'meta', + 'object' => '', + 'name' => pods_v( 'name', $post_type ), + 'label' => pods_v( 'label', $post_type ), + 'label_singular' => pods_v( 'singular_label', $post_type ), + 'description' => pods_v( 'description', $post_type ), + + // Supports arguments. + 'supports_title' => in_array( 'title', $supports, true ), + 'supports_editor' => in_array( 'editor', $supports, true ), + 'supports_excerpt' => in_array( 'excerpt', $supports, true ), + 'supports_trackbacks' => in_array( 'trackbacks', $supports, true ), + 'supports_custom_fields' => in_array( 'custom-fields', $supports, true ), + 'supports_comments' => in_array( 'comments', $supports, true ), + 'supports_revisions' => in_array( 'revisions', $supports, true ), + 'supports_thumbnail' => in_array( 'thumbnail', $supports, true ), + 'supports_author' => in_array( 'author', $supports, true ), + 'supports_page_attributes' => in_array( 'page-attributes', $supports, true ), + 'supports_post_formats' => in_array( 'post-formats', $supports, true ), + 'supports_custom' => pods_v( 'custom_supports', $post_type ), + + // Custom labels. + 'menu_name' => pods_v( 'menu_name', $labels ), + 'label_all_items' => pods_v( 'all_items', $labels ), + 'label_add_new' => pods_v( 'add_new', $labels ), + 'label_add_new_item' => pods_v( 'add_new_item', $labels ), + 'label_edit_item' => pods_v( 'edit_item', $labels ), + 'label_new_item' => pods_v( 'new_item', $labels ), + 'label_view_item' => pods_v( 'view_item', $labels ), + 'label_view_items' => pods_v( 'view_items', $labels ), + 'label_search_items' => pods_v( 'search_items', $labels ), + 'label_not_found' => pods_v( 'not_found', $labels ), + 'label_not_found_in_trash' => pods_v( 'not_found_in_trash', $labels ), + 'label_parent' => pods_v( 'parent', $labels ), + 'label_featured_image' => pods_v( 'featured_image', $labels ), + 'label_set_featured_image' => pods_v( 'set_featured_image', $labels ), + 'label_remove_featured_image' => pods_v( 'remove_featured_image', $labels ), + 'label_use_featured_image' => pods_v( 'use_featured_image', $labels ), + 'label_archives' => pods_v( 'archives', $labels ), + 'label_insert_into_item' => pods_v( 'insert_into_item', $labels ), + 'label_uploaded_to_this_item' => pods_v( 'uploaded_to_this_item', $labels ), + 'label_filter_items_list' => pods_v( 'filter_items_list', $labels ), + 'label_items_list_navigation' => pods_v( 'items_list_navigation', $labels ), + 'label_items_list' => pods_v( 'items_list', $labels ), + 'label_attributes' => pods_v( 'attributes', $labels ), + 'label_name_admin_bar' => pods_v( 'name_admin_bar', $labels ), + 'label_item_published' => pods_v( 'item_published', $labels ), + 'label_item_published_privately' => pods_v( 'item_published_privately', $labels ), + 'label_item_reverted_to_draft' => pods_v( 'item_reverted_to_draft', $labels ), + 'label_item_scheduled' => pods_v( 'item_scheduled', $labels ), + 'label_item_updated' => pods_v( 'item_updated', $labels ), + + // Other settings. + 'rest_base' => pods_v( 'rest_base', $post_type ), + 'rest_controller_class' => pods_v( 'rest_controller_class', $post_type ), + 'has_archive_string' => pods_v( 'has_archive_string', $post_type ), + 'capability_type' => pods_v( 'capability_type', $post_type ), + 'rewrite_custom_slug' => pods_v( 'rewrite_slug', $post_type ), + 'query_var_string' => pods_v( 'query_var_slug', $post_type ), + 'menu_position' => pods_v( 'menu_position', $post_type ), + 'menu_string' => pods_v( 'show_in_menu_string', $post_type ), + 'menu_icon' => pods_v( 'menu_icon', $post_type ), + + // Boolean flags (0/1). + 'public' => (int) pods_v( 'public', $post_type ), + 'publicly_queryable' => (int) pods_v( 'publicly_queryable', $post_type ), + 'show_ui' => (int) pods_v( 'show_ui', $post_type ), + 'show_in_nav_menus' => (int) pods_v( 'show_in_nav_menus', $post_type ), + 'delete_with_user' => (int) pods_v( 'delete_with_user', $post_type ), + 'show_in_rest' => (int) pods_v( 'show_in_rest', $post_type ), + 'has_archive' => (int) pods_v( 'has_archive', $post_type ), + 'exclude_from_search' => (int) pods_v( 'exclude_from_search', $post_type ), + 'hierarchical' => (int) pods_v( 'hierarchical', $post_type ), + 'rewrite' => (int) pods_v( 'rewrite', $post_type ), + 'rewrite_with_front' => (int) pods_v( 'rewrite_withfront', $post_type ), + 'query_var' => (int) pods_v( 'query_var', $post_type ), + 'show_in_menu' => (int) pods_v( 'show_in_menu', $post_type ), + ]; // Migrate built-in taxonomies - $builtin = $post_type[1]; - if ( is_array( $builtin ) ) { - foreach ( $builtin as $taxonomy_name ) { - $params[ 'built_in_taxonomies_' . $taxonomy_name ] = 1; - } + $builtin = $taxonomies; + + foreach ( $builtin as $taxonomy_name ) { + $params[ 'built_in_taxonomies_' . $taxonomy_name ] = 1; } if ( ! is_object( $this->api ) ) { @@ -278,40 +338,89 @@ private function migrate_post_type( $post_type ) { * @return bool|int|mixed */ private function migrate_taxonomy( $taxonomy ) { + $labels = []; + + if ( isset( $taxonomy['labels'] ) && is_array( $taxonomy['labels'] ) ) { + // New style. + $labels = $taxonomy['labels']; + } elseif ( isset( $taxonomy[0] ) && is_array( $taxonomy[0] ) ) { + // Old style. + $labels = $taxonomy[0]; + } + + $post_types = []; + + if ( isset( $taxonomy['object_types'] ) && is_array( $taxonomy['object_types'] ) ) { + // New style. + $post_types = $taxonomy['object_types']; + } elseif ( isset( $taxonomy[0] ) && is_array( $taxonomy[0] ) ) { + // Old style. + $post_types = $taxonomy[0]; + } - $params = array( + $default_term = explode( ',', pods_v( 'default_term', $taxonomy ) ); + + $params = [ 'type' => 'taxonomy', - 'storage' => 'table', + 'storage' => 'meta', 'object' => '', - 'name' => pods_var_raw( 'name', $taxonomy ), - 'label' => pods_var_raw( 'label', $taxonomy ), - 'label_singular' => pods_var_raw( 'singular_label', $taxonomy ), - 'public' => 1, - 'show_ui' => (int) pods_var_raw( 'show_ui', $taxonomy ), - 'hierarchical' => (int) pods_var_raw( 'hierarchical', $taxonomy ), - 'query_var' => (int) pods_var_raw( 'query_var', $taxonomy ), - 'rewrite' => (int) pods_var_raw( 'rewrite', $taxonomy ), - 'rewrite_custom_slug' => pods_var_raw( 'rewrite_slug', $taxonomy ), - 'label_search_items' => pods_var_raw( 'search_items', $taxonomy[0] ), - 'label_popular_items' => pods_var_raw( 'popular_items', $taxonomy[0] ), - 'label_all_items' => pods_var_raw( 'all_items', $taxonomy[0] ), - 'label_parent' => pods_var_raw( 'parent_item', $taxonomy[0] ), - 'label_parent_item_colon' => pods_var_raw( 'parent_item_colon', $taxonomy[0] ), - 'label_edit' => pods_var_raw( 'edit_item', $taxonomy[0] ), - 'label_update_item' => pods_var_raw( 'update_item', $taxonomy[0] ), - 'label_add_new' => pods_var_raw( 'add_new_item', $taxonomy[0] ), - 'label_new_item' => pods_var_raw( 'new_item_name', $taxonomy[0] ), - 'label_separate_items_with_commas' => pods_var_raw( 'separate_items_with_commas', $taxonomy[0] ), - 'label_add_or_remove_items' => pods_var_raw( 'add_or_remove_items', $taxonomy[0] ), - 'label_choose_from_the_most_used' => pods_var_raw( 'choose_from_most_used', $taxonomy[0] ), - ); + 'name' => pods_v( 'name', $taxonomy ), + 'label' => pods_v( 'label', $taxonomy ), + 'label_singular' => pods_v( 'singular_label', $taxonomy ), + 'description' => pods_v( 'description', $taxonomy ), + + // Custom labels. + 'label_menu_name' => pods_v( 'menu_name', $labels ), + 'label_all_items' => pods_v( 'all_items', $labels ), + 'label_edit_item' => pods_v( 'edit_item', $labels ), + 'label_view_item' => pods_v( 'view_item', $labels ), + 'label_update_item' => pods_v( 'update_item', $labels ), + 'label_add_new_item' => pods_v( 'add_new_item', $labels ), + 'label_new_item_name' => pods_v( 'new_item_name', $labels ), + 'label_parent_item' => pods_v( 'parent_item', $labels ), + 'label_parent_item_colon' => pods_v( 'parent_item_colon', $labels ), + 'label_search_items' => pods_v( 'search_items', $labels ), + 'label_popular_items' => pods_v( 'popular_items', $labels ), + 'label_separate_items_with_commas' => pods_v( 'separate_items_with_commas', $labels ), + 'label_add_or_remove_items' => pods_v( 'add_or_remove_items', $labels ), + 'label_choose_from_most_used' => pods_v( 'choose_from_most_used', $labels ), + 'label_no_terms' => pods_v( 'no_terms', $labels ), + 'label_items_list_navigation' => pods_v( 'items_list_navigation', $labels ), + 'label_items_list' => pods_v( 'items_list', $labels ), + 'label_not_found' => pods_v( 'not_found', $labels ), + 'label_back_to_items' => pods_v( 'back_to_items', $labels ), + + // Other settings. + 'query_var_string' => pods_v( 'query_var_slug', $taxonomy ), + 'rewrite_custom_slug' => pods_v( 'rewrite_slug', $taxonomy ), + 'rest_base' => pods_v( 'rest_base', $taxonomy ), // Not currently used. + 'rest_controller_class' => pods_v( 'rest_controller_class', $taxonomy ), // Not currently used. + 'register_meta_box_cb' => pods_v( 'meta_box_cb', $taxonomy ), // Not currently used. + 'default_term_name' => $default_term[0], + 'default_term_slug' => $default_term[1], + 'default_term_description' => $default_term[2], + + // Boolean flags (0/1). + 'public' => (int) pods_v( 'public', $taxonomy, 1 ), + 'publicly_queryable' => (int) pods_v( 'publicly_queryable', $taxonomy, 1 ), + 'hierarchical' => (int) pods_v( 'hierarchical', $taxonomy ), + 'show_ui' => (int) pods_v( 'show_ui', $taxonomy, 1 ), + 'show_in_menu' => (int) pods_v( 'show_in_menu', $taxonomy, 1 ), + 'show_in_nav_menus' => (int) pods_v( 'show_in_nav_menus', $taxonomy, 1 ), + 'query_var' => (int) pods_v( 'query_var', $taxonomy, 1 ), + 'rewrite' => (int) pods_v( 'rewrite', $taxonomy, 1 ), + 'rewrite_with_front' => (int) pods_v( 'rewrite_withfront', $taxonomy ), + 'rewrite_hierarchical' => (int) pods_v( 'rewrite_hierarchical', $taxonomy ), + 'show_admin_column' => (int) pods_v( 'show_admin_column', $taxonomy ), + 'show_in_rest' => (int) pods_v( 'show_in_rest', $taxonomy ), + 'show_in_quick_edit' => (int) pods_v( 'show_in_quick_edit', $taxonomy ), + ]; // Migrate attach-to - $attach = $taxonomy[1]; - if ( is_array( $attach ) ) { - foreach ( $attach as $type_name ) { - $params[ 'built_in_post_types_' . $type_name ] = 1; - } + $attach = $post_types; + + foreach ( $attach as $type_name ) { + $params[ 'built_in_post_types_' . $type_name ] = 1; } if ( ! is_object( $this->api ) ) { @@ -348,7 +457,6 @@ private function migrate_taxonomy( $taxonomy ) { * @since 2.0.0 */ public function clean() { - if ( ! is_null( $this->post_option_name ) ) { delete_option( $this->post_option_name ); } diff --git a/components/Migrate-CPTUI/ui/wizard.php b/components/Migrate-CPTUI/ui/wizard.php index e780494446..f54879b790 100644 --- a/components/Migrate-CPTUI/ui/wizard.php +++ b/components/Migrate-CPTUI/ui/wizard.php @@ -1,7 +1,4 @@
-

@@ -82,7 +79,12 @@ ?>
  • - $post_type_label . ' (' . $post_type_name . ')' ) ); ?> + $post_type_label . ' (' . $post_type_name . ')', + 'disable_dfv' => true, + ] ); + ?>
  • - $taxonomy_label . ' (' . $taxonomy_name . ')' ) ); ?> + $taxonomy_label . ' (' . $taxonomy_name . ')', + 'disable_dfv' => true, + ] ); + ?>
  • -
    +
    - - + +
    diff --git a/components/Migrate-Packages/Migrate-Packages.php b/components/Migrate-Packages/Migrate-Packages.php index f4102fdbf7..0f74103ec0 100644 --- a/components/Migrate-Packages/Migrate-Packages.php +++ b/components/Migrate-Packages/Migrate-Packages.php @@ -25,13 +25,27 @@ */ class Pods_Migrate_Packages extends PodsComponent { + /** + * The PodsAPI instance. + * + * @var PodsAPI + */ + private static $api; + + /** + * The package meta version. + * + * @var string + */ + private static $package_meta_version; + /** * Enqueue styles * * @since 2.0.0 */ public function admin_assets() { - + wp_enqueue_script( 'pods-file-saver', PODS_URL . '/components/Migrate-Packages/js/FileSaver.min.js', '', [], '2.0.4', true ); wp_enqueue_style( 'pods-wizard' ); } @@ -44,9 +58,8 @@ public function admin_assets() { * @since 2.0.0 */ public function admin( $options, $component ) { - $method = 'import_export'; - // ajax_import + pods_view( PODS_DIR . 'components/Migrate-Packages/ui/wizard.php', compact( array_keys( get_defined_vars() ) ) ); } @@ -56,14 +69,41 @@ public function admin( $options, $component ) { * @param $params */ public function ajax_import_export( $params ) { - if ( 'import' === $params->import_export ) { $data = trim( $params->import_package ); + $file = null; $content = '
    '; + /** + * Allow filtering whether to replace existing configurations when importing a package. + * + * @since 2.8.0 + * + * @param bool $replace Whether to replace existing configurations when importing a package. + */ + $replace = apply_filters( 'pods_migrate_packages_import_replace', false ); + + if ( ! empty( $_FILES['import_package_file'] ) ) { + $data = null; + $file = $_FILES['import_package_file']; + + if ( 0 !== (int) $file['error'] ) { + $content .= '

    ' . esc_html__( 'Import Error: Package upload failed', 'pods' ) . '

    '; + } elseif ( + ! in_array( $file['type'], [ 'application/json', 'text/json' ], true ) + || '.json' !== substr( $file['name'], -5, 5 ) + ) { + $content .= '

    ' . esc_html__( 'Import Error: Package upload is not a valid JSON file', 'pods' ) . '

    '; + } elseif ( ! is_file( $file['tmp_name'] ) ) { + $content .= '

    ' . esc_html__( 'Import Error: Package upload not completed', 'pods' ) . '

    '; + } else { + $data = file_get_contents( $file['tmp_name'] ); + } + } + if ( ! empty( $data ) ) { - $imported = $this->import( $data ); + $imported = self::import( $data, $replace ); if ( ! empty( $imported ) ) { $content .= '

    Import Complete! The following items were imported:

    '; @@ -80,8 +120,8 @@ public function ajax_import_export( $params ) { $content .= ''; } } - } else { - $content .= '

    Import Error: Invalid Package

    '; + } elseif ( null === $file ) { + $content .= '

    ' . esc_html__( 'Import Error: Invalid Package', 'pods' ) . '

    '; }//end if $content .= '
    '; @@ -95,15 +135,19 @@ public function ajax_import_export( $params ) { } } - $package = $this->export( $params ); + $package = self::export( $params ); echo '
    '; - echo PodsForm::field( 'export_package', $package, 'paragraph', array( 'attributes' => array( 'style' => 'width: 94%; max-width: 94%; height: 300px;' ) ) ); + echo PodsForm::field( 'export_package', $package, 'paragraph', [ + 'attributes' => [ + 'style' => 'width: 94%; max-width: 94%; height: 300px;', + ], + 'disable_dfv' => true, + ] ); echo '
    '; }//end if - } /** @@ -137,7 +181,7 @@ public static function import( $data, $replace = false ) { return false; } - $api = pods_api(); + self::$api = pods_api(); if ( ! isset( $data['meta'] ) || ! isset( $data['meta']['version'] ) || empty( $data['meta']['version'] ) ) { return false; @@ -151,414 +195,629 @@ public static function import( $data, $replace = false ) { $data['meta']['version'] = pods_version_to_point( $data['meta']['version'] ); } + self::$package_meta_version = $data['meta']['version']; + $found = array(); if ( isset( $data['pods'] ) && is_array( $data['pods'] ) ) { foreach ( $data['pods'] as $pod_data ) { - if ( isset( $pod_data['id'] ) ) { - unset( $pod_data['id'] ); + $pod = self::import_pod( $pod_data, $replace ); + + if ( ! $pod ) { + continue; } - $pod = $api->load_pod( array( 'name' => $pod_data['name'] ), false ); + if ( ! isset( $found['pods'] ) ) { + $found['pods'] = array(); + } - $existing_fields = array(); + $found['pods'][ $pod['name'] ] = $pod['label']; + }//end foreach + }//end if - if ( ! empty( $pod ) ) { - // Delete Pod if it exists - if ( $replace ) { - $api->delete_pod( array( 'id' => $pod['id'] ) ); + if ( isset( $data['templates'] ) && is_array( $data['templates'] ) ) { + foreach ( $data['templates'] as $template_data ) { + $template = self::import_pod_template( $template_data, $replace ); - $pod = array( 'fields' => array() ); - } else { - $existing_fields = $pod['fields']; - } - } else { - $pod = array( 'fields' => array() ); + if ( ! $template ) { + continue; } - // Backwards compatibility - if ( version_compare( $data['meta']['version'], '2.0', '<' ) ) { - $core_fields = array( - array( - 'name' => 'created', - 'label' => 'Date Created', - 'type' => 'datetime', - 'options' => array( - 'datetime_format' => 'ymd_slash', - 'datetime_time_type' => '12', - 'datetime_time_format' => 'h_mm_ss_A', - ), - 'weight' => 1, - ), - array( - 'name' => 'modified', - 'label' => 'Date Modified', - 'type' => 'datetime', - 'options' => array( - 'datetime_format' => 'ymd_slash', - 'datetime_time_type' => '12', - 'datetime_time_format' => 'h_mm_ss_A', - ), - 'weight' => 2, - ), - array( - 'name' => 'author', - 'label' => 'Author', - 'type' => 'pick', - 'pick_object' => 'user', - 'options' => array( - 'pick_format_type' => 'single', - 'pick_format_single' => 'autocomplete', - 'default_value' => '{@user.ID}', - ), - 'weight' => 3, - ), - ); - - $found_fields = array(); - - if ( ! empty( $pod_data['fields'] ) ) { - foreach ( $pod_data['fields'] as $k => $field ) { - $field_type = $field['coltype']; - - if ( 'txt' === $field_type ) { - $field_type = 'text'; - } elseif ( 'desc' === $field_type ) { - $field_type = 'wysiwyg'; - } elseif ( 'code' === $field_type ) { - $field_type = 'paragraph'; - } elseif ( 'bool' === $field_type ) { - $field_type = 'boolean'; - } elseif ( 'num' === $field_type ) { - $field_type = 'number'; - } elseif ( 'date' === $field_type ) { - $field_type = 'datetime'; - } + if ( ! isset( $found['templates'] ) ) { + $found['templates'] = array(); + } - $multiple = min( max( (int) $field['multiple'], 0 ), 1 ); - - $new_field = array( - 'name' => trim( $field['name'] ), - 'label' => trim( $field['label'] ), - 'description' => trim( $field['comment'] ), - 'type' => $field_type, - 'weight' => (int) $field['weight'], - 'options' => array( - 'required' => min( max( (int) $field['required'], 0 ), 1 ), - 'unique' => min( max( (int) $field['unique'], 0 ), 1 ), - 'input_helper' => $field['input_helper'], - ), - ); - - if ( in_array( $new_field['name'], $found_fields, true ) ) { - unset( $pod_data['fields'][ $k ] ); - - continue; - } + $found['templates'][ $template['name'] ] = $template['name']; + }//end foreach + }//end if - $found_fields[] = $new_field['name']; + // Backwards compatibility + if ( isset( $data['pod_pages'] ) ) { + $data['pages'] = $data['pod_pages']; - if ( 'pick' === $field_type ) { - $new_field['pick_object'] = 'pod'; - $new_field['pick_val'] = $field['pickval']; + unset( $data['pod_pages'] ); + } - if ( 'wp_user' === $field['pickval'] ) { - $new_field['pick_object'] = 'user'; - } elseif ( 'wp_post' === $field['pickval'] ) { - $new_field['pick_object'] = 'post_type-post'; - } elseif ( 'wp_page' === $field['pickval'] ) { - $new_field['pick_object'] = 'post_type-page'; - } elseif ( 'wp_taxonomy' === $field['pickval'] ) { - $new_field['pick_object'] = 'taxonomy-category'; - } + if ( isset( $data['pages'] ) && is_array( $data['pages'] ) ) { + foreach ( $data['pages'] as $page_data ) { + $page = self::import_pod_page( $page_data, $replace ); - // This won't work if the field doesn't exist - // $new_field[ 'sister_id' ] = $field[ 'sister_field_id' ]; - $new_field['options']['pick_filter'] = $field['pick_filter']; - $new_field['options']['pick_orderby'] = $field['pick_orderby']; - $new_field['options']['pick_display'] = ''; - $new_field['options']['pick_size'] = 'medium'; - - if ( 1 == $multiple ) { - $new_field['options']['pick_format_type'] = 'multi'; - $new_field['options']['pick_format_multi'] = 'checkbox'; - $new_field['options']['pick_limit'] = 0; - } else { - $new_field['options']['pick_format_type'] = 'single'; - $new_field['options']['pick_format_single'] = 'dropdown'; - $new_field['options']['pick_limit'] = 1; - } - } elseif ( 'file' === $field_type ) { - $new_field['options']['file_format_type'] = 'multi'; - $new_field['options']['file_type'] = 'any'; - } elseif ( 'number' === $field_type ) { - $new_field['options']['number_decimals'] = 2; - } elseif ( 'desc' === $field['coltype'] ) { - $new_field['options']['wysiwyg_editor'] = 'tinymce'; - } elseif ( 'text' === $field_type ) { - $new_field['options']['text_max_length'] = 128; - }//end if - - if ( isset( $pod['fields'][ $new_field['name'] ] ) ) { - $new_field = array_merge( $pod['fields'][ $new_field['name'] ], $new_field ); - } + if ( ! $page ) { + continue; + } - $pod_data['fields'][ $k ] = $new_field; - }//end foreach - }//end if + if ( ! isset( $found['pages'] ) ) { + $found['pages'] = array(); + } - if ( pods_var( 'id', $pod, 0 ) < 1 ) { - $pod_data['fields'] = array_merge( $core_fields, $pod_data['fields'] ); - } + $found['pages'][ $page['name'] ] = $page['name']; + }//end foreach + }//end if - if ( empty( $pod_data['label'] ) ) { - $pod_data['label'] = ucwords( str_replace( '_', ' ', $pod_data['name'] ) ); - } + if ( isset( $data['helpers'] ) && is_array( $data['helpers'] ) ) { + foreach ( $data['helpers'] as $helper_data ) { + $helper = self::import_pod_helper( $helper_data, $replace ); - if ( isset( $pod_data['is_toplevel'] ) ) { - $pod_data['show_in_menu'] = ( 1 == $pod_data['is_toplevel'] ? 1 : 0 ); + if ( ! $helper ) { + continue; + } - unset( $pod_data['is_toplevel'] ); - } + if ( ! isset( $found['helpers'] ) ) { + $found['helpers'] = array(); + } - if ( isset( $pod_data['detail_page'] ) ) { - $pod_data['detail_url'] = $pod_data['detail_page']; + $found['helpers'][ $helper['name'] ] = $helper['name']; + }//end foreach + }//end if - unset( $pod_data['detail_page'] ); - } + $found = apply_filters( 'pods_packages_import', $found, $data, $replace ); - if ( isset( $pod_data['before_helpers'] ) ) { - $pod_data['pre_save_helpers'] = $pod_data['before_helpers']; + if ( ! empty( $found ) ) { + return $found; + } - unset( $pod_data['before_helpers'] ); - } + return false; + } - if ( isset( $pod_data['after_helpers'] ) ) { - $pod_data['post_save_helpers'] = $pod_data['after_helpers']; + /** + * Handle importing of the pod. + * + * @since 2.8.0 + * + * @param array $data The import data. + * @param bool $replace Whether to replace an existing configuration if found. + * + * @return array|\Pods\Whatsit|false The imported object or false if failed. + */ + public static function import_pod( $data, $replace = false ) { + if ( isset( $data['id'] ) ) { + unset( $data['id'] ); + } - unset( $pod_data['after_helpers'] ); - } + $pod_object = self::$api->load_pod( [ 'name' => $data['name'] ], false ); - if ( isset( $pod_data['pre_drop_helpers'] ) ) { - $pod_data['pre_delete_helpers'] = $pod_data['pre_drop_helpers']; + $pod = [ + 'groups' => [], + 'fields' => [], + ]; - unset( $pod_data['pre_drop_helpers'] ); - } + $existing_groups = []; + $existing_fields = []; - if ( isset( $pod_data['post_drop_helpers'] ) ) { - $pod_data['post_delete_helpers'] = $pod_data['post_drop_helpers']; + if ( $pod_object ) { + // Convert to an array. + $pod = $pod_object->get_args(); - unset( $pod_data['post_drop_helpers'] ); - } + if ( ! $replace ) { + // We will still be replacing any groups/fields that are sent. + $replace = true; - $pod_data['name'] = pods_clean_name( $pod_data['name'] ); - - $pod_data = array( - 'name' => $pod_data['name'], - 'label' => $pod_data['label'], - 'type' => 'pod', - 'storage' => 'table', - 'fields' => $pod_data['fields'], - 'options' => array( - 'pre_save_helpers' => pods_var_raw( 'pre_save_helpers', $pod_data ), - 'post_save_helpers' => pods_var_raw( 'post_save_helpers', $pod_data ), - 'pre_delete_helpers' => pods_var_raw( 'pre_delete_helpers', $pod_data ), - 'post_delete_helpers' => pods_var_raw( 'post_delete_helpers', $pod_data ), - 'show_in_menu' => ( 1 == pods_var_raw( 'show_in_menu', $pod_data, 0 ) ? 1 : 0 ), - 'detail_url' => pods_var_raw( 'detail_url', $pod_data ), - 'pod_index' => 'name', - ), - ); - }//end if + // Append to the groups and fields. + $existing_groups = $pod_object['groups']; + $existing_fields = $pod_object['fields']; + } + } - $pod = array_merge( $pod, $pod_data ); + $pod_data = $data; - if ( in_array( $pod['name'], pods_reserved_keywords(), true ) ) { - // Extending objects when using reserved keywords. - // This will then accept `post`, `page` etc. as Pods object names. - $pod['create_extend'] = 'extend'; - } + // Backwards compatibility + if ( version_compare( self::$package_meta_version, '2.0', '<' ) ) { + $pod_data = self::import_pod_prepare( $data, $pod ); + } - foreach ( $pod['fields'] as $k => $field ) { - if ( isset( $field['id'] ) && ! isset( $existing_fields[ $field['name'] ] ) ) { - unset( $pod['fields'][ $k ]['id'] ); - } + $pod = pods_config_merge_data( $pod, $pod_data ); - if ( isset( $field['pod_id'] ) ) { - unset( $pod['fields'][ $k ]['pod_id'] ); - } + if ( in_array( $pod['name'], pods_reserved_keywords(), true ) ) { + // Extending objects when using reserved keywords. + // This will then accept `post`, `page` etc. as Pods object names. + $pod['create_extend'] = 'extend'; + } - if ( isset( $existing_fields[ $field['name'] ] ) ) { - $existing_field = pods_api()->load_field( - array( - 'name' => $field['name'], - 'pod' => $pod['name'], - ) - ); - if ( $existing_field ) { - $pod['fields'][ $k ]['id'] = $existing_field['id']; - } - } + if ( ! empty( $pod['groups'] ) ) { + $pod['groups'] = self::import_pod_setup_objects( $pod['groups'], $existing_groups, $existing_fields ); + } elseif ( ! empty( $pod['fields'] ) ) { + $pod['fields'] = self::import_pod_setup_objects( $pod['fields'], $existing_fields ); + } - if ( isset( $field['pod'] ) ) { - unset( $pod['fields'][ $k ]['pod'] ); - } - }//end foreach + $pod['overwrite'] = $replace; - if ( $api->save_pod( $pod ) ) { - if ( ! isset( $found['pods'] ) ) { - $found['pods'] = array(); - } + self::$api->save_pod( $pod ); - $found['pods'][ $pod['name'] ] = $pod['label']; + return $pod; + } + + /** + * Handle setting up the objects for importing. + * + * @since 2.8.0 + * + * @param array $objects The objects to set up. + * @param array $existing_objects List of existing objects. + * @param array $existing_fields List of existing fields (if the objects support fields). + * + * @return array The objects that were set up. + */ + private static function import_pod_setup_objects( array $objects, array $existing_objects, array $existing_fields = [] ) { + $unset_args = [ + 'id', + 'pod', + 'pod_data', + 'pod_id', + 'group', + 'group_id', + ]; + + foreach ( $objects as $key => $object ) { + foreach ( $unset_args as $unset_arg ) { + if ( isset( $object[ $unset_arg ] ) ) { + unset( $object[ $unset_arg ] ); } + } - }//end foreach - }//end if + if ( isset( $existing_objects[ $object['name'] ] ) ) { + // Set the ID as we need to be updating the existing object. + $object['id'] = $existing_objects[ $object['name'] ]['id']; + } - if ( isset( $data['templates'] ) && is_array( $data['templates'] ) ) { - foreach ( $data['templates'] as $template_data ) { - if ( isset( $template_data['id'] ) ) { - unset( $template_data['id'] ); - } + if ( ! empty( $object['fields'] ) ) { + $object['fields'] = self::import_pod_setup_objects( $object['fields'], $existing_fields ); + } - $template = $api->load_template( array( 'name' => $template_data['name'] ) ); + $objects[ $key ] = $object; + } - if ( ! empty( $template ) ) { - // Delete Template if it exists - if ( $replace ) { - $api->delete_template( array( 'id' => $template['id'] ) ); + return $objects; + } - $template = array(); - } - } else { - $template = array(); + /** + * Handle import preparation of the pod. + * + * @since 2.8.0 + * + * @param array $data The import data. + * @param array $pod The existing pod (if set). + * + * @return array|false The prepared pod or false if failed. + */ + public static function import_pod_prepare( $data, $pod ) { + $core_fields = [ + [ + 'name' => 'created', + 'label' => 'Date Created', + 'type' => 'datetime', + 'options' => [ + 'datetime_format' => 'ymd_slash', + 'datetime_time_type' => '12', + 'datetime_time_format' => 'h_mm_ss_A', + ], + 'weight' => 1, + ], + [ + 'name' => 'modified', + 'label' => 'Date Modified', + 'type' => 'datetime', + 'options' => [ + 'datetime_format' => 'ymd_slash', + 'datetime_time_type' => '12', + 'datetime_time_format' => 'h_mm_ss_A', + ], + 'weight' => 2, + ], + [ + 'name' => 'author', + 'label' => 'Author', + 'type' => 'pick', + 'pick_object' => 'user', + 'options' => [ + 'pick_format_type' => 'single', + 'pick_format_single' => 'autocomplete', + 'default_value' => '{@user.ID}', + ], + 'weight' => 3, + ], + ]; + + $found_fields = []; + + if ( ! empty( $data['fields'] ) ) { + foreach ( $data['fields'] as $k => $field ) { + if ( in_array( $field['name'], $found_fields, true ) ) { + return false; } - $template = array_merge( $template, $template_data ); + $field = self::import_pod_field( $field ); - $api->save_template( $template ); + if ( ! $field ) { + continue; + } - if ( ! isset( $found['templates'] ) ) { - $found['templates'] = array(); + $found_fields[] = $field['name']; + + if ( isset( $pod['fields'][ $field['name'] ] ) ) { + $field = pods_config_merge_data( $pod['fields'][ $field['name'] ], $field ); } - $found['templates'][ $template['name'] ] = $template['name']; + $data['fields'][ $k ] = $field; }//end foreach }//end if - // Backwards compatibility - if ( isset( $data['pod_pages'] ) ) { - $data['pages'] = $data['pod_pages']; + if ( (int) pods_v( 'id', $pod, 0 ) < 1 ) { + $data['fields'] = array_merge( $core_fields, $data['fields'] ); + } - unset( $data['pod_pages'] ); + if ( empty( $data['label'] ) ) { + $data['label'] = ucwords( str_replace( '_', ' ', $data['name'] ) ); } - if ( isset( $data['pages'] ) && is_array( $data['pages'] ) ) { - foreach ( $data['pages'] as $page_data ) { - if ( isset( $page_data['id'] ) ) { - unset( $page_data['id'] ); - } + if ( isset( $data['is_toplevel'] ) ) { + $data['show_in_menu'] = ( 1 === (int) $data['is_toplevel'] ? 1 : 0 ); - $page = $api->load_page( array( 'name' => pods_var_raw( 'name', $page_data, pods_var_raw( 'uri', $page_data ), null, true ) ) ); + unset( $data['is_toplevel'] ); + } - if ( ! empty( $page ) ) { - // Delete Page if it exists - if ( $replace ) { - $api->delete_page( array( 'id' => $page['id'] ) ); + $mapped_deprecated_options = [ + 'detail_page' => 'detail_url', + 'before_helpers' => 'pre_save_helpers', + 'after_helpers' => 'post_save_helpers', + 'pre_drop_helpers' => 'pre_delete_helpers', + 'post_drop_helpers' => 'post_delete_helpers', + ]; + + foreach ( $mapped_deprecated_options as $mapped_deprecated_option => $new_option ) { + if ( ! isset( $data[ $mapped_deprecated_option ] ) ) { + continue; + } - $page = array(); - } - } else { - $page = array(); - } + $data[ $new_option ] = $data[ $mapped_deprecated_option ]; - // Backwards compatibility - if ( isset( $page_data['uri'] ) ) { - $page_data['name'] = $page_data['uri']; + unset( $data[ $mapped_deprecated_option ] ); + } - unset( $page_data['uri'] ); - } + $data['name'] = pods_clean_name( $data['name'] ); + + // Set up basic pod configuration (ACT). + return [ + 'name' => $data['name'], + 'label' => $data['label'], + 'type' => 'pod', + 'storage' => 'table', + 'fields' => $data['fields'], + 'options' => [ + 'pre_save_helpers' => pods_v( 'pre_save_helpers', $data ), + 'post_save_helpers' => pods_v( 'post_save_helpers', $data ), + 'pre_delete_helpers' => pods_v( 'pre_delete_helpers', $data ), + 'post_delete_helpers' => pods_v( 'post_delete_helpers', $data ), + 'show_in_menu' => ( 1 === (int) pods_v( 'show_in_menu', $data, 0 ) ? 1 : 0 ), + 'detail_url' => pods_v( 'detail_url', $data ), + 'pod_index' => 'name', + ], + ]; + } + + /** + * Handle import preparation of the field. + * + * @since 2.8.0 + * + * @param array $data The import data. + * + * @return array|false The prepared field or false if failed. + */ + public static function import_pod_field_prepare( $data ) { + // Easy import if we aren't dealing with deprecated mappings. + if ( ! isset( $data['coltype'] ) ) { + return $data; + } - if ( isset( $page_data['phpcode'] ) ) { - $page_data['code'] = $page_data['phpcode']; + // Handle deprecated field import preparation. + $mapped_deprecated_types = [ + 'txt' => 'text', + 'desc' => 'wysiwyg', + 'code' => 'paragraph', + 'bool' => 'boolean', + 'num' => 'number', + 'date' => 'datetime', + ]; - unset( $page_data['phpcode'] ); - } + // Get field type but check for deprecated coltype. + $field_type = pods_v( 'type', $data, pods_v( 'coltype', $data ) ); - $page = array_merge( $page, $page_data ); + if ( empty( $field_type ) ) { + return false; + } - $page['name'] = trim( $page['name'], '/' ); + if ( isset( $mapped_deprecated_types[ $field_type ] ) ) { + $field_type = $mapped_deprecated_types[ $field_type ]; + } - $api->save_page( $page ); + $new_field = [ + 'name' => trim( pods_v( 'name', $data, '' ) ), + 'label' => trim( pods_v( 'label', $data, '' ) ), + 'description' => trim( pods_v( 'description', $data, pods_v( 'comment', $data, '' ) ) ), + 'type' => $field_type, + 'weight' => (int) $data['weight'], + 'required' => 1 === (int) $data['required'] ? 1 : 0, + 'unique' => 1 === (int) $data['unique'] ? 1 : 0, + ]; + + if ( isset( $data['input_helper'] ) ) { + $new_field['input_helper'] = $data['input_helper']; + } - if ( ! isset( $found['pages'] ) ) { - $found['pages'] = array(); + if ( 'pick' === $field_type ) { + $mapped_deprecated_relationship_values = [ + 'wp_user' => 'user', + 'wp_post' => 'post_type-post', + 'wp_page' => 'post_type-page', + 'wp_taxonomy' => 'taxonomy-category', + ]; + + if ( isset( $data['pickval'] ) ) { + $new_field['pick_object'] = 'pod'; + $new_field['pick_val'] = $data['pickval']; + + if ( isset( $mapped_deprecated_relationship_values[ $data['pickval'] ] ) ) { + $new_field['pick_object'] = $mapped_deprecated_relationship_values[ $data['pickval'] ]; } + } - $found['pages'][ $page['name'] ] = $page['name']; - }//end foreach + // @todo Add sister field ID mapping. + + // This won't work if the field doesn't exist + // $new_field['sister_id'] = $data['sister_field_id']; + $new_field['options']['pick_filter'] = $data['pick_filter']; + $new_field['options']['pick_orderby'] = $data['pick_orderby']; + $new_field['options']['pick_display'] = ''; + $new_field['options']['pick_size'] = 'medium'; + + if ( 1 === (int) $data['multiple'] ) { + $new_field['options']['pick_format_type'] = 'multi'; + $new_field['options']['pick_format_multi'] = 'checkbox'; + $new_field['options']['pick_limit'] = 0; + } else { + $new_field['options']['pick_format_type'] = 'single'; + $new_field['options']['pick_format_single'] = 'dropdown'; + $new_field['options']['pick_limit'] = 1; + } + } elseif ( 'file' === $field_type ) { + $new_field['options']['file_format_type'] = 'multi'; + $new_field['options']['file_type'] = 'any'; + } elseif ( 'number' === $field_type ) { + $new_field['options']['number_decimals'] = 2; + } elseif ( isset( $data['coltype'] ) && 'desc' === $data['coltype'] ) { + $new_field['options']['wysiwyg_editor'] = 'tinymce'; + } elseif ( 'text' === $field_type ) { + $new_field['options']['text_max_length'] = 128; }//end if - if ( isset( $data['helpers'] ) && is_array( $data['helpers'] ) ) { - foreach ( $data['helpers'] as $helper_data ) { - if ( isset( $helper_data['id'] ) ) { - unset( $helper_data['id'] ); - } + return $new_field; + } - $helper = $api->load_helper( array( 'name' => $helper_data['name'] ) ); + /** + * Handle importing of the pod template. + * + * @since 2.8.0 + * + * @param array $data The import data. + * @param bool $replace Whether to replace an existing configuration if found. + * + * @return array|\Pods\Whatsit|false The imported object or false if failed. + */ + public static function import_pod_template( $data, $replace = false ) { + if ( isset( $data['id'] ) ) { + unset( $data['id'] ); + } - if ( ! empty( $helper ) ) { - // Delete Helper if it exists - if ( $replace ) { - $api->delete_helper( array( 'id' => $helper['id'] ) ); + $template = self::$api->load_template( [ + 'name' => $data['name'], + ] ); - $helper = array(); - } - } else { - $helper = array(); - } + if ( ! empty( $template ) ) { + // Delete Template if it exists + if ( $replace ) { + self::$api->delete_template( [ 'id' => $template['id'] ] ); - // Backwards compatibility - if ( isset( $helper_data['phpcode'] ) ) { - $helper_data['code'] = $helper_data['phpcode']; + $template = []; + } + } else { + $template = []; + } - unset( $helper_data['phpcode'] ); - } + $template_id = (int) pods_v( 'id', $template ); - if ( isset( $helper_data['type'] ) ) { - if ( 'before' === $helper_data['type'] ) { - $helper_data['type'] = 'pre_save'; - } elseif ( 'after' === $helper_data['type'] ) { - $helper_data['type'] = 'post_save'; - } + $template = pods_config_merge_data( $template, $data ); + + if ( $template instanceof \Pods\Whatsit\Template ) { + $template = $template->get_args(); + + $excluded_args = [ + 'object_type', + 'storage_type', + 'parent', + 'group', + 'label', + 'description', + 'slug', + 'weight', + ]; + + foreach ( $excluded_args as $excluded_arg ) { + if ( isset( $template[ $excluded_arg ] ) ) { + unset( $template[ $excluded_arg ] ); } + } + } elseif ( ! empty( $template['options'] ) ) { + $template = pods_config_merge_data( $template, $template['options'] ); - $helper = array_merge( $helper, $helper_data ); + unset( $template['options'] ); + } + + if ( 0 < $template_id ) { + $template['id'] = $template_id; + } - if ( isset( $helper['type'] ) ) { - $helper['helper_type'] = $helper['type']; + self::$api->save_template( $template ); - unset( $helper['helper_type'] ); - } + return $template; + } - $api->save_helper( $helper ); + /** + * Handle importing of the pod page. + * + * @since 2.8.0 + * + * @param array $data The import data. + * @param bool $replace Whether to replace an existing configuration if found. + * + * @return array|\Pods\Whatsit|false The imported object or false if failed. + */ + public static function import_pod_page( $data, $replace = false ) { + if ( isset( $data['id'] ) ) { + unset( $data['id'] ); + } - if ( ! isset( $found['helpers'] ) ) { - $found['helpers'] = array(); + $page = self::$api->load_page( [ + 'name' => pods_v( 'name', $data, pods_v( 'uri', $data ), true ), + ] ); + + if ( ! empty( $page ) ) { + // Delete Page if it exists + if ( $replace ) { + self::$api->delete_page( [ 'id' => $page['id'] ] ); + + $page = []; + } + } else { + $page = []; + } + + // Backwards compatibility + if ( isset( $data['uri'] ) ) { + $data['name'] = $data['uri']; + + unset( $data['uri'] ); + } + + if ( isset( $data['phpcode'] ) ) { + $data['code'] = $data['phpcode']; + + unset( $data['phpcode'] ); + } + + $page_id = (int) pods_v( 'id', $page ); + + $page = pods_config_merge_data( $page, $data ); + + if ( $page instanceof \Pods\Whatsit\Page ) { + $page = $page->get_args(); + + $excluded_args = [ + 'object_type', + 'storage_type', + 'parent', + 'group', + 'label', + 'description', + 'slug', + 'weight', + ]; + + foreach ( $excluded_args as $excluded_arg ) { + if ( isset( $template[ $excluded_arg ] ) ) { + unset( $template[ $excluded_arg ] ); } + } + } elseif ( ! empty( $page['options'] ) ) { + $page = pods_config_merge_data( $page, $page['options'] ); - $found['helpers'][ $helper['name'] ] = $helper['name']; - }//end foreach - }//end if + unset( $page['options'] ); + } - $found = apply_filters( 'pods_packages_import', $found, $data, $replace ); + if ( 0 < $page_id ) { + $page['id'] = $page_id; + } - if ( ! empty( $found ) ) { - return $found; + $page['name'] = trim( $page['name'], '/' ); + + self::$api->save_page( $page ); + + return $page; + } + + /** + * Handle importing of the pod helper. + * + * @since 2.8.0 + * + * @param array $data The import data. + * @param bool $replace Whether to replace an existing configuration if found. + * + * @return array|\Pods\Whatsit|false The imported object or false if failed. + */ + public static function import_pod_helper( $data, $replace = false ) { + if ( isset( $data['id'] ) ) { + unset( $data['id'] ); } - return false; + $helper = self::$api->load_helper( [ 'name' => $data['name'] ] ); + + if ( ! empty( $helper ) ) { + // Delete Helper if it exists + if ( $replace ) { + self::$api->delete_helper( [ 'id' => $helper['id'] ] ); + + $helper = []; + } + } else { + $helper = []; + } + + // Backwards compatibility + if ( isset( $data['phpcode'] ) ) { + $data['code'] = $data['phpcode']; + + unset( $data['phpcode'] ); + } + + if ( isset( $data['type'] ) ) { + if ( 'before' === $data['type'] ) { + $data['type'] = 'pre_save'; + } elseif ( 'after' === $data['type'] ) { + $data['type'] = 'post_save'; + } + } + + $helper = pods_config_merge_data( $helper, $data ); + + if ( isset( $helper['type'] ) ) { + $helper['helper_type'] = $helper['type']; + + unset( $helper['helper_type'] ); + } + + self::$api->save_helper( $helper ); + + return $helper; } /** @@ -589,25 +848,35 @@ public static function export( $params ) { $params = get_object_vars( $params ); } - $api = pods_api(); + self::$api = pods_api(); - $pod_ids = pods_var_raw( 'pods', $params ); - $template_ids = pods_var_raw( 'templates', $params ); - $page_ids = pods_var_raw( 'pages', $params ); - $helper_ids = pods_var_raw( 'helpers', $params ); + $pod_ids = pods_v( 'pods', $params ); + $template_ids = pods_v( 'templates', $params ); + $page_ids = pods_v( 'pages', $params ); + $helper_ids = pods_v( 'helpers', $params ); if ( ! empty( $pod_ids ) ) { - $api_params = array( 'export' => true ); + $api_params = []; if ( true !== $pod_ids ) { $api_params['ids'] = (array) $pod_ids; } - $export['pods'] = $api->load_pods( $api_params ); + $export['pods'] = self::$api->load_pods( $api_params ); + $export['pods'] = array_map( static function( $pod ) { + return $pod->export( [ + 'include_fields' => false, + 'build_default_group' => true, + ] ); + }, $export['pods'] ); $options_ignore = array( 'pod_id', + 'parent', 'old_name', + 'podType', + 'storageType', + 'storage_type', 'object_type', 'object_name', 'object_hierarchical', @@ -633,6 +902,7 @@ public static function export( $params ) { 'pod', 'recurse', 'table_info', + 'pod_data', 'attributes', 'group', 'grouped', @@ -640,6 +910,7 @@ public static function export( $params ) { 'dependency', 'depends-on', 'excludes-on', + '_locale', ); $field_types = PodsForm::field_types(); @@ -650,59 +921,76 @@ public static function export( $params ) { $field_type_options[ $type ] = PodsForm::ui_options( $type ); } - foreach ( $export['pods'] as &$pod ) { - if ( isset( $pod['options'] ) ) { - $pod = array_merge( $pod, $pod['options'] ); - - unset( $pod['options'] ); - } - + foreach ( $export['pods'] as $pod_key => $pod ) { foreach ( $pod as $option => $option_value ) { if ( in_array( $option, $options_ignore, true ) || null === $option_value ) { unset( $pod[ $option ] ); } } - if ( ! empty( $pod['fields'] ) ) { - foreach ( $pod['fields'] as &$field ) { - if ( isset( $field['options'] ) ) { - $field = array_merge( $field, $field['options'] ); - - unset( $field['options'] ); - } - - foreach ( $field as $option => $option_value ) { + if ( ! empty( $pod['groups'] ) ) { + foreach ( $pod['groups'] as $group_key => $group ) { + foreach ( $group as $option => $option_value ) { if ( in_array( $option, $options_ignore, true ) || null === $option_value ) { - unset( $field[ $option ] ); + unset( $group[ $option ] ); } } - foreach ( $field_type_options as $type => $options ) { - if ( $type == pods_var( 'type', $field ) ) { - continue; - } + if ( ! empty( $group['fields'] ) ) { + foreach ( $group['fields'] as $field_key => $field ) { + foreach ( $field as $option => $option_value ) { + if ( in_array( $option, $options_ignore, true ) || null === $option_value ) { + unset( $field[ $option ] ); + } + } - foreach ( $options as $option_data ) { - if ( isset( $option_data['group'] ) && is_array( $option_data['group'] ) && ! empty( $option_data['group'] ) ) { - if ( isset( $field[ $option_data['name'] ] ) ) { - unset( $field[ $option_data['name'] ] ); + foreach ( $field_type_options as $type => $options ) { + if ( $type === pods_v( 'type', $field ) ) { + continue; } - foreach ( $option_data['group'] as $group_option_data ) { - if ( isset( $field[ $group_option_data['name'] ] ) ) { - unset( $field[ $group_option_data['name'] ] ); + foreach ( $options as $option_data ) { + if ( isset( $option_data['group'] ) && is_array( $option_data['group'] ) && ! empty( $option_data['group'] ) ) { + if ( isset( $field[ $option_data['name'] ] ) ) { + unset( $field[ $option_data['name'] ] ); + } + + foreach ( $option_data['group'] as $group_option_data ) { + if ( isset( $field[ $group_option_data['name'] ] ) ) { + unset( $field[ $group_option_data['name'] ] ); + } + } + } elseif ( isset( $field[ $option_data['name'] ] ) ) { + unset( $field[ $option_data['name'] ] ); } } - } elseif ( isset( $field[ $option_data['name'] ] ) ) { - unset( $field[ $option_data['name'] ] ); - } - } - }//end foreach + }//end foreach + + $group['fields'][ $field_key ] = $field; + }//end foreach + + $group['fields'] = array_values( $group['fields'] ); + }//end if + + $pod['groups'][ $group_key ] = $group; }//end foreach + + $pod['groups'] = array_values( $pod['groups'] ); }//end if + + $export['pods'][ $pod_key ] = $pod; }//end foreach + + $export['pods'] = array_values( $export['pods'] ); }//end if + $excluded_args = [ + 'label', + 'description', + 'slug', + 'weight', + ]; + if ( ! empty( $template_ids ) ) { $api_params = array(); @@ -710,7 +998,19 @@ public static function export( $params ) { $api_params['ids'] = (array) $template_ids; } - $export['templates'] = $api->load_templates( $api_params ); + $export['templates'] = array_values( self::$api->load_templates( $api_params ) ); + + foreach ( $export['templates'] as $k => $template ) { + $template = $template->get_clean_args(); + + foreach ( $excluded_args as $excluded_arg ) { + if ( isset( $template[ $excluded_arg ] ) ) { + unset( $template[ $excluded_arg ] ); + } + } + + $export['templates'][ $k ] = $template; + } } if ( ! empty( $page_ids ) ) { @@ -720,7 +1020,19 @@ public static function export( $params ) { $api_params['ids'] = (array) $page_ids; } - $export['pages'] = $api->load_pages( $api_params ); + $export['pages'] = array_values( self::$api->load_pages( $api_params ) ); + + foreach ( $export['pages'] as $k => $page ) { + $page = $page->get_clean_args(); + + foreach ( $excluded_args as $excluded_arg ) { + if ( isset( $page[ $excluded_arg ] ) ) { + unset( $page[ $excluded_arg ] ); + } + } + + $export['pages'][ $k ] = $page; + } } if ( ! empty( $helper_ids ) ) { @@ -730,7 +1042,19 @@ public static function export( $params ) { $api_params['ids'] = (array) $helper_ids; } - $export['helpers'] = $api->load_helpers( $api_params ); + $export['helpers'] = array_values( self::$api->load_helpers( $api_params ) ); + + foreach ( $export['helpers'] as $k => $helper ) { + $helper = $helper->get_clean_args(); + + foreach ( $excluded_args as $excluded_arg ) { + if ( isset( $helper[ $excluded_arg ] ) ) { + unset( $helper[ $excluded_arg ] ); + } + } + + $export['helpers'][ $k ] = $helper; + } } $export = apply_filters( 'pods_packages_export', $export, $params ); @@ -739,8 +1063,6 @@ public static function export( $params ) { return false; } - $export = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $export, JSON_UNESCAPED_UNICODE ) : json_encode( $export ); - - return $export; + return wp_json_encode( $export, JSON_PRETTY_PRINT ); } } diff --git a/components/Migrate-Packages/js/FileSaver.min.js b/components/Migrate-Packages/js/FileSaver.min.js new file mode 100644 index 0000000000..5cfb719849 --- /dev/null +++ b/components/Migrate-Packages/js/FileSaver.min.js @@ -0,0 +1,12 @@ + /* + * FileSaver.js + * A saveAs() FileSaver implementation. + * + * By Eli Grey, http://eligrey.com + * + * Version: 2.0.4 + * + * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT) + * source : http://purl.eligrey.com/github/FileSaver.js + */ +(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)}); diff --git a/components/Migrate-Packages/ui/wizard.php b/components/Migrate-Packages/ui/wizard.php index c6e71a6a5d..72dbc950b8 100644 --- a/components/Migrate-Packages/ui/wizard.php +++ b/components/Migrate-Packages/ui/wizard.php @@ -1,12 +1,13 @@
    -

    - + + + + +

    @@ -42,7 +43,7 @@
    -

    +

    @@ -50,7 +51,7 @@

    -

    +


    @@ -63,7 +64,7 @@

    -

    +


    @@ -77,16 +78,34 @@
    -

    +

    -

    +

    -
    +
    array( 'style' => 'width: 100%; max-width: 100%; height: 300px;' ) ) ); + echo PodsForm::label( 'import_package_file', __( 'Upload your pods-package.json', 'pods' ) ); + ?> + + +
    +
    + [ + 'style' => 'width: 100%; max-width: 100%; height: 250px;', + ], + 'disable_dfv' => true, + ] ); ?>
    @@ -95,7 +114,7 @@
    -

    +

    -

    - -

    -
    +

    + +

    +
    • - $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ) ) ); ?> + $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ), + 'disable_dfv' => true, + ] ); + ?>
    • -

      - -

      -
      +

      + +

      +
      • - $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ) ) ); ?> + $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ), + 'disable_dfv' => true, + ] ); + ?>
      • -

        - -

        -
        +

        + +

        +
        • - $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ) ) ); ?> + $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ), + 'disable_dfv' => true, + ] ); + ?>
        • -

          - -

          -
          +

          + +

          +
          • - $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ) ) ); ?> + $item['name'] . ( ! empty( $item['label'] ) ? ' (' . $item['label'] . ')' : '' ), + 'disable_dfv' => true, + ] ); + ?>
          -
          +
          - - + +
          @@ -293,13 +338,12 @@
          diff --git a/components/Pages.php b/components/Pages.php index 26f39ffc16..c424e44a19 100644 --- a/components/Pages.php +++ b/components/Pages.php @@ -241,7 +241,7 @@ public function setup_updated_messages( $messages ) { * @since 2.0.0 */ public function admin_assets() { - + wp_enqueue_script( 'pods-dfv' ); wp_enqueue_style( 'pods-styles' ); } @@ -417,6 +417,8 @@ public function add_meta_boxes() { return; } + add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ), 21 ); + if ( ! function_exists( 'get_page_templates' ) ) { include_once ABSPATH . 'wp-admin/includes/theme.php'; } @@ -515,14 +517,14 @@ public function add_meta_boxes() { $fields = array( array( 'name' => 'admin_only', - 'label' => __( 'Restrict access to Admins?', 'pods' ), + 'label' => __( 'Restrict access to Admins', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, ), array( 'name' => 'restrict_role', - 'label' => __( 'Restrict access by Role?', 'pods' ), + 'label' => __( 'Restrict access by Role', 'pods' ), 'help' => array( __( '
          Roles
          Roles are assigned to users to provide them access to specific functionality in WordPress. Please see the Roles and Capabilities component in Pods for an easy tool to add your own roles and edit existing ones.', 'pods' ), 'http://codex.wordpress.org/Roles_and_Capabilities', @@ -546,7 +548,7 @@ public function add_meta_boxes() { ), array( 'name' => 'restrict_capability', - 'label' => __( 'Restrict access by Capability?', 'pods' ), + 'label' => __( 'Restrict access by Capability', 'pods' ), 'help' => array( __( '
          Capabilities
          Capabilities denote access to specific functionality in WordPress, and are assigned to specific User Roles. Please see the Roles and Capabilities component in Pods for an easy tool to add your own capabilities and roles.', 'pods' ), 'http://codex.wordpress.org/Roles_and_Capabilities', @@ -570,7 +572,7 @@ public function add_meta_boxes() { ), array( 'name' => 'restrict_redirect', - 'label' => __( 'Redirect if Restricted?', 'pods' ), + 'label' => __( 'Redirect if Restricted', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, @@ -695,7 +697,7 @@ public static function flush_rewrites() { uksort( $pod_page_rewrites, 'pods_page_length_sort' ); - pods_transient_set( 'pods_object_page_rewrites', $pod_page_rewrites ); + pods_transient_set( 'pods_object_page_rewrites', $pod_page_rewrites, WEEK_IN_SECONDS ); $pod_page_rewrites = array_flip( $pod_page_rewrites ); @@ -712,20 +714,22 @@ public static function flush_rewrites() { * @return array|bool */ public static function exists( $uri = null ) { - if ( null === $uri ) { - $uri = parse_url( pods_current_url() ); - $uri = $uri['path']; - } else { - $uri = explode( '?', $uri ); - $uri = explode( '#', $uri[0] ); - $uri = $uri[0]; + $uri = pods_current_path(); + } + + if ( empty( $uri ) ) { + return false; } - $home = parse_url( get_home_url() ); + $uri = explode( '?', $uri ); + $uri = explode( '#', $uri[0] ); + $uri = $uri[0]; - if ( ! empty( $home ) && isset( $home['path'] ) && '/' !== $home['path'] ) { - $uri = substr( $uri, strlen( $home['path'] ) ); + $home_path = wp_parse_url( get_home_url(), PHP_URL_PATH ); + + if ( ! empty( $home_path ) && '/' !== $home_path ) { + $uri = substr( $uri, strlen( $home_path ) ); } $uri = trim( $uri, '/' ); @@ -985,7 +989,7 @@ public function precode() { } if ( false !== self::$exists ) { - $permission = pods_permission( self::$exists['options'] ); + $permission = pods_permission( self::$exists ); $permission = (boolean) apply_filters( 'pods_pages_permission', $permission, self::$exists ); @@ -1331,7 +1335,6 @@ function get_pod_page_uri() { * @since 1.7.5 */ function pod_page_exists( $uri = null ) { - return Pods_Pages::exists( $uri ); } diff --git a/components/Roles/Roles.php b/components/Roles/Roles.php index 72332a5d9c..649f286cff 100644 --- a/components/Roles/Roles.php +++ b/components/Roles/Roles.php @@ -83,8 +83,8 @@ public function admin( $options, $component ) { 'data' => $roles, 'total' => count( $roles ), 'total_found' => count( $roles ), - 'items' => 'Roles', - 'item' => 'Role', + 'items' => __( 'Roles', 'pods' ), + 'item' => __( 'Role', 'pods' ), 'fields' => array( 'manage' => array( 'label' => array( 'label' => __( 'Label', 'pods' ) ), @@ -95,7 +95,7 @@ public function admin( $options, $component ) { 'type' => 'text', 'options' => array( 'text_allow_html' => 1, - 'text_allowed_html_tags' => '', + 'text_allowed_html_tags' => 'strong em a ul ol li b i br', ), ), ), @@ -303,7 +303,7 @@ public function ajax_add( $params ) { return pods_error( __( 'Role label is required', 'pods' ) ); } - return add_role( $role_name, $role_label, $capabilities ); + return add_role( $role_name, $role_label, $capabilities ) instanceof WP_Role; } /** diff --git a/components/Roles/ui/add.php b/components/Roles/ui/add.php index ba32425064..ce74b0fcd6 100644 --- a/components/Roles/ui/add.php +++ b/components/Roles/ui/add.php @@ -1,7 +1,4 @@
          -

          @@ -41,19 +38,21 @@
          'pods-validate pods-validate-required' ) ); + echo PodsForm::field( 'role_label', pods_var_raw( 'role_label', 'post' ), 'text', [ + 'class' => 'pods-validate pods-validate-required', + 'disable_dfv' => true, + ] ); ?>
          array( 'data-sluggable' => 'role_label' ), - 'class' => 'pods-validate pods-validate-required pods-slugged-lower', - ) - ); + echo PodsForm::field( 'role_name', pods_var_raw( 'role_name', 'post' ), 'db', [ + 'attributes' => [ 'data-sluggable' => 'role_label' ], + 'class' => 'pods-validate pods-validate-required pods-slugged-lower', + 'disable_dfv' => true, + ] ); ?>
          @@ -70,11 +69,11 @@
          -

          - -

          -
          +

          + +

          +
          • - $capability ) ); ?> + $capability, + 'disable_dfv' => true, + ] ); ?>
            • - + true, + ] ); + ?>
            @@ -126,10 +136,10 @@
          -
          +
          - - + +
          diff --git a/components/Roles/ui/edit.php b/components/Roles/ui/edit.php index 4ba6093cb2..fad23f72ad 100644 --- a/components/Roles/ui/edit.php +++ b/components/Roles/ui/edit.php @@ -1,7 +1,4 @@
          -

          @@ -80,11 +77,11 @@
          -

          - -

          -
          +

          + +

          +
          • - $capability ) ); ?> + $capability, + 'disable_dfv' => true, + ] ); + ?>
            • - + true, + ] ); + ?>
            diff --git a/components/Templates/Templates.php b/components/Templates/Templates.php index b163867f90..05528cb266 100644 --- a/components/Templates/Templates.php +++ b/components/Templates/Templates.php @@ -211,7 +211,7 @@ public function setup_updated_messages( $messages ) { * @since 2.0.0 */ public function admin_assets() { - + wp_enqueue_script( 'pods-dfv' ); wp_enqueue_style( 'pods-styles' ); } @@ -363,17 +363,19 @@ public function add_meta_boxes() { return; } + add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ), 21 ); + $fields = array( array( 'name' => 'admin_only', - 'label' => __( 'Show to Admins Only?', 'pods' ), + 'label' => __( 'Show to Admins Only', 'pods' ), 'default' => 0, 'type' => 'boolean', 'dependency' => true, ), array( 'name' => 'restrict_capability', - 'label' => __( 'Restrict access by Capability?', 'pods' ), + 'label' => __( 'Restrict access by Capability', 'pods' ), 'help' => array( __( '
            Capabilities
            Capabilities denote access to specific functionality in WordPress, and are assigned to specific User Roles. Please see the Roles and Capabilities component in Pods for an easy tool to add your own capabilities and roles.', 'pods' ), 'http://codex.wordpress.org/Roles_and_Capabilities', @@ -397,7 +399,7 @@ public function add_meta_boxes() { ), array( 'name' => 'show_restrict_message', - 'label' => __( 'Show no access message?', 'pods' ), + 'label' => __( 'Show no access message', 'pods' ), 'default' => 1, 'type' => 'boolean', 'dependency' => true, @@ -528,7 +530,7 @@ public static function template( $template_name, $code = null, $obj = null, $dep $options = pods_v( 'options', $template ); - $permission = pods_permission( $options ); + $permission = pods_permission( $template ); $permission = (boolean) apply_filters( 'pods_templates_permission', $permission, $code, $template, $obj ); @@ -595,7 +597,6 @@ public static function template( $template_name, $code = null, $obj = null, $dep * @return mixed|string|void */ public static function do_template( $code, $obj = null ) { - if ( ! empty( $obj ) ) { self::$obj =& $obj; } else { diff --git a/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Front_End.php b/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Front_End.php index d6ff8713fc..3001c19a0e 100644 --- a/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Front_End.php +++ b/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Front_End.php @@ -26,7 +26,7 @@ class Pods_Templates_Auto_Template_Front_End { * * @since 2.7.25 */ - private $auto_pods = []; + private $auto_pods = array(); /** * Pods_Templates_Auto_Template_Front_End constructor. @@ -49,24 +49,36 @@ public function __construct() { * @since 2.6.6 */ public function hook_content() { - /** - * Allows plugin to append/replace the_excerpt. - * - * Default is false, set to true to enable. - */ - if ( ! defined( 'PFAT_USE_ON_EXCERPT' ) ) { - define( 'PFAT_USE_ON_EXCERPT', false ); - } - $possible_pods = $this->auto_pods(); + // Always register archive hooks. foreach ( $possible_pods as $pod_name => $pod ) { - $filter = $this->get_pod_filter( $pod_name ); + $filter = pods_v( 'archive_filter', $pod, '', true ); + if ( $filter ) { + $this->filtered_content[ $filter ] = 10.5; + } + } - $this->filtered_content[ $filter ] = 10.5; + // Optionally register single hook for current object. + $obj = get_queried_object(); + $pod = null; + switch ( true ) { + case $obj instanceof WP_Post: + $pod = $obj->post_type; + break; + case $obj instanceof WP_Term: + $pod = $obj->name; + break; + case $obj instanceof WP_User: + $pod = 'user'; + break; + } - if ( PFAT_USE_ON_EXCERPT && ! empty( $possible_pods[ $pod_name ]['type'] ) && 'post_type' === $possible_pods[ $pod_name ]['type'] ) { - $this->filtered_content['the_excerpt'] = 10; + if ( ! empty( $possible_pods[ $pod ] ) ) { + // No need to check for default hooks, this is already done in auto_pods(). + $filter = pods_v( 'single_filter', $possible_pods[ $pod ], '', true ); + if ( $filter ) { + $this->filtered_content[ $filter ] = 10.5; } } @@ -128,7 +140,7 @@ public function the_pods() { ); // cache the results. - pods_transient_set( $key, $the_pods ); + pods_transient_set( $key, $the_pods, WEEK_IN_SECONDS ); } @@ -259,7 +271,7 @@ public function auto_pods() { }//end foreach // cache the results. - pods_transient_set( $key, $auto_pods ); + pods_transient_set( $key, $auto_pods, WEEK_IN_SECONDS ); }//end if /** @@ -276,39 +288,6 @@ public function auto_pods() { $this->auto_pods = apply_filters( 'pods_pfat_auto_pods', $auto_pods ); return $this->auto_pods; - - } - - /** - * Get the filter used for a Pod. - * - * @param string $pod_name The pod name. - * - * @return string - * @since 1.7.2 - */ - public function get_pod_filter( $pod_name = '' ) { - $filter = 'the_content'; - - if ( ! $pod_name ) { - // Get the current post type. - $pod_name = $this->get_pod_name(); - } - - // Now use other methods in class to build array to search in/ use. - $possible_pods = $this->auto_pods(); - - if ( isset( $possible_pods[ $pod_name ] ) ) { - $this_pod = $possible_pods[ $pod_name ]; - - if ( in_the_loop() && ! is_singular() ) { - $filter = pods_v( 'archive_filter', $this_pod, $filter, true ); - } else { - $filter = pods_v( 'single_filter', $this_pod, $filter, true ); - } - } - - return $filter; } /** @@ -453,7 +432,7 @@ public function front( $content, $obj = null ) { } } - if ( $is_single && ( ! $in_the_loop || is_singular() ) ) { + if ( $is_single && ( ! $in_the_loop || is_singular( $pod_name ) ) ) { $type = 'single'; $type_filter = 'single_filter'; $type_append = 'single_append'; diff --git a/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Settings.php b/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Settings.php index 2b02960a86..22a3b2ec95 100644 --- a/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Settings.php +++ b/components/Templates/includes/auto-template/Pods_Templates_Auto_Template_Settings.php @@ -56,8 +56,8 @@ public function __construct() { // Include and init front-end class add_action( 'init', array( $this, 'front_end' ), 25 ); - // Delete transients when Pods settings are updated. - add_action( 'update_option', array( $this, 'reset' ), 21, 3 ); + // Delete transients when Pods cache is flushed. + add_action( 'pods_cache_flushed', array( $this, 'reseter' ) ); // admin notice for archives without archives add_action( 'admin_notices', array( $this, 'archive_warning' ) ); @@ -186,11 +186,13 @@ public function options( $options, $pod ) { 'type' => 'text', 'default' => false, 'depends-on' => array( 'pfat_enable' => true ), + 'dependency' => true, ), 'pfat_append_single' => array( 'label' => __( 'Singular Template Location', 'pods' ), 'help' => __( 'Whether the template will go before, after or in place of the existing content.', 'pods' ), 'depends-on' => array( 'pfat_enable' => true ), + 'excludes-on' => array( 'pfat_single' => '' ), ), 'pfat_filter_single' => array( 'label' => __( 'Singular Template Filter', 'pods' ), @@ -202,6 +204,7 @@ public function options( $options, $pod ) { 'custom' => __( 'Use a custom hook', 'pods' ), ), 'depends-on' => array( 'pfat_enable' => true ), + 'excludes-on' => array( 'pfat_single' => '' ), 'dependency' => true, ), 'pfat_filter_single_custom' => array( @@ -210,6 +213,7 @@ public function options( $options, $pod ) { 'default' => $default_single_hook_custom, 'type' => 'text', 'depends-on' => array( 'pfat_enable' => true, 'pfat_filter_single' => 'custom' ), + 'excludes-on' => array( 'pfat_single' => '' ), ), 'pfat_archive' => array( 'label' => __( 'List Template', 'pods' ), @@ -217,11 +221,13 @@ public function options( $options, $pod ) { 'type' => 'text', 'default' => false, 'depends-on' => array( 'pfat_enable' => true ), + 'dependency' => true, ), 'pfat_append_archive' => array( 'label' => __( 'List Template Location', 'pods' ), 'help' => __( 'Whether the template will go before, after or in place of the existing content.', 'pods' ), 'depends-on' => array( 'pfat_enable' => true ), + 'excludes-on' => array( 'pfat_archive' => '' ), ), 'pfat_filter_archive' => array( 'label' => __( 'List Template Filter', 'pods' ), @@ -233,6 +239,7 @@ public function options( $options, $pod ) { 'custom' => __( 'Use a custom hook', 'pods' ), ), 'depends-on' => array( 'pfat_enable' => true ), + 'excludes-on' => array( 'pfat_archive' => '' ), 'dependency' => true, ), 'pfat_filter_archive_custom' => array( @@ -241,6 +248,7 @@ public function options( $options, $pod ) { 'default' => $default_archive_hook_custom, 'type' => 'text', 'depends-on' => array( 'pfat_enable' => true, 'pfat_filter_archive' => 'custom' ), + 'excludes-on' => array( 'pfat_archive' => '' ), ), 'pfat_run_outside_loop' => array( 'label' => __( 'Run outside loop', 'pods' ), @@ -358,25 +366,6 @@ public function front_end( $load_in_admin = false ) { } - /** - * Reset the transients for front-end class when Pods are saved. - * - * @uses update_option hook - * - * @param string $option - * @param mixed $old_value - * @param mixed $value - * - * @since 2.5.5 - */ - public function reset( $option, $old_value, $value ) { - - if ( $option === '_transient_pods_flush_rewrites' ) { - $this->reseter(); - } - - } - /** * Delete transients that stores the settings. * @@ -384,7 +373,7 @@ public function reset( $option, $old_value, $value ) { */ public function reseter() { - $keys = array( 'pods_pfat_the_pods', 'pods_pfat_auto_pods', 'pods_pfat_archive_test' ); + $keys = array( '_pods_pfat_the_pods', 'pods_pfat_the_pods', 'pods_pfat_auto_pods', 'pods_pfat_archive_test' ); foreach ( $keys as $key ) { pods_transient_clear( $key ); } @@ -420,7 +409,7 @@ public function archive_test() { } } - pods_transient_set( $key, $archive_test ); + pods_transient_set( $key, $archive_test, WEEK_IN_SECONDS ); } diff --git a/components/Templates/includes/functions-pod_reference.php b/components/Templates/includes/functions-pod_reference.php index 23617f9f49..cc4152c55b 100644 --- a/components/Templates/includes/functions-pod_reference.php +++ b/components/Templates/includes/functions-pod_reference.php @@ -54,10 +54,6 @@ function pq_recurse_pod_fields( $pod_name, $prefix = '', &$pods_visited = array( $recurse_queue = array(); - foreach ( $pod->pod_data['object_fields'] as $name => $field ) { - // Add WordPress object fields - $fields[] = $prefix . $name; - } if ( post_type_supports( $pod_name, 'thumbnail' ) ) { $fields[] = "{$prefix}post_thumbnail"; $fields[] = "{$prefix}post_thumbnail_url"; @@ -67,7 +63,9 @@ function pq_recurse_pod_fields( $pod_name, $prefix = '', &$pods_visited = array( $fields[] = "{$prefix}post_thumbnail_url.{$size}"; } } + $pod_fields = $pod->fields(); + foreach ( $pod_fields as $name => $field ) { // Add base field name $fields[] = $prefix . $name; diff --git a/components/Templates/includes/functions-view_template.php b/components/Templates/includes/functions-view_template.php index 98b9f8a8f6..da9bab4294 100644 --- a/components/Templates/includes/functions-view_template.php +++ b/components/Templates/includes/functions-view_template.php @@ -83,42 +83,41 @@ function frontier_decode_template( $code, $atts ) { /** * processes if condition within a template * - * @param array $atts attributes from template + * @param array $attributes attributes from template * @param string $code encoded template to be decoded * * @return string * @since 2.4.0 */ -function frontier_if_block( $atts, $code ) { - - $pod = pods( $atts['pod'], $atts['id'] ); +function frontier_if_block( $attributes, $code ) { + $attributes = array_merge( [ + 'pod' => null, + 'id' => null, + 'field' => null, + 'value' => null, + 'compare' => null, + 'index' => null, + ], $attributes ); + + $pod = pods( $attributes['pod'], $attributes['id'] ); if ( ! $pod || ! $pod->valid() || ! $pod->exists() ) { return ''; } - $code = explode( '[else]', frontier_decode_template( $code, $atts ) ); - - // sysvals - $system_values = array( - '_index', - ); + $code = explode( '[else]', frontier_decode_template( $code, $attributes ) ); // field data $field_data = null; - $field_type = null; + $field_type = 'text'; - if ( in_array( $atts['field'], $system_values, true ) ) { - switch ( $atts['field'] ) { - case '_index': - $field_data = $atts['index']; - - break; + if ( ! empty( $attributes['field'] ) ) { + if ( '_index' === $attributes['field'] ) { + $field_data = pods_v( 'index', $attributes ); + } else { + $field_data = $pod->field( $attributes['field'] ); + $field_type = $pod->fields( $attributes['field'], 'type' ); } - } else { - $field_data = $pod->field( $atts['field'] ); - - $field_type = $pod->fields( $atts['field'], 'type' ); } $is_empty = true; @@ -131,56 +130,148 @@ function frontier_if_block( $atts, $code ) { $is_empty = PodsForm::field_method( $field_type, 'values_are_empty', $field_data ); } - $output = ''; + $has_value_compare_attribute = null !== $attributes['value'] || null !== $attributes['compare']; - if ( ! $is_empty || isset( $atts['value'] ) ) { - // theres a field - let go deeper - if ( isset( $atts['value'] ) ) { + if ( ! $is_empty || $has_value_compare_attribute ) { + // Check if we do not have a value to compare with. + if ( ! $has_value_compare_attribute ) { + // Field exists and is not empty, use [IF] content + $template = $pod->do_magic_tags( $code[0] ); - // check if + or - are present - if ( '+' === substr( $atts['value'], 0, 1 ) ) { - // is greater - $atts['value'] = (float) substr( $atts['value'], 1 ) + 1; + return frontier_do_shortcode( $template ); + } - if ( (float) $field_data > $atts['value'] ) { - // is greater - set it the same to allow - $atts['value'] = $field_data; - } - } elseif ( substr( $atts['value'], 0, 1 ) === '-' ) { - // is smaller - $atts['value'] = (float) substr( $atts['value'], 1 ) - 1; + $first_character = substr( $attributes['value'], 0, 1 ); + + // check if + or - are present + if ( '+' === $first_character ) { + // is greater + $attributes['value'] = (float) substr( $attributes['value'], 1 ) + 1; + $attributes['compare'] = '>'; + } elseif ( '-' === $first_character ) { + // is smaller + $attributes['value'] = (float) substr( $attributes['value'], 1 ) - 1; + $attributes['compare'] = '<'; + } - if ( (float) $field_data < $atts['value'] ) { - // is greater - set it the same to allow - $atts['value'] = $field_data; - } - } + if ( empty( $attributes['compare'] ) ) { + $attributes['compare'] = '='; + } + + $attributes['compare'] = html_entity_decode( $attributes['compare'] ); + $attributes['compare'] = strtoupper( $attributes['compare'] ); + + // Normalize the compare. + $comparisons = [ + '=', + '!=', + '>', + '>=', + '<', + '<=', + 'LIKE', + 'NOT LIKE', + 'EXISTS', + 'NOT EXISTS', + 'EMPTY', + 'NOT EMPTY', + ]; + + // Comparison not supported, assume it does not match. + if ( ! in_array( $attributes['compare'], $comparisons, true ) ) { + return ''; + } + + $pass = false; + + $maybe_array = is_array( $field_data ) || is_array( $attributes['value'] ); - if ( (string) $field_data === (string) $atts['value'] ) { - // IF statement true, use [IF] content as template - $template = $pod->do_magic_tags( $code[0] ); + // Handle comparison. + if ( '=' === $attributes['compare'] ) { + if ( $maybe_array ) { + $pass = $field_data === $attributes['value']; } else { - // No 'field' value (or value false), switch to [else] content - if ( isset( $code[1] ) ) { - // There is an [ELSE] tag - $template = $pod->do_magic_tags( $code[1] ); - } else { - // Value did not match (and no [ELSE]), nothing should be displayed - $template = ''; + $pass = (string) $field_data === (string) $attributes['value']; + } + } elseif ( '!=' === $attributes['compare'] ) { + if ( $maybe_array ) { + $pass = $field_data !== $attributes['value']; + } else { + $pass = (string) $field_data !== (string) $attributes['value']; + } + } elseif ( 'EXISTS' === $attributes['compare'] ) { + $pass = null !== $field_data && [] !== $field_data; + } elseif ( 'NOT EXISTS' === $attributes['compare'] ) { + $pass = null === $field_data || [] === $field_data; + } elseif ( $maybe_array ) { + // We do not support comparisons for array values beyond equals. + $pass = false; + } elseif ( '>' === $attributes['compare'] ) { + $pass = (float) $field_data > (float) $attributes['value']; + } elseif ( '>=' === $attributes['compare'] ) { + $pass = (float) $field_data >= (float) $attributes['value']; + } elseif ( '<' === $attributes['compare'] ) { + $pass = (float) $field_data < (float) $attributes['value']; + } elseif ( '<=' === $attributes['compare'] ) { + $pass = (float) $field_data <= (float) $attributes['value']; + } elseif ( 'LIKE' === $attributes['compare'] || 'NOT LIKE' === $attributes['compare'] ) { + $field_data = (string) $field_data; + + $attributes['value'] = (string) $attributes['value']; + + if ( false !== strpos( $attributes['value'], '%' ) ) { + // Handle % LIKE values. + $attributes['value'] = str_replace( '%', '.*', preg_quote( $attributes['value'], '/' ) ); + + $found = preg_match( '/^' . $attributes['value'] . '$/Uim', $field_data ); + + if ( 0 === $found ) { + $found = false; } + } else { + $found = stripos( $field_data, $attributes['value'] ); } - } else { - // Field exists and is not empty, use [IF] content + + if ( 'LIKE' === $attributes['compare'] ) { + // Check if the string contains the match. + $pass = false !== $found; + } elseif ( 'NOT LIKE' === $attributes['compare'] ) { + // Check if the string does not contain the match. + $pass = false === $found; + } + } elseif ( 'EMPTY' === $attributes['compare'] ) { + $pass = $is_empty; + } elseif ( 'NOT EMPTY' === $attributes['compare'] ) { + $pass = ! $is_empty; + } + + if ( $pass ) { + // IF statement true, use [IF] content as template. $template = $pod->do_magic_tags( $code[0] ); - }//end if - } elseif ( isset( $code[1] ) ) { - // No value or field is empty and there is an [ELSE] tag. Use [ELSE] + + return frontier_do_shortcode( $template ); + } + + if ( isset( $code[1] ) ) { + // There is an [ELSE] tag + $template = $pod->do_magic_tags( $code[1] ); + + return frontier_do_shortcode( $template ); + } + + // Value did not match (and no [ELSE]), nothing should be displayed. + return ''; + } + + if ( isset( $code[1] ) ) { + // No value or field is empty and there is an [ELSE] tag. Use [ELSE]. $template = $pod->do_magic_tags( $code[1] ); - } else { - $template = ''; - }//end if - return do_shortcode( $template ); + return frontier_do_shortcode( $template ); + } + + // No match at all for the format we support. + return ''; } /** @@ -268,13 +359,13 @@ function frontier_do_subtemplate( $atts, $content ) { $entries = $pod->field( $field_name ); - if ( ! empty( $entries ) ) { - $entries = (array) $entries; + $field = $pod->fields( $field_name ); - $field = $pod->fields[ $field_name ]; + if ( ! empty( $entries ) && $field ) { + $entries = (array) $entries; // Force array even for single items since the logic below is using loops. - if ( 'single' === pods_v( $field['type'] . '_format_type', $field['options'], 'single' ) && ! isset( $entries[0] ) ) { + if ( 'single' === pods_v( $field['type'] . '_format_type', $field, 'single' ) && ! isset( $entries[0] ) ) { $entries = array( $entries ); } @@ -292,13 +383,13 @@ function frontier_do_subtemplate( $atts, $content ) { * the $pod->fields array and is something to not expect to be there in * 3.0 as this was unintentional. */ - if ( in_array( $field['pick_object'], $object_types, true ) || 'taxonomy' == $field['type'] ) { + if ( 'taxonomy' === $field['type'] || in_array( $field['pick_object'], $object_types, true ) ) { // Match any Pod object or taxonomy foreach ( $entries as $key => $entry ) { $subpod = pods( $field['pick_val'] ); $subatts = array( - 'id' => $entry[ $subpod->api->pod_data['field_id'] ], + 'id' => $entry[ $subpod->pod_data['field_id'] ], 'pod' => $field['pick_val'], ); @@ -326,24 +417,28 @@ function frontier_do_subtemplate( $atts, $content ) { ); }//end foreach - } elseif ( 'file' == $field['type'] && 'attachment' == $field['options']['file_uploader'] ) { + } elseif ( 'file' === $field['type'] ) { $template = frontier_decode_template( $content, $atts ); $media_pod = pods( 'media' ); foreach ( $entries as $key => $entry ) { $content = str_replace( '{_index}', $key, $template ); - $content = str_replace( '{@_img', '{@image_attachment.' . $entry['ID'], $content ); - $content = str_replace( '{@_src', '{@image_attachment_url.' . $entry['ID'], $content ); - $content = str_replace( '{@' . $field_name . '}', '{@image_attachment.' . $entry['ID'] . '}', $content ); if ( $media_pod && $media_pod->valid() && $media_pod->fetch( $entry['ID'] ) ) { $content = str_replace( '{@' . $field_name . '.', '{@', $content ); + $entry_pod = $media_pod; } else { + $content = str_replace( '{@_img', '{@image_attachment.' . $entry['ID'], $content ); + $content = str_replace( '{@_src', '{@image_attachment_url.' . $entry['ID'], $content ); + $content = str_replace( '{@' . $field_name . '}', '{@image_attachment.' . $entry['ID'] . '}', $content ); + // Fix for lowercase ID's. $entry['id'] = $entry['ID']; + // Allow array-like tags. $content = frontier_pseudo_magic_tags( $content, $entry, $pod, true ); + // Fallback to parent Pod so above tags still work. $entry_pod = $pod; } @@ -509,65 +604,101 @@ function frontier_prefilter_template( $code, $template, $pod ) { $aliases = array(); foreach ( $commands as $command => $shortcode ) { - preg_match_all( '/(\[' . $command . '(.*?)]|\[\/' . $command . '\])/m', $code, $matches ); + //preg_match_all( '/(\[' . $command . '(?.*?)]|\[\/' . $command . '\])/m', $code, $matches ); + preg_match_all( '/(' + . '\[' . preg_quote( $command, '/' ) . '\s*' + . '(?field="(?[^"]*)")*' . '\s*' + . '(?value="(?[^"]*)")*' . '\s*' + . '(?compare="(?[^"]*)")*' . '\s*' + . '(?[^\]]*)' + . ']|\[\/' . preg_quote( $command, '/' ) . '\]' + . ')/m', $code, $matches ); + if ( ! empty( $matches[0] ) ) { - // holder for found blocks. - $blocks = array(); + // holder for found tags. + $tags = array(); $indexCount = 0; foreach ( $matches[0] as $key => $tag ) { - if ( false === strpos( $tag, '[/' ) ) { - // open tag - $field = null; - $value = null; - $ID = '{@EntryID}'; - $atts = ' pod="@pod" id="' . $ID . '"'; - if ( ! empty( $matches[2][ $key ] ) ) { - // get atts if any - // $atts = shortcode_parse_atts(str_replace('.', '____', $matches[2][$key])); - $atts = array(); - $pattern = '/(\w.+)\s*=\s*"([^"]*)"(?:\s|$)/'; - $text = preg_replace( "/[\x{00a0}\x{200b}]+/u", ' ', $matches[2][ $key ] ); - if ( preg_match_all( $pattern, $text, $match, PREG_SET_ORDER ) ) { - $field = $match[0][1]; - $value = $match[0][2]; - } else { - $field = trim( $matches[2][ $key ] ); - } - if ( false !== strpos( $field, '.' ) ) { - $path = explode( '.', $field ); - $field = array_pop( $path ); - $ID = '{@' . implode( '.', $path ) . '.' . $pod->api->pod_data['field_id'] . '}'; - } - $atts = ' id="' . $ID . '" pod="@pod" field="' . $field . '"'; - if ( ! empty( $value ) ) { - $atts .= ' value="' . $value . '"'; - } - }//end if - - $newtag = $shortcode . '__' . $key; - $tags[ $indexCount ] = $newtag; - $aliases[] = $newtag; - $code = preg_replace( '/(' . preg_quote( $tag ) . ')/m', '[' . $newtag . $atts . ' index="{_index}"]', $code, 1 ); - $indexCount ++; - } else { + if ( false !== strpos( $tag, '[/' ) ) { // close tag $indexCount --; $newclose = $tags[ $indexCount ]; $code = preg_replace( '/(' . preg_quote( $tag, '/' ) . ')/m', '[/' . $newclose . ']', $code, 1 ); + continue; }//end if + + // Handle open tags. + + $field = null; + $value = null; + $compare = null; + + $ID = '{@EntryID}'; + $atts = ' pod="{@pod}"'; + + if ( '' !== $matches['field_attr'][ $key ] ) { + $field = $matches['field'][ $key ]; + + if ( '' !== $matches['value_attr'][ $key ] ) { + $value = $matches['value'][ $key ]; + } + + if ( '' !== $matches['compare_attr'][ $key ] ) { + $compare = $matches['compare'][ $key ]; + } + } elseif ( '' !== $matches['other_attributes'][ $key ] ) { + // get atts if any + // $atts = shortcode_parse_atts(str_replace('.', '____', $matches[2][$key])); + $pattern = '/(?[\w\.]+)\s*=\s*"(?[^"]*)"(?:\s|$)/'; + $field = trim( $matches['other_attributes'][ $key ] ); + $text = preg_replace( "/[\x{00a0}\x{200b}]+/u", ' ', $field ); + + if ( preg_match_all( $pattern, $text, $field_value_match, PREG_SET_ORDER ) ) { + $field = $field_value_match[0]['field']; + $value = $field_value_match[0]['value']; + } + }//end if + + if ( $field && false !== strpos( $field, '.' ) && 0 !== strpos( $field, '_' ) ) { + // Take the last element off of the array and use the ID. + $path = explode( '.', $field ); + $field = array_pop( $path ); + + // Rebuild the ID used for the lookup. + $ID = '{@' . implode( '.', $path ) . '.' . $pod->pod_data['field_id'] . '}'; + } + + $atts .= ' id="' . esc_attr( $ID ) . '"'; + + if ( $field ) { + $atts .= ' field="' . esc_attr( $field ) . '"'; + } + + if ( null !== $value ) { + $atts .= ' value="' . esc_attr( $value ) . '"'; + } + + if ( null !== $compare ) { + $atts .= ' compare="' . esc_attr( $compare ) . '"'; + } + + $newtag = $shortcode . '__' . $key; + $tags[ $indexCount ] = $newtag; + $aliases[] = $newtag; + + $code = preg_replace( '/(' . preg_quote( $tag, '/' ) . ')/m', '[' . $newtag . $atts . ' index="{_index}"]', $code, 1 ); + + $indexCount ++; }//end foreach - if ( $command == 'if' ) { - // dump($pod); - } }//end if }//end foreach - // get new aliased shotcodes + // get new aliased shortcodes if ( ! empty( $aliases ) ) { $code = frontier_backtrack_template( $code, $aliases ); } - $code = str_replace( '@pod', $pod->pod, $code ); - $code = str_replace( '@EntryID', '@' . $pod->api->pod_data['field_id'], $code ); + $code = str_replace( '{@pod}', $pod->pod, $code ); + $code = str_replace( '{@EntryID}', '{@' . $pod->pod_data['field_id'] . '}', $code ); return $code; } diff --git a/composer.json b/composer.json index f0ac764ab2..b23d0ca214 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "issues": "https://github.com/pods-framework/pods/issues", "forum": "https://wordpress.org/support/plugin/pods", "source": "https://github.com/pods-framework/pods", - "docs": "https://pods.io/docs/" + "docs": "https://docs.pods.io/" }, "repositories": [ { @@ -49,20 +49,26 @@ ], "require": { "composer/installers": "1.12.*", - "php": ">=5.3", - "freemius/wordpress-sdk": "2.4.2" + "php": ">=5.6" }, "require-dev": { "automattic/vipwpcs": "^2.0", "bvanhoekelen/performance": "^2.5.1", + "codeception/codeception": "2.5.6", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "wp-coding-standards/wpcs": "^2.1", + "fzaninotto/faker": "^1.8", + "lucatume/function-mocker": "^1.3.8", + "lucatume/function-mocker-le": "^1.0.1", + "lucatume/wp-browser": "2.2.15", + "lucatume/wp-snaphot-assertions": "^1.0", "the-events-calendar/tribalscents": "dev-master", + "phpunit/phpunit": "6.5.14", + "spatie/phpunit-snapshot-assertions": "^1.4.2", "wp-cli/wp-cli": "2.*", - "phpunit/phpunit": "4.*", - "mockery/mockery": "1.3.*", - "phpcompatibility/php-compatibility": "9.*" + "wp-coding-standards/wpcs": "^2.1" }, + "minimum-stability": "stable", + "prefer-stable": true, "suggest": { "wp-cli/wp-cli": "Enables access to Pods CLI commands." }, diff --git a/deprecated/classes/Pods.php b/deprecated/classes/Pods.php index adad8e852b..db23354013 100644 --- a/deprecated/classes/Pods.php +++ b/deprecated/classes/Pods.php @@ -1,6 +1,8 @@ var_name $vars = get_object_vars( $obj ); @@ -47,7 +48,6 @@ public function __construct( $obj ) { * @since 1.2.0 */ public function set_field( $name, $data = null ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::set_field', '2.0' ); } @@ -67,7 +67,6 @@ public function set_field( $name, $data = null ) { * @param string $label */ public function showform( $id = null, $public_fields = null, $label = 'Save changes' ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::showform', '2.0' ); } @@ -106,16 +105,24 @@ public function showform( $id = null, $public_fields = null, $label = 'Save chan do_action( 'pods_showform_pre', $pod_id, $public_fields, $label, $this ); foreach ( $fields as $key => $field ) { - if ( ! is_array( $field ) || in_array( $key, array( 'created', 'modified' ), true ) ) { + $is_field_object = $field instanceof Field; + + if ( + ( + ! is_array( $field ) + && ! $is_field_object + ) + || in_array( $key, array( 'created', 'modified' ), true ) + ) { continue; } // Pass options so they can be manipulated via form - $field = array_merge( $field['options'], $field ); + $field = $field; // Replace field attributes with public form attributes if ( ! empty( $attributes ) && is_array( $attributes[ $key ] ) ) { - $field = array_merge( $field, $attributes[ $key ] ); + $field = pods_config_merge_data( $field, $attributes[ $key ] ); } // Replace the input helper name with the helper code @@ -234,7 +241,6 @@ public function showform( $id = null, $public_fields = null, $label = 'Save chan $result = pods_query( $sql, $this ); if ( ! empty( $result ) ) { - $exclude = array(); foreach ( $result as $row ) { @@ -314,7 +320,6 @@ public function showform( $id = null, $public_fields = null, $label = 'Save chan * @return array */ public function get_dropdown_values( $params ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::get_dropdown_values', '2.0' ); } @@ -376,7 +381,6 @@ public function get_dropdown_values( $params ) { * @param null $thankyou_url */ public function publicForm( $fields = null, $label = 'Save Changes', $thankyou_url = null ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::publicForm', '2.0', 'Pods::form' ); } @@ -386,20 +390,20 @@ public function publicForm( $fields = null, $label = 'Save Changes', $thankyou_u foreach ( $fields as $k => $field ) { $name = $k; - if ( ! is_array( $field ) ) { + $is_field_object = $field instanceof Field; + + if ( ! is_array( $field ) && ! $is_field_object ) { $name = $field; $field = array(); } elseif ( isset( $field['name'] ) ) { $name = $field['name']; } - if ( in_array( - $name, array( + if ( in_array( $name, array( 'created', 'modified', 'author', - ), true - ) && isset( $this->obj->fields[ $name . '2' ] ) ) { + ), true ) && isset( $this->obj->fields[ $name . '2' ] ) ) { $name .= '2'; } @@ -420,7 +424,6 @@ public function publicForm( $fields = null, $label = 'Save Changes', $thankyou_u * @param array $field Field data. */ public function build_field_html( $field ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::build_field_html', '2.0' ); } @@ -435,7 +438,6 @@ public function build_field_html( $field ) { * @deprecated 2.0.0 */ public function fetchRecord() { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::fetchRecord', '2.0', 'Pods::fetch' ); } @@ -454,18 +456,15 @@ public function fetchRecord() { * @return array|mixed */ public function get_field( $name, $orderby = null ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::get_field', '2.0', 'Pods::field' ); } - $value = $this->obj->field( - array( + $value = $this->obj->field( array( 'name' => $name, 'orderby' => $orderby, 'deprecated' => true, - ) - ); + ) ); if ( is_array( $value ) && ! empty( $value ) ) { if ( false === strpos( $name, '.' ) && ! isset( $value[0] ) ) { @@ -487,7 +486,6 @@ public function get_field( $name, $orderby = null ) { * @deprecated 2.0.0 */ public function get_pod_id() { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::get_pod_id', '2.0' ); } @@ -502,7 +500,7 @@ public function get_pod_id() { /** * Search and filter records * - * @since 1.x.x + * @since 1.x.x * @deprecated 2.0.0 * * @param null $orderby @@ -513,7 +511,6 @@ public function get_pod_id() { * @return */ public function findRecords( $orderby = null, $rows_per_page = 15, $where = null, $sql = null ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::findRecords', '2.0', 'Pods::find' ); } @@ -588,7 +585,7 @@ public function findRecords( $orderby = null, $rows_per_page = 15, $where = null /** * Return a single record * - * @since 1.x.x + * @since 1.x.x * @deprecated 2.0.0 * * @param int $id Item ID. @@ -596,7 +593,6 @@ public function findRecords( $orderby = null, $rows_per_page = 15, $where = null * @return */ public function getRecordById( $id ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::getRecordById', '2.0', 'Pods::fetch_item' ); } @@ -610,7 +606,6 @@ public function getRecordById( $id ) { * @deprecated 2.0.0 */ public function getTotalRows() { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::getTotalRows', '2.0', 'Pods::total_found' ); } @@ -628,7 +623,6 @@ public function getTotalRows() { * @return */ public function resetPointer( $row_number = 0 ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::resetPointer', '2.0', 'Pods::reset' ); } @@ -644,17 +638,14 @@ public function resetPointer( $row_number = 0 ) { * @param string $label */ public function getPagination( $label = 'Go to page:' ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::getPagination', '2.0', 'Pods::pagination' ); } - echo $this->obj->pagination( - array( + echo $this->obj->pagination( array( 'type' => 'advanced', 'label' => $label, - ) - ); + ) ); } /** @@ -667,7 +658,6 @@ public function getPagination( $label = 'Go to page:' ) { * @param string $action */ public function getFilters( $filters = null, $label = 'Filter', $action = '' ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::getFilters', '2.0', 'Pods::filters' ); } @@ -699,7 +689,6 @@ public function getFilters( $filters = null, $label = 'Filter', $action = '' ) { * @deprecated 2.0.0 */ public function pod_helper( $helper_name, $value = null, $name = null ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::pod_helper', '2.0', 'Pods::helper' ); } @@ -725,7 +714,6 @@ public function pod_helper( $helper_name, $value = null, $name = null ) { * @return */ public function showTemplate( $template_name, $code = null ) { - if ( Pod::$deprecated_notice ) { pods_deprecated( 'Pods::showTemplate', '2.0', 'Pods::template' ); } diff --git a/deprecated/classes/PodsAPI.php b/deprecated/classes/PodsAPI.php index cc954f799a..78b5bc0c48 100644 --- a/deprecated/classes/PodsAPI.php +++ b/deprecated/classes/PodsAPI.php @@ -24,10 +24,9 @@ class PodsAPI_Deprecated { * @param object $obj The PodsAPI object * * @license http://www.gnu.org/licenses/gpl-2.0.html - * @since 2.0.0 + * @since 2.0.0 */ public function __construct( $obj ) { - // backwards-compatibility with references to $this->var_name $vars = get_object_vars( $obj ); @@ -59,7 +58,6 @@ public function __construct( $obj ) { * @since 1.7.9 */ public function save_column( $params ) { - pods_deprecated( 'PodsAPI::save_field', '2.0' ); return $this->obj->save_field( $params ); @@ -74,7 +72,6 @@ public function save_column( $params ) { * @return bool */ public function save_roles( $params ) { - pods_deprecated( '[use WP roles and capabilities instead]', '2.0' ); return false; @@ -91,7 +88,6 @@ public function save_roles( $params ) { * @since 1.7.9 */ public function drop_pod( $params ) { - pods_deprecated( 'PodsAPI::delete_pod', '2.0' ); return $this->obj->delete_pod( $params ); @@ -110,7 +106,6 @@ public function drop_pod( $params ) { * @since 1.7.9 */ public function drop_column( $params ) { - pods_deprecated( 'PodsAPI::delete_field', '2.0' ); return $this->obj->delete_field( $params ); @@ -127,7 +122,6 @@ public function drop_column( $params ) { * @since 1.7.9 */ public function drop_template( $params ) { - pods_deprecated( 'PodsAPI::delete_template', '2.0' ); return $this->obj->delete_template( $params ); @@ -144,7 +138,6 @@ public function drop_template( $params ) { * @since 1.7.9 */ public function drop_page( $params ) { - pods_deprecated( 'PodsAPI::delete_page', '2.0' ); return $this->obj->delete_page( $params ); @@ -161,7 +154,6 @@ public function drop_page( $params ) { * @since 1.7.9 */ public function drop_helper( $params ) { - pods_deprecated( 'PodsAPI::delete_helper', '2.0' ); return $this->obj->delete_helper( $params ); @@ -180,7 +172,6 @@ public function drop_helper( $params ) { * @since 1.7.9 */ public function drop_pod_item( $params ) { - pods_deprecated( 'PodsAPI::delete_pod_item', '2.0' ); return $this->obj->delete_pod_item( $params ); @@ -198,7 +189,6 @@ public function drop_pod_item( $params ) { * @since 1.7.9 */ public function load_column( $params ) { - pods_deprecated( 'PodsAPI::load_column', '2.0', 'PodsAPI::load_field' ); return $this->obj->load_field( $params ); diff --git a/deprecated/deprecated.php b/deprecated/deprecated.php index 9a7f4c69e4..93e577f576 100644 --- a/deprecated/deprecated.php +++ b/deprecated/deprecated.php @@ -17,7 +17,6 @@ * @return mixed */ function json_encode( $str ) { - $json = new Moxiecode_JSON(); return $json->encode( $str ); @@ -29,7 +28,6 @@ function json_encode( $str ) { * @return mixed */ function json_decode( $str ) { - $json = new Moxiecode_JSON(); return $json->decode( $str ); @@ -42,7 +40,6 @@ function json_decode( $str ) { * @param array $response Response data. */ function wp_send_json( $response ) { - @header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) ); echo json_encode( $response ); if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { @@ -66,7 +63,6 @@ function wp_send_json( $response ) { * @return mixed|void */ function get_current_url() { - $url = pods_current_url(); return apply_filters( 'get_current_url', $url ); @@ -76,7 +72,7 @@ function get_current_url() { /** * Mapping function to new function name (following normalization of function names from pod_ to pods_) * - * @since 1.x.x + * @since 1.x.x * @deprecated 2.0.0 * * @param string $sql SQL query. @@ -87,7 +83,6 @@ function get_current_url() { * @return array|bool|mixed|null|void Result of the query */ function pod_query( $sql, $error = 'SQL failed', $results_error = null, $no_results_error = null ) { - pods_deprecated( 'pod_query', '2.0', 'pods_query' ); global $wpdb; @@ -111,7 +106,7 @@ function pod_query( $sql, $error = 'SQL failed', $results_error = null, $no_resu /** * Include and Init the Pods class * - * @since 1.x.x + * @since 1.x.x * @deprecated 2.0.0 * @package Pods\Deprecated */ @@ -138,7 +133,6 @@ class Pod { * @param null $id */ public function __construct( $type = null, $id = null ) { - if ( self::$deprecated_notice ) { pods_deprecated( 'PodAPI (class)', '2.0', 'pods_api (function)' ); } @@ -158,7 +152,6 @@ public function __construct( $type = null, $id = null ) { * @return array|bool|int|mixed|PodsData */ public function __get( $name ) { - $name = (string) $name; if ( 'data' === $name ) { @@ -205,7 +198,6 @@ public function __get( $name ) { * @return mixed */ public function __set( $name, $value ) { - $name = (string) $name; $this->new->{$name} = $value; @@ -224,7 +216,6 @@ public function __set( $name, $value ) { * @return mixed */ public function __call( $name, $args ) { - $name = (string) $name; return call_user_func_array( array( $this->new, $name ), $args ); @@ -240,7 +231,6 @@ public function __call( $name, $args ) { * @return bool */ public function __isset( $name ) { - $name = (string) $name; if ( in_array( $name, array( '_data', 'data', 'total', 'total_rows', 'zebra' ), true ) ) { @@ -256,7 +246,7 @@ public function __isset( $name ) { /** * Include and Init the PodsAPI class * - * @since 1.x.x + * @since 1.x.x * @deprecated 2.0.0 * @package Pods\Deprecated */ @@ -273,7 +263,6 @@ class PodAPI { * @param null $format */ public function __construct( $type = null, $format = null ) { - if ( self::$deprecated_notice ) { pods_deprecated( 'PodAPI (class)', '2.0', 'pods_api (function)' ); } @@ -291,7 +280,6 @@ public function __construct( $type = null, $format = null ) { * @return null|mixed */ public function __get( $name ) { - $name = (string) $name; $var = $this->new->{$name}; @@ -310,7 +298,6 @@ public function __get( $name ) { * @return mixed */ public function __call( $name, $args ) { - $name = (string) $name; return call_user_func_array( array( $this->new, $name ), $args ); @@ -320,7 +307,7 @@ public function __call( $name, $args ) { /** * Include and Init the PodsUI class * - * @since 2.0.0 + * @since 2.0.0 * @deprecated 2.0.0 * * @param Pods $obj Pods object. @@ -328,7 +315,6 @@ public function __call( $name, $args ) { * @return PodsUI */ function pods_ui_manage( $obj ) { - pods_deprecated( 'pods_ui_manage', '2.0', 'pods_ui' ); return pods_ui( $obj, true ); @@ -337,7 +323,7 @@ function pods_ui_manage( $obj ) { /** * Limit Access based on Field Value * - * @since 1.x.x + * @since 1.x.x * @deprecated 2.0.0 * * @param Pods $object Pods object. @@ -347,7 +333,6 @@ function pods_ui_manage( $obj ) { * @return bool */ function pods_ui_access( $object, $access, $what ) { - pods_deprecated( 'pods_ui_access', '2.0' ); if ( is_array( $access ) ) { foreach ( $access as $field => $match ) { @@ -381,7 +366,6 @@ function pods_ui_access( $object, $access, $what ) { * @deprecated 2.0.0 */ function pods_url_variable( $key = 'last', $type = 'url' ) { - $output = apply_filters( 'pods_url_variable', pods_var( $key, $type ), $key, $type ); return $output; @@ -401,7 +385,6 @@ function pods_url_variable( $key = 'last', $type = 'url' ) { * @return mixed|string|void */ function pods_generate_key( $datatype, $uri_hash, $columns, $form_count = 1 ) { - $token = wp_create_nonce( 'pods-form-' . $datatype . '-' . (int) $form_count . '-' . $uri_hash . '-' . json_encode( $columns ) ); $token = apply_filters( 'pods_generate_key', $token, $datatype, $uri_hash, $columns, (int) $form_count ); $_SESSION[ 'pods_form_' . $token ] = $columns; @@ -424,7 +407,6 @@ function pods_generate_key( $datatype, $uri_hash, $columns, $form_count = 1 ) { * @return mixed|void */ function pods_validate_key( $token, $datatype, $uri_hash, $columns = null, $form_count = 1 ) { - if ( null === $columns && ! empty( $_SESSION ) && isset( $_SESSION[ 'pods_form_' . $token ] ) ) { $columns = $_SESSION[ 'pods_form_' . $token ]; } @@ -448,7 +430,6 @@ function pods_validate_key( $token, $datatype, $uri_hash, $columns = null, $form * @deprcated 2.3 */ function pods_ui_message( $message, $error = false ) { - pods_deprecated( 'pods_message', '2.3' ); pods_message( $message, ( $error ? 'error' : 'notice' ) ); @@ -465,7 +446,6 @@ function pods_ui_message( $message, $error = false ) { * @deprcated 2.3 */ function pods_ui_error( $message ) { - pods_deprecated( 'pods_message', '2.3' ); pods_message( $message, 'error' ); @@ -482,7 +462,6 @@ function pods_ui_error( $message ) { * @return int|string */ function pods_point_to_version( $point ) { - $version_tmp = explode( '.', $point ); $version = ''; @@ -519,7 +498,6 @@ function pods_point_to_version( $point ) { * @return array|string */ function pods_version_to_point( $version ) { - $point_tmp = $version; if ( strlen( $point_tmp ) < 9 ) { diff --git a/deprecated/list_filters.php b/deprecated/list_filters.php index c863ef0903..0877e92715 100644 --- a/deprecated/list_filters.php +++ b/deprecated/list_filters.php @@ -5,27 +5,30 @@ $filters = explode( ',', $filters ); } foreach ( $filters as $field_name ) { - $field = $this->api->load_column( - array( - 'name' => $field_name, - 'pod' => $this->pod, - ) - ); + $field = $this->api->load_column( array( + 'name' => $field_name, + 'pod' => $this->pod, + ) ); + if ( empty( $field ) ) { continue; } + if ( 'pick' === $field['type'] && ! empty( $field['pick_object'] ) ) { $pick_object = $field['pick_object']; $pick_val = $field['pick_val']; + if ( 'pod' === $pick_object ) { $pick_pod = $this->api->load_pod( array( 'name' => $pick_val ) ); $pick_object = $pick_pod['type']; $pick_val = $pick_pod['object']; } + $pick_table = ''; $pick_join = ''; $pick_where = ''; $pick_column_id = 'id'; + switch ( $pick_object ) { case 'pod': $pick_table = "@wp_pods_{$pick_val}"; @@ -56,6 +59,7 @@ $pick_column_id = 'id'; break; }//end switch + $pick_params = array( 'selected_ids' => $selected_ids, 'table' => $pick_table, @@ -65,8 +69,10 @@ 'orderby' => $field['options']['pick_orderby'], 'where' => $pick_where, ); + $field_data = $this->get_dropdown_values( $pick_params ); $field_label = ucwords( str_replace( '_', ' ', $field_name ) ); + if ( 0 < strlen( $row['label'] ) ) { $field_label = $row['label']; } diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 411bc47450..6840808613 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -22,6 +22,16 @@ When contributing please ensure you follow the guidelines below so that we can k At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary. +## Tribe Common + +In Pods 2.8, we included the [Tribe Common](https://github.com/the-events-calendar/tribe-common) library which helps to power The Events Calendar and Event Tickets. It has many positive benefits as there are some great potential areas for reducing overall needs of custom code that has to be unique to each plugin. + +### Including Common + +For Pods, we will take the "shipped" version of [Tribe Common](https://github.com/the-events-calendar/tribe-common) that comes within The Events Calendar or Event Tickets (whichever is newest at the time). This involves opening up the plugin's zip and pulling out the entire "common" folder. + +This is the preferred way to handle dependencies. When using a composer requirement, certain dependencies like Tribe Common have their own dependencies, and some require additional build steps that Pods does not automate. Everything in the Pods GitHub repository is pre-built, meaning you can include it without running anything else. This is preferred as many users will download release ZIPs of certain release branches. + # Additional Resources * [General GitHub documentation](https://help.github.com/) * [GitHub pull request documentation](https://help.github.com/send-pull-requests/) diff --git a/docs/release-workflow.md b/docs/release-workflow.md index 6858df95ff..6279bb236d 100644 --- a/docs/release-workflow.md +++ b/docs/release-workflow.md @@ -13,9 +13,13 @@ Next you'll install the packages for this repo using: `npm install` ## Version Changes -* Set new version in `package.json` (it might be something like `1.2.3-a-1`, so set it to `1.2.3`) -* Run the `version_number` task using `npm run version_number` -* _TODO: Would be great if running `npm run version_number` would ask for the version number to save a step_ +* Run the `version_number` task using `npm run version_number -- --ver=1.2.3-a-1` or set it in `package.json` and run it without parameters. +* Commit / merge changes into `release/x.x.x` branch + +## Asset Build for Production + +* Run `npm run build-production` to ensure assets will be built and minimized correctly +* Commit / merge changes into `release/x.x.x` branch ## Release diff --git a/includes/classes.php b/includes/classes.php index b72c69b9ab..2c8207abf1 100644 --- a/includes/classes.php +++ b/includes/classes.php @@ -1,7 +1,9 @@ data returns a reference and has a circular reference to Pod + return new PodsData( clone $pod->pod_data, $id, $strict ); + } - require_once PODS_DIR . 'classes/PodsData.php'; + if ( ! in_array( $pod, array( null, false ), true ) ) { + return new PodsData( $pod, $id, $strict ); + } - if ( $unique && false !== $pod ) { - return new PodsData( $pod, $id, $strict ); + return new PodsData; } return PodsData::init( $pod, $id, $strict ); @@ -108,9 +109,6 @@ function pods_data( $pod = null, $id = null, $strict = true, $unique = true ) { * @since 2.0.0 */ function pods_form() { - - require_once PODS_DIR . 'classes/PodsForm.php'; - return PodsForm::init(); } @@ -124,9 +122,6 @@ function pods_form() { * @since 2.0.0 */ function pods_init() { - - require_once PODS_DIR . 'classes/PodsInit.php'; - return PodsInit::init(); } @@ -140,10 +135,6 @@ function pods_init() { * @since 2.0.0 */ function pods_components() { - - require_once PODS_DIR . 'classes/PodsComponents.php'; - require_once PODS_DIR . 'classes/PodsComponent.php'; - return PodsComponents::init(); } @@ -157,9 +148,6 @@ function pods_components() { * @since 2.0.0 */ function pods_admin() { - - require_once PODS_DIR . 'classes/PodsAdmin.php'; - return PodsAdmin::init(); } @@ -173,9 +161,6 @@ function pods_admin() { * @since 2.0.0 */ function pods_meta() { - - require_once PODS_DIR . 'classes/PodsMeta.php'; - return PodsMeta::init(); } @@ -191,9 +176,6 @@ function pods_meta() { * @since 2.0.0 */ function pods_array( $container ) { - - require_once PODS_DIR . 'classes/PodsArray.php'; - return new PodsArray( $container ); } @@ -201,9 +183,6 @@ function pods_array( $container ) { * @since 2.7.0 */ function pods_i18n() { - - require_once PODS_DIR . 'classes/PodsI18n.php'; - return PodsI18n::get_instance(); } @@ -222,12 +201,9 @@ function pods_i18n() { * @return string|bool The view output * * @since 2.0.0 - * @link https://pods.io/docs/pods-view/ + * @link https://docs.pods.io/code/pods-view/ */ function pods_view( $view, $data = null, $expires = false, $cache_mode = 'cache', $return = false ) { - - require_once PODS_DIR . 'classes/PodsView.php'; - $view = PodsView::view( $view, $data, $expires, $cache_mode ); if ( $return ) { @@ -251,9 +227,6 @@ function pods_view( $view, $data = null, $expires = false, $cache_mode = 'cache' * @since 2.2.0 */ function pods_migrate( $type = null, $delimiter = null, $data = null ) { - - require_once PODS_DIR . 'classes/PodsMigrate.php'; - return new PodsMigrate( $type, $delimiter, $data ); } @@ -269,7 +242,6 @@ function pods_migrate( $type = null, $delimiter = null, $data = null ) { * @since 2.1.0 */ function pods_upgrade( $version = '' ) { - include_once PODS_DIR . 'sql/upgrade/PodsUpgrade.php'; $class_name = str_replace( '.', '_', $version ); diff --git a/includes/data.php b/includes/data.php index d32ef93536..823a9eb684 100644 --- a/includes/data.php +++ b/includes/data.php @@ -15,7 +15,6 @@ * @see wp_slash */ function pods_sanitize( $input, $params = array() ) { - if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } @@ -69,7 +68,6 @@ function pods_sanitize( $input, $params = array() ) { }//end if return $output; - } /** @@ -84,7 +82,6 @@ function pods_sanitize( $input, $params = array() ) { * @see like_escape */ function pods_sanitize_like( $input ) { - if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } @@ -111,7 +108,6 @@ function pods_sanitize_like( $input ) { } return $output; - } /** @@ -127,7 +123,6 @@ function pods_sanitize_like( $input ) { * @see wp_slash */ function pods_slash( $input, $params = array() ) { - if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } @@ -175,7 +170,6 @@ function pods_slash( $input, $params = array() ) { }//end if return $output; - } /** @@ -189,7 +183,6 @@ function pods_slash( $input, $params = array() ) { * @since 1.2.0 */ function pods_unsanitize( $input, $params = array() ) { - if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } @@ -221,7 +214,6 @@ function pods_unsanitize( $input, $params = array() ) { }//end if return $output; - } /** @@ -236,7 +228,6 @@ function pods_unsanitize( $input, $params = array() ) { * @see wp_unslash */ function pods_unslash( $input ) { - if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } @@ -262,7 +253,6 @@ function pods_unslash( $input ) { } return $output; - } /** @@ -275,8 +265,7 @@ function pods_unslash( $input ) { * @return array|object|string * @since 1.2.0 */ -function pods_trim( $input, $charlist = null, $lr = null ) { - +function pods_trim( $input, $charlist = " \t\n\r\0\x0B", $lr = null ) { $output = array(); if ( is_object( $input ) ) { @@ -307,7 +296,6 @@ function pods_trim( $input, $charlist = null, $lr = null ) { }//end if return $output; - } /** @@ -367,7 +355,6 @@ function pods_traverse( $traverse, $value ) { * @since 2.3.10 */ function pods_v( $var = null, $type = 'get', $default = null, $strict = false, $params = array() ) { - $defaults = array( 'casting' => false, 'allowed' => null, @@ -612,7 +599,7 @@ function pods_v( $var = null, $type = 'get', $default = null, $strict = false, $ $output = $wpdb->prefix; break; case 'server': - if ( ! pods_strict() ) { + if ( ! pods_strict( false ) ) { if ( isset( $_SERVER[ $var ] ) ) { $output = pods_unslash( $_SERVER[ $var ] ); } elseif ( isset( $_SERVER[ strtoupper( $var ) ] ) ) { @@ -911,13 +898,11 @@ function pods_v( $var = null, $type = 'get', $default = null, $strict = false, $ * @see pods_v */ function pods_v_sanitized( $var = null, $type = 'get', $default = null, $strict = false, $params = array() ) { - $output = pods_v( $var, $type, $default, $strict, $params ); $output = pods_sanitize( $output, $params ); return $output; - } /** @@ -933,7 +918,6 @@ function pods_v_sanitized( $var = null, $type = 'get', $default = null, $strict * @since 2.3.10 */ function pods_v_set( $value, $var, $type = 'get' ) { - $ret = false; if ( null === $var || '' === $var ) { @@ -1021,12 +1005,10 @@ function pods_v_set( $value, $var, $type = 'get' ) { $user->set_role( $value ); } elseif ( isset( $user_data[ $var ] ) ) { // Core field - wp_update_user( - array( + wp_update_user( array( 'ID' => $user->ID, $var => $value, - ) - ); + ) ); } else { // Meta field update_user_meta( $user->ID, $var, $value ); @@ -1048,7 +1030,6 @@ function pods_v_set( $value, $var, $type = 'get' ) { }//end if return $ret; - } /** @@ -1070,25 +1051,19 @@ function pods_v_set( $value, $var, $type = 'get' ) { * @see pods_v_sanitized */ function pods_var( $var = 'last', $type = 'get', $default = null, $allowed = null, $strict = false, $casting = false, $context = 'display' ) { - if ( 'raw' === $context ) { - $output = pods_v( - $var, $type, $default, $strict, array( + $output = pods_v( $var, $type, $default, $strict, array( 'allowed' => $allowed, 'casting' => $casting, - ) - ); + ) ); } else { - $output = pods_v_sanitized( - $var, $type, $default, $strict, array( + $output = pods_v_sanitized( $var, $type, $default, $strict, array( 'allowed' => $allowed, 'casting' => $casting, - ) - ); + ) ); } return $output; - } /** @@ -1103,20 +1078,16 @@ function pods_var( $var = 'last', $type = 'get', $default = null, $allowed = nul * @param bool $casting (optional) Whether to cast the value returned like provided in $default * * @return mixed The variable (if exists), or default value - * @since 2.0.0 + * @since 2.0.0 * * @deprecated 2.4.0 Use pods_v() instead. * @see pods_v */ function pods_var_raw( $var = 'last', $type = 'get', $default = null, $allowed = null, $strict = false, $casting = false ) { - - return pods_v( - $var, $type, $default, $strict, array( + return pods_v( $var, $type, $default, $strict, array( 'allowed' => $allowed, 'casting' => $casting, - ) - ); - + ) ); } /** @@ -1133,9 +1104,7 @@ function pods_var_raw( $var = 'last', $type = 'get', $default = null, $allowed = * @see pods_v_set */ function pods_var_set( $value, $var = 'last', $type = 'url' ) { - return pods_v_set( $value, $var, $type ); - } /** @@ -1153,7 +1122,6 @@ function pods_var_set( $value, $var = 'last', $type = 'url' ) { * @see add_query_arg */ function pods_query_arg( $array = null, $allowed = null, $excluded = null, $url = null ) { - $array = (array) $array; $allowed = (array) $allowed; $excluded = (array) $excluded; @@ -1181,13 +1149,13 @@ function pods_query_arg( $array = null, $allowed = null, $excluded = null, $url foreach ( $query_args as $key => $val ) { if ( is_array( $val ) && empty( $val ) ) { $query_args[ $key ] = false; - } elseif ( ! is_array( $val ) && strlen( $val ) < 1 ) { + } elseif ( ! is_array( $val ) && '' === $val ) { $query_args[ $key ] = false; } elseif ( ! empty( $allowed ) ) { $allow_it = false; foreach ( $allowed as $allow ) { - if ( $allow == $key ) { + if ( $allow === $key ) { $allow_it = true; } elseif ( false !== strpos( $allow, '*' ) && 0 === strpos( $key, trim( $allow, '*' ) ) ) { $allow_it = true; @@ -1215,7 +1183,7 @@ function pods_query_arg( $array = null, $allowed = null, $excluded = null, $url $query_args[ $key ] = $val; } elseif ( ! is_array( $val ) && 0 < strlen( $val ) ) { $query_args[ $key ] = $val; - } elseif ( isset( $query_args[ $key ] ) ) { + } else { $query_args[ $key ] = false; } } else { @@ -1237,7 +1205,6 @@ function pods_query_arg( $array = null, $allowed = null, $excluded = null, $url } return $url; - } /** @@ -1250,15 +1217,13 @@ function pods_query_arg( $array = null, $allowed = null, $excluded = null, $url * * @return mixed * - * @since 2.0.0 + * @since 2.0.0 * * @deprecated 2.4.0 Use pods_query_arg() instead. * @see pods_query_arg */ function pods_var_update( $array = null, $allowed = null, $excluded = null, $url = null ) { - return pods_query_arg( $array, $allowed, $excluded, $url ); - } /** @@ -1272,7 +1237,6 @@ function pods_var_update( $array = null, $allowed = null, $excluded = null, $url * @since 2.0.0 */ function pods_cast( $value, $cast_from = null ) { - if ( null !== $cast_from ) { if ( is_object( $value ) && is_array( $cast_from ) ) { $value = get_object_vars( $value ); @@ -1284,7 +1248,6 @@ function pods_cast( $value, $cast_from = null ) { } return $value; - } /** @@ -1298,7 +1261,6 @@ function pods_cast( $value, $cast_from = null ) { * @since 1.8.9 */ function pods_create_slug( $orig, $strict = true ) { - $str = preg_replace( '/([_ \\/])/', '-', trim( $orig ) ); if ( $strict ) { @@ -1330,12 +1292,11 @@ function pods_create_slug( $orig, $strict = true ) { * @since 1.7.2 */ function pods_unique_slug( $slug, $column_name, $pod, $pod_id = 0, $id = 0, $obj = null, $strict = true ) { - $slug = pods_create_slug( $slug, $strict ); $pod_data = array(); - if ( is_array( $pod ) ) { + if ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) { $pod_data = $pod; $pod_id = pods_v_sanitized( 'id', $pod_data, 0 ); $pod = pods_v_sanitized( 'name', $pod_data ); @@ -1345,12 +1306,10 @@ function pods_unique_slug( $slug, $column_name, $pod, $pod_id = 0, $id = 0, $obj $id = absint( $id ); if ( empty( $pod_data ) ) { - $pod_data = pods_api()->load_pod( - array( - 'id' => $pod_id, - 'name' => $pod, - ), false - ); + $pod_data = pods_api()->load_pod( array( + 'id' => $pod_id, + 'name' => $pod, + ), false ); } if ( empty( $pod_data ) || empty( $pod_id ) || empty( $pod ) ) { @@ -1401,11 +1360,10 @@ function pods_unique_slug( $slug, $column_name, $pod, $pod_id = 0, $id = 0, $obj * @since 1.2.0 */ function pods_clean_name( $orig, $lower = true, $trim_underscores = false ) { - $str = trim( $orig ); - $str = preg_replace( '/(\s)/', '_', $str ); - $str = preg_replace( '/([^0-9a-zA-Z\-_])/', '', $str ); - $str = preg_replace( '/(_){2,}/', '_', $str ); + $str = preg_replace( '/([^0-9a-zA-Z\-_\s])/', '', $str ); + $str = preg_replace( '/(\s_)/', '_', $str ); + $str = preg_replace( '/(\s+)/', '_', $str ); $str = preg_replace( '/(-){2,}/', '-', $str ); if ( $lower ) { @@ -1420,23 +1378,42 @@ function pods_clean_name( $orig, $lower = true, $trim_underscores = false ) { } /** - * Return a lowercase alphanumeric name (with underscores) for safe Javascript variable names + * Return a lowercase alphanumeric name (with underscores) for safe JavaScript variable names. * - * @param string $orig Input string to clean - * @param boolean $lower Force lowercase + * @param string $orig Input string to clean. + * @param boolean $lower Whether to force lowercase. * - * @return string Sanitized name + * @return string The sanitized name. * * @since 2.5.3 */ function pods_js_name( $orig, $lower = true ) { - $str = pods_clean_name( $orig, $lower ); $str = str_replace( '-', '_', $str ); return $str; } +/** + * Return a camelCase alphanumeric name for safe JavaScript variable names. + * + * @param string $orig Input string to clean. + * + * @return string The sanitized name as camelCase. + * + * @since 2.8.0 + */ +function pods_js_camelcase_name( $orig ) { + // Clean the name for JS. + $str = pods_js_name( $orig, false ); + + // Replace _ with spaces and then Upper Case the words. + $str = ucwords( str_replace( '_', ' ', $str ) ); + + // Remove the spaces and lower case the firstWord. + return lcfirst( str_replace( ' ', '', $str ) ); +} + /** * Get the Absolute Integer of a value * @@ -1448,7 +1425,6 @@ function pods_js_name( $orig, $lower = true ) { * @since 2.0.0 */ function pods_absint( $maybeint, $strict = true, $allow_negative = false ) { - if ( true === $strict && ! is_numeric( trim( $maybeint ) ) ) { return 0; } @@ -1473,7 +1449,6 @@ function pods_absint( $maybeint, $strict = true, $allow_negative = false ) { * @return mixed */ function pods_str_replace( $find, $replace, $string, $occurrences = - 1 ) { - if ( is_array( $string ) ) { foreach ( $string as $k => $v ) { $string[ $k ] = pods_str_replace( $find, $replace, $v, $occurrences ); @@ -1513,13 +1488,11 @@ function pods_str_replace( $find, $replace, $string, $occurrences = - 1 ) { * @return int */ function pods_mb_strlen( $string ) { - if ( function_exists( 'mb_strlen' ) ) { return mb_strlen( $string ); } return strlen( $string ); - } /** @@ -1533,7 +1506,6 @@ function pods_mb_strlen( $string ) { * @return string */ function pods_mb_substr( $string, $start, $length = null, $encoding = null ) { - if ( function_exists( 'mb_substr' ) ) { if ( null === $encoding ) { $encoding = mb_internal_encoding(); @@ -1543,7 +1515,6 @@ function pods_mb_substr( $string, $start, $length = null, $encoding = null ) { } return substr( $string, $start, $length ); - } /** @@ -1872,7 +1843,6 @@ function pods_evaluate_tag( $tag, $args = array() ) { * @since 2.0.0 */ function pods_serial_comma( $value, $field = null, $fields = null, $and = null, $field_index = null ) { - if ( is_object( $value ) ) { $value = get_object_vars( $value ); } @@ -1903,7 +1873,7 @@ function pods_serial_comma( $value, $field = null, $fields = null, $and = null, $simple_tableless_objects = PodsForm::simple_tableless_objects(); - if ( ! empty( $params->field ) && is_array( $params->field ) && in_array( $params->field['type'], PodsForm::tableless_field_types(), true ) ) { + if ( ! empty( $params->field ) && ! is_string( $params->field ) && in_array( $params->field['type'], PodsForm::tableless_field_types(), true ) ) { if ( in_array( $params->field['type'], PodsForm::file_field_types(), true ) ) { if ( null === $params->field_index ) { $params->field_index = 'guid'; @@ -1936,7 +1906,7 @@ function pods_serial_comma( $value, $field = null, $fields = null, $and = null, $params->field = null; }//end if - if ( $simple && is_array( $params->field ) && ! is_array( $value ) && '' !== $value && null !== $value ) { + if ( $simple && ! is_array( $value ) && '' !== $value && null !== $value ) { $value = PodsForm::field_method( 'pick', 'simple_value', $params->field['name'], $value, $params->field ); } @@ -1992,7 +1962,7 @@ function pods_serial_comma( $value, $field = null, $fields = null, $and = null, $last = array_pop( $value ); } - if ( $simple && is_array( $params->field ) && ! is_array( $last ) && '' !== $last && null !== $last ) { + if ( $simple && ! is_array( $last ) && '' !== $last && null !== $last ) { $last = PodsForm::field_method( 'pick', 'simple_value', $params->field['name'], $last, $params->field ); } @@ -2018,7 +1988,7 @@ function pods_serial_comma( $value, $field = null, $fields = null, $and = null, } foreach ( $value as $k => $v ) { - if ( $simple && is_array( $params->field ) && ! is_array( $v ) && '' !== $v && null !== $v ) { + if ( $simple && ! is_array( $v ) && '' !== $v && null !== $v ) { $v = PodsForm::field_method( 'pick', 'simple_value', $params->field['name'], $v, $params->field ); } @@ -2093,7 +2063,6 @@ function pods_serial_comma( $value, $field = null, $fields = null, $and = null, * @since 2.0.5 */ function pods_var_user( $anon = false, $user = true, $capability = null ) { - $value = $anon; if ( is_user_logged_in() ) { @@ -2125,7 +2094,6 @@ function pods_var_user( $anon = false, $user = true, $capability = null ) { * @since 2.3.0 */ function pods_hierarchical_list( $list, $args = array() ) { - if ( empty( $args ) || ( ! is_object( $list ) && ! is_array( $list ) ) ) { return $list; } @@ -2158,7 +2126,6 @@ function pods_hierarchical_list( $list, $args = array() ) { * @since 2.3.0 */ function pods_hierarchical_list_recurse( $parent, $list, &$args ) { - $new = array(); $object = false; @@ -2260,10 +2227,9 @@ function pods_hierarchical_list_recurse( $parent, $list, &$args ) { * @return array|object * @internal param string $children_key Key to recurse children into * - * @since 2.3.0 + * @since 2.3.0 */ function pods_hierarchical_select( $list, $args = array() ) { - $object = false; if ( is_object( $list ) ) { @@ -2302,10 +2268,9 @@ function pods_hierarchical_select( $list, $args = array() ) { * @internal param string $children_key Key to recurse children into * * @see pods_hierarchical_select - * @since 2.3.0 + * @since 2.3.0 */ function pods_hierarchical_select_recurse( $items, $args, $depth = 0 ) { - $data = array(); foreach ( $items as $k => $v ) { @@ -2362,7 +2327,6 @@ function pods_hierarchical_select_recurse( $items, $args, $depth = 0 ) { * @since 2.3.0 */ function pods_list_filter( $list, $args = array(), $operator = 'AND' ) { - if ( empty( $args ) ) { return $list; } @@ -2384,3 +2348,28 @@ function pods_list_filter( $list, $args = array(), $operator = 'AND' ) { return $filtered; } + +/** + * Clean extra line breaks to prevent empty

            when it eventually goes into wpautop(). + * + * @since 2.8.0 + * + * @param string $content The content to be cleaned up. + * + * @return string The content that has been cleaned up. + */ +function pods_clean_linebreaks( $content ) { + // Replace \n\n\n (or more) with \n\n. + $content = preg_replace( '/(\n+[ \t]*\n+[ \t]*\n+)+/m', "\n\n", $content ); + + // Replace extra whitespace at the end of lines. + $content = preg_replace( '/([ \t]+\n)/m', "\n", $content ); + + if ( ! $content || ! is_string( $content ) ) { + return ''; + } + + return $content; +} + +add_filter( 'pods_template_content', 'pods_clean_linebreaks' ); diff --git a/includes/forms.php b/includes/forms.php new file mode 100644 index 0000000000..58b7959d7e --- /dev/null +++ b/includes/forms.php @@ -0,0 +1,392 @@ + context. + * + * @since 2.8.0 + * + * @param string $name The object name. + * @param int|string $object_id The object ID. + * @param array $options The customization options. + */ +function pods_form_render_fields( $name, $object_id, array $options = [] ) { + $defaults = [ + 'section_field' => null, + 'section' => null, + 'separator' => 'before', + 'heading' => 'h2', + 'separated_heading' => null, + 'render' => 'table', + ]; + + $options = array_merge( $defaults, $options ); + + $pod = pods( $name, $object_id, true ); + + if ( ! $pod ) { + return; + } + + // Return groups. + $options['return_type'] = 'group'; + + // Get groups/fields and render them. + $groups = pods_form_get_visible_objects( $pod, $options ); + + foreach ( $groups as $group ) { + $fields = $group->get_fields(); + + /** + * Allow hooking into before the form field output for a group is rendered. + * + * @since 2.8.0 + * + * @param Whatsit\Group $group The Group object. + */ + do_action( 'pods_form_render_fields_group_pre', $group ); + + $is_table_separated_render = 'table-separated' === $options['render']; + $is_table_render = 'table' === $options['render'] || $is_table_separated_render; + $is_table_rows_render = 'table-rows' === $options['render']; + + if ( $is_table_separated_render ) { + echo "\n"; + } + + if ( ! $is_table_rows_render && 'before' === $options['separator'] ) { + echo "
            \n"; + } + + if ( $is_table_rows_render ) { + echo ''; + } + + if ( $options['heading'] ) { + $heading_classes = [ + 'pods-form-heading', + 'pods-form-heading--pod-' . $name, + 'pods-form-heading--group', + 'pods-form-heading--group-' . $group['name'], + ]; + + $heading_classes = array_map( 'sanitize_html_class', $heading_classes ); + $heading_classes = implode( ' ', $heading_classes ); + + printf( + '<%1$s class="%2$s">%3$s' . "\n", + esc_html( $options['heading'] ), + esc_attr( $heading_classes ), + wp_kses_post( $group['label'] ) + ); + } + + if ( $is_table_rows_render ) { + echo ''; + } + + $container_classes = [ + 'pods-form', + 'pods-form-container', + 'pods-form-container--pod--' . $name, + 'pods-form-container--group', + 'pods-form-container--group--' . $group['name'], + ]; + + $container_classes = array_map( 'sanitize_html_class', $container_classes ); + $container_classes = implode( ' ', $container_classes ); + + if ( $is_table_render || $is_table_rows_render ) { + if ( $is_table_render ) { + echo '' . "\n"; + } + + $field_prefix = 'pods_meta_'; + $field_row_classes = 'pods-meta'; + + pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) ); + + if ( $is_table_render ) { + echo "
            \n"; + } + } elseif ( 'div-rows' === $options['render'] ) { + echo '
            ' . "\n"; + + $field_prefix = 'pods_meta_'; + $field_row_classes = 'pods-meta'; + + pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) ); + + echo "
            \n"; + } + + if ( $is_table_separated_render ) { + if ( $options['heading'] && $options['separated_heading'] ) { + printf( '<%1$s>%2$s' . "\n", esc_html( $options['heading'] ), wp_kses_post( $options['separated_heading'] ) ); + } + + echo '' . "\n"; + } + + if ( ! $is_table_rows_render && 'after' === $options['separator'] ) { + echo "
            \n"; + } + + /** + * Allow hooking into after the form field output for a group is rendered. + * + * @since 2.8.0 + * + * @param Whatsit\Group $group The Group object. + */ + do_action( 'pods_form_render_fields_group_post', $group ); + } +} + +/** + * Get the list of Groups or Fields that are able to be shown. + * + * @since 2.8.0 + * + * @param Pods $pod The Pods object. + * @param array $options The customization options. + * + * @return Whatsit\Group[]|Whatsit\Field[] List of Groups or Fields that are able to be shown. + */ +function pods_form_get_visible_objects( $pod, array $options = [] ) { + $defaults = [ + 'section_field' => null, + 'section' => null, + 'return_type' => 'group', + ]; + + $options = array_merge( $defaults, $options ); + + $visible_groups = []; + $visible_fields = []; + + $return_fields = 'field' === $options['return_type']; + + // Get groups/fields and render them. + $groups = $pod->pod_data->get_groups(); + + foreach ( $groups as $group ) { + // Skip if the section does not match. + if ( + $options['section'] + && $options['section_field'] + && ( + 'any' === $options['section'] + || ! in_array( $options['section'], (array) $group[ $options['section_field'] ], true ) + ) + ) { + continue; + } + + $fields = $group->get_fields(); + + if ( empty( $fields ) ) { + continue; + } + + if ( ! pods_permission( $group ) ) { + continue; + } + + $field_found = false; + + foreach ( $fields as $field ) { + if ( ! pods_permission( $field ) ) { + continue; + } + + if ( pods_v( 'hidden', $field, false ) ) { + continue; + } + + if ( $return_fields ) { + $visible_fields[] = $field; + + continue; + } + + $field_found = true; + + break; + } + + if ( ! $field_found ) { + continue; + } + + $visible_groups[] = $group; + } + + if ( $return_fields ) { + return $visible_fields; + } + + return $visible_groups; +} + +/** + * Validate the submitted fields from the form. + * + * @since 2.8.0 + * + * @param string $name The object name. + * @param int|string|null $object_id The object ID. + * @param array $options The customization options. + * + * @return true|WP_Error[]|null True if the fields validate, a list of WP_Error objects with validation errors, or null if Pod does not exist. + */ +function pods_form_validate_submitted_fields( $name, $object_id = null, array $options = [] ) { + $pod = pods( $name, $object_id, true ); + + if ( ! $pod ) { + return null; + } + + // Get the fields. + $options['return_type'] = 'field'; + + // Get fields and save them. + $fields = pods_form_get_visible_objects( $pod, $options ); + + $api = pods_api(); + + // Enforce WP_Error objects for validation errors. + $api->display_errors = 'wp_error'; + + $errors = []; + + foreach ( $fields as $field ) { + $field_name = $field['name']; + + $value = pods_form_get_submitted_field_value( $field_name ); + + $field_is_valid = $api->handle_field_validation( $value, $field_name, [], $fields, $pod ); + + if ( is_wp_error( $field_is_valid ) ) { + $errors[] = $field_is_valid; + } + } + + // Check for validation errors. + if ( ! empty( $errors ) ) { + return $errors; + } + + // Fields are valid. + return true; +} + +/** + * Save the submitted fields from the form. + * + * @since 2.8.0 + * + * @param string $name The object name. + * @param int|string $object_id The object ID. + * @param bool $is_new_item Whether this is a new item being saved. + * @param array $options The customization options. + * + * @return int|null The saved item or null if the pod does not exist. + */ +function pods_form_save_submitted_fields( $name, $object_id, $is_new_item = false, array $options = [] ) { + $pod = pods( $name, $object_id, true ); + + if ( ! $pod ) { + return null; + } + + // Get the submitted field values. + $data = pods_form_get_submitted_field_values( $name, $options ); + + return $pod->save( $data, null, null, [ + 'is_new_item' => $is_new_item, + 'podsmeta' => true, + ] ); +} + +/** + * Get the submitted field values from the form. + * + * @since 2.8.0 + * + * @param string $name The object name. + * @param array $options The customization options. + * + * @return array List of submitted field values and their values. + */ +function pods_form_get_submitted_field_values( $name, array $options = [] ) { + // Get the submitted fields. + $fields = pods_form_get_submitted_fields( $name, $options ); + + $data = []; + + foreach ( $fields as $field ) { + $field_name = $field['name']; + + $data[ $field_name ] = pods_form_get_submitted_field_value( $field_name ); + } + + return $data; +} + +/** + * Get the submitted field value for a field. + * + * @since 2.8.0 + * + * @param string|array|Field $field The field name or object. + * @param string $method The method to get the value from (default: post). + * + * @return mixed The submitted field value for a field. + */ +function pods_form_get_submitted_field_value( $field, $method = 'post' ) { + $field_name = $field; + + if ( $field instanceof Field ) { + $field_name = $field->get_name(); + } elseif ( is_array( $field ) ) { + $field_name = $field['name']; + } elseif ( ! is_string( $field ) ) { + return ''; + } + + return pods_v( 'pods_meta_' . $field_name, $method, '' ); +} + + +/** + * Get the submitted fields from the form. + * + * @since 2.8.0 + * + * @param string $name The object name. + * @param array $options The customization options. + * + * @return array List of submitted fields and their values. + */ +function pods_form_get_submitted_fields( $name, array $options = [] ) { + $pod = pods( $name, null, true ); + + if ( ! $pod ) { + return []; + } + + // Get the fields. + $options['return_type'] = 'field'; + + // Get fields and save them. + return pods_form_get_visible_objects( $pod, $options ); +} diff --git a/includes/general.php b/includes/general.php index b0a955fff5..a405a4eeb8 100644 --- a/includes/general.php +++ b/includes/general.php @@ -2,6 +2,15 @@ /** * @package Pods\Global\Functions\General */ + +use Pods\Admin\Settings; +use Pods\API\Whatsit\Value_Field; +use Pods\Whatsit; +use Pods\Whatsit\Field; +use Pods\Whatsit\Pod; +use Pods\Whatsit\Store; +use Pods\Permissions; + /** * Standardize queries and error reporting. It replaces @wp_ with $wpdb->prefix. * @@ -16,8 +25,11 @@ * @since 2.0.0 */ function pods_query( $sql, $error = 'Database Error', $results_error = null, $no_results_error = null ) { - - $podsdata = pods_data(); + try { + $podsdata = pods_data( null, null, true, false ); + } catch ( Exception $exception ) { + return null; + } $sql = apply_filters( 'pods_query_sql', $sql, $error, $results_error, $no_results_error ); $sql = $podsdata->get_sql( $sql ); @@ -44,7 +56,7 @@ function pods_query( $sql, $error = 'Database Error', $results_error = null, $no echo ''; } - return $podsdata->query( $sql, $error, $results_error, $no_results_error ); + return PodsData::query( $sql, $error, $results_error, $no_results_error ); } /** @@ -60,7 +72,6 @@ function pods_query( $sql, $error = 'Database Error', $results_error = null, $no * @todo Need to figure out how to handle $scope = 'pods' for the Pods class */ function pods_do_hook( $scope, $name, $args = null, $obj = null ) { - // Add filter name array_unshift( $args, "pods_{$scope}_{$name}" ); @@ -82,7 +93,6 @@ function pods_do_hook( $scope, $name, $args = null, $obj = null ) { * @return void */ function pods_message( $message, $type = null ) { - if ( empty( $type ) || ! in_array( $type, array( 'notice', 'error' ), true ) ) { $type = 'notice'; } @@ -114,7 +124,6 @@ function pods_message( $message, $type = null ) { * @since 2.0.0 */ function pods_error( $error, $obj = null ) { - global $pods_errors; $display_errors = $obj; @@ -142,7 +151,7 @@ function pods_error( $error, $obj = null ) { /** * @var string $error_mode Throw an exception, exit with the message, return false, or return WP_Error */ - if ( ! in_array( $error_mode, array( 'exception', 'exit', 'false', 'wp_error' ), true ) ) { + if ( ! in_array( $error_mode, array( 'exception', 'exit', 'false', 'wp_error', 'json' ), true ) ) { $error_mode = 'exception'; } @@ -151,6 +160,8 @@ function pods_error( $error, $obj = null ) { */ if ( pods_doing_shortcode() ) { $error_mode = 'exception'; + } elseif ( pods_doing_json() ) { + $error_mode = 'json'; } /** @@ -203,6 +214,11 @@ function pods_error( $error, $obj = null ) { $error_mode = 'exit'; } + // Support testing debug messages. + if ( function_exists( 'codecept_debug' ) ) { + codecept_debug( 'Pods Debug Error: ' . $error ); + } + if ( ! empty( $error ) ) { if ( 'exception' === $error_mode ) { $exception_bypass = apply_filters( 'pods_error_exception', null, $error ); @@ -213,7 +229,19 @@ function pods_error( $error, $obj = null ) { $pods_errors = $error; - set_exception_handler( 'pods_error' ); + /** + * Allow filtering whether the fallback is enabled to catch uncaught exceptions. + * + * @since 2.8.0 + * + * @param bool $exception_fallback_enabled Whether the fallback is enabled to catch uncaught exceptions. + * @param string $error The error information. + */ + $exception_fallback_enabled = apply_filters( 'pods_error_exception_fallback_enabled', true, $error ); + + if ( $exception_fallback_enabled ) { + set_exception_handler( 'pods_error' ); + } throw new Exception( $error ); } elseif ( 'exit' === $error_mode ) { @@ -231,11 +259,22 @@ function pods_error( $error, $obj = null ) { } } elseif ( 'wp_error' === $error_mode ) { return $wp_error; + } elseif ( 'json' === $error_mode ) { + $meta_box_loader_compat = (int) pods_v( 'meta-box-loader', 'request', 0 ); + + // Check if this is a back-compat meta box save request. + if ( 1 === $meta_box_loader_compat ) { + // Do not block this page. + error_log( 'Pods Meta Save Error:' . $error ); + } else { + wp_send_json( [ + 'message' => $error, + ], 500 ); + } }//end if }//end if return false; - } /** @@ -255,14 +294,16 @@ function pods_error( $error, $obj = null ) { * @since 2.0.0 */ function pods_debug( $debug = '_null', $die = false, $prefix = '_null' ) { - global $pods_debug; $pods_debug ++; - if ( ! pods_is_debug_display() ) { - // Log errors if we do not display them. - error_log( 'Pods error: ' . (string) $debug ); + if ( function_exists( 'codecept_debug' ) ) { + if ( ! is_string( $debug ) ) { + $debug = var_export( $debug, true ); + } + + codecept_debug( 'Pods Debug: ' . $debug ); return; } @@ -320,7 +361,6 @@ function pods_is_debug_display() { * @since 2.3.5 */ function pods_is_admin( $cap = null ) { - if ( is_user_logged_in() ) { if ( is_multisite() && is_super_admin() ) { @@ -362,7 +402,6 @@ function pods_is_admin( $cap = null ) { * @since 2.3.0 */ function pods_developer() { - if ( defined( 'PODS_DEVELOPER' ) && PODS_DEVELOPER ) { return true; } @@ -378,7 +417,6 @@ function pods_developer() { * @since 2.3.0 */ function pods_tableless() { - if ( defined( 'PODS_TABLELESS' ) && PODS_TABLELESS ) { return true; } @@ -386,6 +424,52 @@ function pods_tableless() { return false; } +/** + * Determine whether the wp_podsrel table is enabled. + * + * @since 2.8.0 + * + * @return bool Whether the wp_podsrel table is enabled. + */ +function pods_podsrel_enabled() { + // Disabled when Pods Tableless mode is on. + if ( pods_tableless() ) { + return false; + } + + /** + * Allow filtering of whether the wp_podsrel table is enabled. + * + * @since 2.8.0 + * + * @param bool $enabled Whether the wp_podsrel table is enabled. + */ + return apply_filters( 'pods_podsrel_enabled', true ); +} + +/** + * Determine whether relationship meta storage is enabled. + * + * @since 2.8.0 + * + * @param null|array|Field $field The field object. + * @param null|array|Pod $pod The pod object. + * + * @return bool Whether relationship meta storage is enabled. + */ +function pods_relationship_meta_storage_enabled( $field = null, $pod = null ) { + /** + * Allow filtering of whether relationship meta storage is enabled. + * + * @since 2.8.0 + * + * @param bool $enabled Whether relationship meta storage table is enabled. + * @param null|array|Field $field The field object. + * @param null|array|Pod $pod The pod object. + */ + return apply_filters( 'pods_relationship_meta_storage_enabled', true, $field, $pod ); +} + /** * Determine if Light Mode is enabled * @@ -411,18 +495,25 @@ function pods_light() { * @since 2.3.5 */ function pods_strict( $include_debug = true ) { + $strict = false; if ( defined( 'PODS_STRICT' ) && PODS_STRICT ) { // Deprecated PODS_STRICT_MODE since 2.3.5 - return true; + $strict = true; } elseif ( defined( 'PODS_STRICT_MODE' ) && PODS_STRICT_MODE && pods_allow_deprecated( false ) ) { - return true; + $strict = true; } elseif ( $include_debug && defined( 'WP_DEBUG' ) && WP_DEBUG ) { - return true; + $strict = true; } - return false; - + /** + * Allow filtering of whether strict mode is enabled. + * + * @param boolean $strict Whether strict mode is enabled. + * + * @since 2.8.0 + */ + return apply_filters( 'pods_strict_mode', $strict ); } /** @@ -435,15 +526,13 @@ function pods_strict( $include_debug = true ) { * @since 2.3.10 */ function pods_allow_deprecated( $strict = true ) { - - if ( $strict && pods_strict() ) { + if ( $strict && pods_strict( false ) ) { return false; } elseif ( ! defined( 'PODS_DEPRECATED' ) || PODS_DEPRECATED ) { return true; } return false; - } /** @@ -454,12 +543,18 @@ function pods_allow_deprecated( $strict = true ) { * @since 2.3.9 */ function pods_api_cache() { - if ( defined( 'PODS_API_CACHE' ) && ! PODS_API_CACHE ) { return false; } - return true; + /** + * Filter whether to use the Pods API cache. + * + * @param boolean $use_cache Whether to use the Pods API cache. + * + * @since 2.8.0 + */ + return apply_filters( 'pods_api_cache', true ); } /** @@ -500,7 +595,6 @@ function pods_shortcode_allow_evaluate_tags() { * @since 2.0.0 */ function pods_deprecated( $function, $version, $replacement = null ) { - if ( ! version_compare( $version, PODS_VERSION, '<=' ) && ! version_compare( $version . '-a-0', PODS_VERSION, '<=' ) ) { return; } @@ -515,7 +609,7 @@ function pods_deprecated( $function, $version, $replacement = null ) { $error = __( '%1$s has been deprecated since Pods version %2$s with no alternative available.', 'pods' ); } - trigger_error( sprintf( $error, $function, $version, $replacement ) ); + trigger_error( sprintf( $error, $function, $version, $replacement ), E_USER_DEPRECATED ); } } @@ -530,7 +624,6 @@ function pods_deprecated( $function, $version, $replacement = null ) { * @since 2.0.0 */ function pods_help( $text, $url = null ) { - if ( ! wp_script_is( 'jquery-qtip2', 'registered' ) ) { wp_register_script( 'jquery-qtip2', PODS_URL . 'ui/js/qtip/jquery.qtip.min.js', array( 'jquery' ), '3.0.3' ); } elseif ( ! wp_script_is( 'jquery-qtip2', 'queue' ) && ! wp_script_is( 'jquery-qtip2', 'to_do' ) && ! wp_script_is( 'jquery-qtip2', 'done' ) ) { @@ -538,12 +631,10 @@ function pods_help( $text, $url = null ) { } if ( ! wp_script_is( 'pods-qtip-init', 'registered' ) ) { - wp_register_script( - 'pods-qtip-init', PODS_URL . 'ui/js/qtip.js', array( - 'jquery', - 'jquery-qtip2', - ), PODS_VERSION - ); + wp_register_script( 'pods-qtip-init', PODS_URL . 'ui/js/qtip.js', array( + 'jquery', + 'jquery-qtip2', + ), PODS_VERSION ); wp_enqueue_script( 'pods-qtip-init' ); } elseif ( ! wp_script_is( 'pods-qtip-init', 'queue' ) && ! wp_script_is( 'pods-qtip-init', 'to_do' ) && ! wp_script_is( 'pods-qtip-init', 'done' ) ) { wp_enqueue_script( 'pods-qtip-init' ); @@ -562,14 +653,14 @@ function pods_help( $text, $url = null ) { } if ( 0 < strlen( $url ) ) { - $text .= '

            ' . __( 'Find out more', 'pods' ) . ' »'; + $text .= '

            ' . esc_html__( 'Find out more', 'pods' ) . ' »'; } echo '' . esc_attr( $text ) . ''; } /** - * Check whether or not something is a specific version minimum and/or maximum + * Check whether something is a specific version minimum and/or maximum * * @param string $minimum_version Minimum version * @param string $comparison Comparison operator @@ -578,7 +669,6 @@ function pods_help( $text, $url = null ) { * @return bool */ function pods_version_check( $what, $minimum_version, $comparison = '<=', $maximum_version = null ) { - global $wp_version, $wpdb; if ( 'php' === $what ) { @@ -611,25 +701,60 @@ function pods_version_check( $what, $minimum_version, $comparison = '<=', $maxim * @since 1.7.5 */ function pods_helper( $helper_name, $value = null, $name = null ) { - return pods()->helper( $helper_name, $value, $name ); } /** - * Get the full URL of the current page + * Get the current hostname. + * + * @since 2.8.0 + * + * @return string The current hostname. + */ +function pods_current_host() { + if ( empty( $_SERVER['HTTP_HOST'] ) ) { + $host = wp_parse_url( get_site_url(), PHP_URL_HOST ); + + if ( empty( $host ) ) { + return 'localhost'; + } + + return $host; + } + + return $_SERVER['HTTP_HOST']; +} + +/** + * Get the full path of the current page. + * + * @since 2.8.0 + * + * @return string Full path of the current page. + */ +function pods_current_path() { + if ( empty( $_SERVER['REQUEST_URI'] ) ) { + return '/'; + } + + return $_SERVER['REQUEST_URI']; +} + +/** + * Get the full URL of the current page. * - * @return string Full URL of the current page * @since 2.3.0 + * + * @return string Full URL of the current page. */ function pods_current_url() { - $url = 'http'; if ( isset( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'] && 0 !== $_SERVER['HTTPS'] ) { $url = 'https'; } - $url .= '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $url .= '://' . pods_current_host() . pods_current_path(); return apply_filters( 'pods_current_url', $url ); } @@ -643,7 +768,6 @@ function pods_current_url() { * @since 2.0.0 */ function is_pod( $object = null ) { - global $pods, $post; if ( is_object( $object ) && isset( $object->pod ) && ! empty( $object->pod ) ) { @@ -667,7 +791,6 @@ function is_pod( $object = null ) { * @since 1.2.0 */ function pods_access( $privs, $method = 'OR' ) { - // Convert $privs to an array $privs = (array) $privs; @@ -746,44 +869,66 @@ function pods_doing_shortcode( $bool = null ) { return $check; } +/** + * Check whether we are currently in a JSON request. + * + * @since 2.8.0 + * + * @return bool Whether we are in a REST API or JSON request. + */ +function pods_doing_json() { + // Check whether we are doing a REST API request. + if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + return true; + } + + // Return whether we are doing a JSON request. + return wp_is_json_request(); +} + /** * Shortcode support for use anywhere that support WP Shortcodes. * Will return error message on failure. * + * @since 1.6.7 + * @since 2.7.13 Try/Catch. + * * @param array $tags An associative array of shortcode properties. * @param string $content A string that represents a template override. * * @return string - * @since 1.6.7 - * @since 2.7.13 Try/Catch. */ function pods_shortcode( $tags, $content = null ) { pods_doing_shortcode( true ); + try { $return = pods_shortcode_run( $tags, $content ); } catch ( Exception $exception ) { $return = $exception->getMessage(); + if ( ! pods_is_debug_display() ) { // Logs message. pods_debug( $return ); $return = ''; } } + pods_doing_shortcode( false ); + return $return; } /** * Shortcode support for use anywhere that support WP Shortcodes. * + * @since 2.7.13 + * * @param array $tags An associative array of shortcode properties. * @param string $content A string that represents a template override. * * @return string - * @since 2.7.13 */ function pods_shortcode_run( $tags, $content = null ) { - if ( defined( 'PODS_DISABLE_SHORTCODE' ) && PODS_DISABLE_SHORTCODE ) { return ''; } @@ -820,7 +965,8 @@ function pods_shortcode_run( $tags, $content = null ) { 'pagination' => false, 'page' => null, 'offset' => null, - 'filters' => false, + 'filters_enable' => null, + 'filters' => '', 'filters_label' => null, 'filters_location' => 'before', 'pagination_label' => null, @@ -828,22 +974,24 @@ function pods_shortcode_run( $tags, $content = null ) { 'pagination_location' => 'after', ); - $default_other_tags = array( - 'field' => null, - 'col' => null, - 'template' => null, - 'pods_page' => null, - 'helper' => null, - 'form' => null, - 'fields' => null, - 'label' => null, - 'thank_you' => null, - 'not_found' => null, - 'view' => null, - 'cache_mode' => 'none', - 'expires' => 0, - 'shortcodes' => false, - ); + $default_other_tags = [ + 'blog_id' => null, + 'field' => null, + 'col' => null, + 'template' => null, + 'pods_page' => null, + 'helper' => null, + 'form' => null, + 'form_output_type' => null, + 'fields' => null, + 'label' => null, + 'thank_you' => null, + 'not_found' => null, + 'view' => null, + 'cache_mode' => 'none', + 'expires' => 0, + 'shortcodes' => false, + ]; $defaults = array_merge( $default_other_tags, $default_query_tags ); @@ -875,7 +1023,27 @@ function pods_shortcode_run( $tags, $content = null ) { } } - return $return; + /** + * Allow customization of shortcode output based on shortcode attributes. + * + * @since 2.7.9 + * + * @param string $return Shortcode output to return. + * @param array $tags Shortcode attributes. + * @param null|Pods $pod Pods object, or null if 'view' context. + * @param string $context The shortcode context (form, field, pods-page, view, or list). + */ + return apply_filters( 'pods_shortcode_output', $return, $tags, null, 'view' ); + } + + $blog_is_switched = false; + + if ( defined( 'PODS_SHORTCODE_ALLOW_BLOG_SWITCHING' ) && PODS_SHORTCODE_ALLOW_BLOG_SWITCHING && is_multisite() ) { + if ( ! empty( $tags['blog_id'] ) && is_numeric( $tags['blog_id'] ) && (int) get_current_blog_id() !== (int) $tags['blog_id'] ) { + switch_to_blog( (int) $tags['blog_id'] ); + + $blog_is_switched = true; + } } if ( ! $tags['use_current'] && empty( $tags['name'] ) ) { @@ -908,7 +1076,11 @@ function pods_shortcode_run( $tags, $content = null ) { } if ( ! $tags['use_current'] && empty( $tags['name'] ) ) { - return '

            ' . __( 'Please provide a Pod name', 'pods' ) . '

            '; + if ( $blog_is_switched ) { + restore_current_blog(); + } + + return '

            ' . esc_html__( 'Pods embed error: Please provide a Pod name', 'pods' ) . '

            '; } } @@ -925,7 +1097,11 @@ function pods_shortcode_run( $tags, $content = null ) { } if ( empty( $content ) && empty( $tags['pods_page'] ) && empty( $tags['template'] ) && empty( $tags['field'] ) && empty( $tags['form'] ) ) { - return '

            ' . __( 'Please provide either a template or field name', 'pods' ) . '

            '; + if ( $blog_is_switched ) { + restore_current_blog(); + } + + return '

            ' . esc_html__( 'Pods embed error: Please provide either a template or field name', 'pods' ) . '

            '; } if ( ! $tags['use_current'] && ! isset( $id ) ) { @@ -969,7 +1145,11 @@ function pods_shortcode_run( $tags, $content = null ) { } if ( empty( $pod ) || ! $pod->valid() ) { - return '

            ' . __( 'Pod not found', 'pods' ) . '

            '; + if ( $blog_is_switched ) { + restore_current_blog(); + } + + return '

            ' . esc_html__( 'Pods embed error: Pod not found', 'pods' ) . '

            '; } $found = 0; @@ -1020,8 +1200,19 @@ function pods_shortcode_run( $tags, $content = null ) { }//end if // Load filters and return HTML for later use. - if ( false !== $tags['filters'] ) { - $filters = $pod->filters( $tags['filters'], $tags['filters_label'] ); + if ( + true === (bool) $tags['filters_enable'] + || ( + ! empty( $tags['filters'] ) + && null === $tags['filters_enable'] + ) + ) { + $filters_params = [ + 'fields' => (string) $tags['filters'], + 'label' => (string) $tags['filters_label'], + ]; + + $filters = $pod->filters( $filters_params ); } // Forms require params set @@ -1063,23 +1254,54 @@ function pods_shortcode_run( $tags, $content = null ) { $pod->find( $params ); - $found = $pod->total(); + $found = $pod->total_found(); }//end if }//end if + // Handle form output. if ( ! empty( $tags['form'] ) ) { if ( 'user' === $pod->pod ) { if ( false !== strpos( $tags['fields'], '_capabilities' ) || false !== strpos( $tags['fields'], '_user_level' ) ) { + if ( $blog_is_switched ) { + restore_current_blog(); + } + // Further hardening of User-based forms return ''; } elseif ( $is_singular && ( ! defined( 'PODS_SHORTCODE_ALLOW_USER_EDIT' ) || ! PODS_SHORTCODE_ALLOW_USER_EDIT ) ) { + if ( $blog_is_switched ) { + restore_current_blog(); + } + // Only explicitly allow user edit forms return ''; } } - return $pod->form( $tags['fields'], $tags['label'], $tags['thank_you'] ); - } elseif ( ! empty( $tags['field'] ) ) { + $form_params = [ + 'fields' => $tags['fields'], + 'label' => $tags['label'], + 'thank_you' => $tags['thank_you'], + 'output_type' => $tags['form_output_type'], + ]; + + $return = $pod->form( $form_params ); + + /** + * Allow customization of shortcode output based on shortcode attributes. + * + * @since 2.7.9 + * + * @param string $return Shortcode output to return. + * @param array $tags Shortcode attributes. + * @param null|Pods $pod Pods object, or null if 'view' context. + * @param string $context The shortcode context (form, field, pods-page, view, or list). + */ + return apply_filters( 'pods_shortcode_output', $return, $tags, $pod, 'form' ); + } + + // Handle field output. + if ( ! empty( $tags['field'] ) ) { if ( $tags['template'] || $content ) { $return = ''; $related = $pod->field( $tags['field'], array( 'output' => 'find' ) ); @@ -1094,64 +1316,118 @@ function pods_shortcode_run( $tags, $content = null ) { $return = $pod->helper( $tags['helper'], $pod->field( $tags['field'] ), $tags['field'] ); } + // @todo $blog_is_switched >> Switch back before running other shortcodes? if ( $tags['shortcodes'] && defined( 'PODS_SHORTCODE_ALLOW_SUB_SHORTCODES' ) && PODS_SHORTCODE_ALLOW_SUB_SHORTCODES ) { $return = do_shortcode( $return ); } - return $return; - } elseif ( ! empty( $tags['pods_page'] ) && class_exists( 'Pods_Pages' ) ) { + if ( $blog_is_switched ) { + restore_current_blog(); + } + + /** + * Allow customization of shortcode output based on shortcode attributes. + * + * @since 2.7.9 + * + * @param string $return Shortcode output to return. + * @param array $tags Shortcode attributes. + * @param null|Pods $pod Pods object, or null if 'view' context. + * @param string $context The shortcode context (form, field, pods-page, view, or list). + */ + return apply_filters( 'pods_shortcode_output', $return, $tags, $pod, 'field' ); + } + + // Handle Pods Page output. + if ( ! empty( $tags['pods_page'] ) && class_exists( 'Pods_Pages' ) ) { $pods_page = Pods_Pages::exists( $tags['pods_page'] ); if ( empty( $pods_page ) ) { - return '

            Pods Page not found

            '; + if ( $blog_is_switched ) { + restore_current_blog(); + } + + return '

            ' . esc_html__( 'Pods embed error: Pods Page not found.', 'pods' ) . '

            '; } $return = Pods_Pages::content( true, $pods_page ); + // @todo $blog_is_switched >> Switch back before running other shortcodes? if ( $tags['shortcodes'] && defined( 'PODS_SHORTCODE_ALLOW_SUB_SHORTCODES' ) && PODS_SHORTCODE_ALLOW_SUB_SHORTCODES ) { $return = do_shortcode( $return ); } - return $return; + if ( $blog_is_switched ) { + restore_current_blog(); + } + + /** + * Allow customization of shortcode output based on shortcode attributes. + * + * @since 2.7.9 + * + * @param string $return Shortcode output to return. + * @param array $tags Shortcode attributes. + * @param null|Pods $pod Pods object, or null if 'view' context. + * @param string $context The shortcode context (form, field, pods-page, view, or list). + */ + return apply_filters( 'pods_shortcode_output', $return, $tags, $pod, 'pods-page' ); }//end if $pagination = false; // Only handle pagination on non-singular shortcodes where items were found. - if ( ! $is_singular && 0 < $found && $tags['pagination'] ) { - $pagination = array( + if ( + ! $is_singular + && 0 < $found + && ( + empty( $params['limit'] ) + || ( + 0 < $params['limit'] + && $params['limit'] < $found + ) + ) + && true === $tags['pagination'] + ) { + $pagination_params = array( 'label' => pods_v( 'pagination_label', $tags, null ), 'type' => pods_v( 'pagination_type', $tags, null ), ); // Remove empty params. - $pagination = array_filter( $pagination ); + $pagination_params = array_filter( $pagination_params ); + + $pagination = $pod->pagination( $pagination_params ); } ob_start(); if ( $filters && 'before' === $tags['filters_location'] ) { + // phpcs:ignore echo $filters; } - if ( false !== $pagination && in_array( $tags['pagination_location'], array( 'before', 'both', ), true ) ) { - echo $pod->pagination( $pagination ); + if ( $pagination && in_array( $tags['pagination_location'], [ 'before', 'both' ], true ) ) { + // phpcs:ignore + echo $pagination; } $content = $pod->template( $tags['template'], $content ); - if ( empty( $content ) && ! empty( $tags['not_found'] ) ) { + if ( '' === trim( $content ) && ! empty( $tags['not_found'] ) ) { $content = $pod->do_magic_tags( $tags['not_found'] ); } // phpcs:ignore echo $content; - if ( false !== $pagination && in_array( $tags['pagination_location'], array( 'after', 'both', ), true ) ) { - echo $pod->pagination( $pagination ); + if ( $pagination && in_array( $tags['pagination_location'], [ 'after', 'both' ], true ) ) { + // phpcs:ignore + echo $pagination; } if ( $filters && 'after' === $tags['filters_location'] ) { + // phpcs:ignore echo $filters; } @@ -1161,18 +1437,21 @@ function pods_shortcode_run( $tags, $content = null ) { $return = do_shortcode( $return ); } + if ( $blog_is_switched ) { + restore_current_blog(); + } + /** * Allow customization of shortcode output based on shortcode attributes. * * @since 2.7.9 * - * @param string $return Shortcode output to return. - * @param array $tags Shortcode attributes. - * @param Pods $pod Pods object. + * @param string $return Shortcode output to return. + * @param array $tags Shortcode attributes. + * @param null|Pods $pod Pods object, or null if 'view' context. + * @param string $context The shortcode context (form, field, pods-page, view, or list). */ - $return = apply_filters( 'pods_shortcode_output', $return, $tags, $pod ); - - return $return; + return apply_filters( 'pods_shortcode_output', $return, $tags, $pod, 'list' ); } /** @@ -1185,7 +1464,6 @@ function pods_shortcode_run( $tags, $content = null ) { * @since 2.3.0 */ function pods_shortcode_form( $tags, $content = null ) { - $tags['form'] = 1; return pods_shortcode( $tags, $content ); @@ -1211,7 +1489,6 @@ function pods_shortcode_form( $tags, $content = null ) { * @return string Content with shortcodes filtered out. */ function pods_do_shortcode( $content, $shortcodes ) { - global $shortcode_tags; // No shortcodes in content @@ -1226,7 +1503,6 @@ function pods_do_shortcode( $content, $shortcodes ) { if ( ! empty( $shortcodes ) ) { $temp_shortcode_filter = function ( $return, $tag, $attr, $m ) use ( $shortcodes ) { - if ( in_array( $m[2], $shortcodes, true ) ) { // If shortcode being called is in list, return false to allow it to run return false; @@ -1249,7 +1525,6 @@ function pods_do_shortcode( $content, $shortcodes ) { } return $content; - } /** @@ -1260,7 +1535,6 @@ function pods_do_shortcode( $content, $shortcodes ) { * @since 1.10 */ function pods_compatibility_check() { - $compatible = true; if ( ! pods_version_check( 'wp', PODS_WP_VERSION_MINIMUM ) ) { @@ -1292,7 +1566,6 @@ function pods_compatibility_check() { * @since 1.10 */ function pods_version_notice_wp() { - global $wp_version; ?>
            @@ -1313,7 +1586,6 @@ function pods_version_notice_wp() { * @since 1.10 */ function pods_version_notice_php() { - ?>

            @@ -1333,7 +1605,6 @@ function pods_version_notice_php() { * @since 1.10 */ function pods_version_notice_mysql() { - global $wpdb; $mysql = $wpdb->db_version(); ?> @@ -1360,20 +1631,17 @@ function pods_version_notice_mysql() { * @since 1.12 */ function pods_function_or_file( $function_or_file, $function_name = null, $file_dir = null, $file_name = null ) { - $found = false; $function_or_file = (string) $function_or_file; if ( false !== $function_name ) { if ( null === $function_name ) { $function_name = $function_or_file; } - $function_name = str_replace( - array( - '__', - '__', - '__', - ), '_', preg_replace( '/[^a-z^A-Z^_][^a-z^A-Z^0-9^_]*/', '_', (string) $function_name ) - ); + $function_name = str_replace( array( + '__', + '__', + '__', + ), '_', preg_replace( '/[^a-z^A-Z^_][^a-z^A-Z^0-9^_]*/', '_', (string) $function_name ) ); if ( function_exists( 'pods_custom_' . $function_name ) ) { $found = array( 'function' => 'pods_custom_' . $function_name ); } elseif ( function_exists( $function_name ) ) { @@ -1384,13 +1652,11 @@ function pods_function_or_file( $function_or_file, $function_name = null, $file_ if ( null === $file_name ) { $file_name = $function_or_file; } - $file_name = str_replace( - array( + $file_name = str_replace( array( '__', '__', '__', - ), '_', preg_replace( '/[^a-z^A-Z^0-9^_]*/', '_', (string) $file_name ) - ) . '.php'; + ), '_', preg_replace( '/[^a-z^A-Z^0-9^_]*/', '_', (string) $file_name ) ) . '.php'; $custom_location = apply_filters( 'pods_file_directory', null, $function_or_file, $function_name, $file_dir, $file_name ); if ( defined( 'PODS_FILE_DIRECTORY' ) && false !== PODS_FILE_DIRECTORY ) { $custom_location = PODS_FILE_DIRECTORY; @@ -1421,7 +1687,6 @@ function pods_function_or_file( $function_or_file, $function_name = null, $file_ * @since 2.0.0 */ function pods_redirect( $location, $status = 302, $die = true ) { - if ( ! headers_sent() ) { wp_redirect( $location, $status ); if ( $die ) { @@ -1438,104 +1703,31 @@ function pods_redirect( $location, $status = 302, $die = true ) { /** * Check if a user has permission to be doing something based on standard permission options * - * @param array $options + * @param array|Whatsit $object The object data. * - * @return bool Whether the user has permissions + * @return bool Whether the user has permissions. * * @since 2.0.5 */ -function pods_permission( $options ) { +function pods_permission( $object ) { + $permissions = tribe( Permissions::class ); - global $current_user; - - wp_get_current_user(); - - $permission = false; - - if ( isset( $options['options'] ) ) { - $options = $options['options']; - } - - if ( pods_is_admin() ) { - $permission = true; - } elseif ( 0 === (int) pods_v( 'restrict_role', $options, 0 ) && 0 === (int) pods_v( 'restrict_capability', $options, 0 ) && 0 === (int) pods_v( 'admin_only', $options, 0 ) ) { - $permission = true; - } - - if ( ! $permission && 1 === (int) pods_v( 'restrict_role', $options, 0 ) ) { - $roles = maybe_unserialize( pods_v( 'roles_allowed', $options ) ); - - if ( ! is_array( $roles ) ) { - $roles = explode( ',', $roles ); - } - - $roles = array_unique( array_filter( $roles ) ); - - foreach ( $roles as $role ) { - if ( is_user_logged_in() && in_array( $role, $current_user->roles, true ) ) { - $permission = true; - - break; - } - } - } - - if ( ! $permission && 1 === (int) pods_v( 'restrict_capability', $options, 0 ) ) { - $capabilities = maybe_unserialize( pods_v( 'capability_allowed', $options ) ); - - if ( ! is_array( $capabilities ) ) { - $capabilities = explode( ',', $capabilities ); - } - - $capabilities = array_unique( array_filter( $capabilities ) ); - - foreach ( $capabilities as $capability ) { - $must_have_capabilities = explode( '&&', $capability ); - $must_have_capabilities = array_unique( array_filter( $must_have_capabilities ) ); - - $must_have_permission = true; - - foreach ( $must_have_capabilities as $must_have_capability ) { - if ( ! current_user_can( $must_have_capability ) ) { - $must_have_permission = false; - - break; - } - } - - if ( $must_have_permission && is_user_logged_in() ) { - $permission = true; - - break; - } - } - }//end if - - return $permission; + return $permissions->user_has_permission( $object ); } /** - * Check if permissions are restricted + * Check if permissions are restricted for an object. * - * @param array $options + * @since 2.3.4 * - * @return bool Whether the permissions are restricted + * @param array|Whatsit $object The object data. * - * @since 2.3.4 + * @return bool Whether the permissions are restricted for an object. */ -function pods_has_permissions( $options ) { - - $permission = false; - - if ( isset( $options['options'] ) ) { - $options = $options['options']; - } +function pods_has_permissions( $object ) { + $permissions = tribe( Permissions::class ); - if ( 1 === (int) pods_v( 'restrict_role', $options, 0 ) || 1 === (int) pods_v( 'restrict_capability', $options, 0 ) || 1 === (int) pods_v( 'admin_only', $options, 0 ) ) { - return true; - } - - return false; + return $permissions->are_permissions_restricted( $object ); } /** @@ -1543,17 +1735,17 @@ function pods_has_permissions( $options ) { * * @see get_page_by_title * - * @param string $title Title of item to get - * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. - * @param string $type Post Type - * @param string|array $status Post statuses to include (default is what user has access to) + * @param string $title Title of item to get + * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. + * @param string $type Post Type + * @param string|array $status Post statuses to include (default is what user has access to) + * @param bool $return Whether to return the 'id' or 'post'. * * @return WP_Post|null WP_Post on success or null on failure * * @since 2.3.4 */ -function pods_by_title( $title, $output = OBJECT, $type = 'page', $status = null ) { - +function pods_by_title( $title, $output = OBJECT, $type = 'page', $status = null, $return = 'post' ) { // @todo support Pod item lookups, not just Post Types /** * @var $wpdb WPDB @@ -1583,10 +1775,14 @@ function pods_by_title( $title, $output = OBJECT, $type = 'page', $status = null // Once for WHERE, once for ORDER BY $prepared = array_merge( array( $title, $type ), $status, $status ); - $page = $wpdb->get_var( $wpdb->prepare( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_title` = %s AND `post_type` = %s" . $status_sql . $orderby_sql, $prepared ) ); + $page = (int) $wpdb->get_var( $wpdb->prepare( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_title` = %s AND `post_type` = %s" . $status_sql . $orderby_sql, $prepared ) ); + + if ( 0 < $page ) { + if ( 'id' === $return ) { + return $page; + } - if ( $page ) { - return get_post( pods_v( $page, 'post_id' ), $output ); + return get_post( $page, $output ); } return null; @@ -1605,7 +1801,6 @@ function pods_by_title( $title, $output = OBJECT, $type = 'page', $status = null * @since 2.1.0 */ function pods_field( $pod, $id = null, $name = null, $single = false ) { - // allow for pods_field( 'field_name' ); if ( null === $name ) { $name = $pod; @@ -1642,7 +1837,6 @@ function pods_field( $pod, $id = null, $name = null, $single = false ) { * @since 2.1.0 */ function pods_field_display( $pod, $id = null, $name = null, $single = false ) { - // allow for pods_field_display( 'field_name' ); if ( null === $name ) { $name = $pod; @@ -1679,7 +1873,6 @@ function pods_field_display( $pod, $id = null, $name = null, $single = false ) { * @since 2.1.0 */ function pods_field_raw( $pod, $id = null, $name = null, $single = false ) { - // allow for pods_field_raw( 'field_name' ); if ( null === $name ) { $name = $pod; @@ -1757,9 +1950,6 @@ function pods_field_update( $pod, $id = null, $name = null, $value = null ) { * @since 2.0.0 */ function pods_view_set( $key, $value, $expires = 0, $cache_mode = 'cache', $group = '' ) { - - require_once PODS_DIR . 'classes/PodsView.php'; - return PodsView::set( $key, $value, $expires, $cache_mode, $group ); } @@ -1778,9 +1968,6 @@ function pods_view_set( $key, $value, $expires = 0, $cache_mode = 'cache', $grou * @since 2.0.0 */ function pods_view_get( $key, $cache_mode = 'cache', $group = '', $callback = null ) { - - require_once PODS_DIR . 'classes/PodsView.php'; - return PodsView::get( $key, $cache_mode, $group, $callback ); } @@ -1798,9 +1985,6 @@ function pods_view_get( $key, $cache_mode = 'cache', $group = '', $callback = nu * @since 2.0.0 */ function pods_view_clear( $key = true, $cache_mode = 'cache', $group = '' ) { - - require_once PODS_DIR . 'classes/PodsView.php'; - return PodsView::clear( $key, $cache_mode, $group ); } @@ -1819,7 +2003,6 @@ function pods_view_clear( $key = true, $cache_mode = 'cache', $group = '' ) { * @since 2.0.0 */ function pods_cache_set( $key, $value, $group = '', $expires = 0 ) { - return pods_view_set( $key, $value, $expires, 'cache', $group ); } @@ -1837,7 +2020,6 @@ function pods_cache_set( $key, $value, $group = '', $expires = 0 ) { * @since 2.0.0 */ function pods_cache_get( $key, $group = '', $callback = null ) { - return pods_view_get( $key, 'cache', $group, $callback ); } @@ -1854,7 +2036,6 @@ function pods_cache_get( $key, $group = '', $callback = null ) { * @since 2.0.0 */ function pods_cache_clear( $key = true, $group = '' ) { - return pods_view_clear( $key, 'cache', $group ); } @@ -1872,7 +2053,6 @@ function pods_cache_clear( $key = true, $group = '' ) { * @since 2.0.0 */ function pods_transient_set( $key, $value, $expires = 0 ) { - return pods_view_set( $key, $value, $expires, 'transient' ); } @@ -1889,7 +2069,6 @@ function pods_transient_set( $key, $value, $expires = 0 ) { * @since 2.0.0 */ function pods_transient_get( $key, $callback = null ) { - return pods_view_get( $key, 'transient', '', $callback ); } @@ -1905,7 +2084,6 @@ function pods_transient_get( $key, $callback = null ) { * @since 2.0.0 */ function pods_transient_clear( $key = true ) { - return pods_view_clear( $key, 'transient' ); } @@ -1923,7 +2101,6 @@ function pods_transient_clear( $key = true ) { * @since 2.3.10 */ function pods_site_transient_set( $key, $value, $expires = 0 ) { - return pods_view_set( $key, $value, $expires, 'site-transient' ); } @@ -1940,7 +2117,6 @@ function pods_site_transient_set( $key, $value, $expires = 0 ) { * @since 2.3.10 */ function pods_site_transient_get( $key, $callback = null ) { - return pods_view_get( $key, 'site-transient', '', $callback ); } @@ -1956,7 +2132,6 @@ function pods_site_transient_get( $key, $callback = null ) { * @since 2.3.10 */ function pods_site_transient_clear( $key = true ) { - return pods_view_clear( $key, 'site-transient' ); } @@ -1975,7 +2150,6 @@ function pods_site_transient_clear( $key = true ) { * @since 2.3.10 */ function pods_option_cache_set( $key, $value, $expires = 0, $group = '' ) { - return pods_view_set( $key, $value, $expires, 'option-cache', $group ); } @@ -1993,7 +2167,6 @@ function pods_option_cache_set( $key, $value, $expires = 0, $group = '' ) { * @since 2.3.10 */ function pods_option_cache_get( $key, $group = '', $callback = null ) { - return pods_view_get( $key, 'option-cache', $group, $callback ); } @@ -2010,7 +2183,6 @@ function pods_option_cache_get( $key, $group = '', $callback = null ) { * @since 2.3.10 */ function pods_option_cache_clear( $key = true, $group = '' ) { - return pods_view_clear( $key, 'option-cache', $group ); } @@ -2028,7 +2200,6 @@ function pods_option_cache_clear( $key = true, $group = '' ) { * @since 2.3.9 */ function pods_template_part( $template, $data = null, $return = false ) { - $part = PodsView::get_template_part( $template, $data ); if ( ! $return ) { @@ -2053,7 +2224,6 @@ function pods_template_part( $template, $data = null, $return = false ) { * @since 2.1.0 */ function pods_register_type( $type, $name, $object = null ) { - if ( empty( $object ) ) { $object = array(); } @@ -2078,7 +2248,6 @@ function pods_register_type( $type, $name, $object = null ) { * @since 2.1.0 */ function pods_register_field( $pod, $name, $field = null ) { - if ( empty( $field ) ) { $field = array(); } @@ -2102,7 +2271,6 @@ function pods_register_field( $pod, $name, $field = null ) { * @since 2.3.0 */ function pods_register_field_type( $type, $file = null ) { - return PodsForm::register_field_type( $type, $file ); } @@ -2117,51 +2285,177 @@ function pods_register_field_type( $type, $file = null ) { * @since 2.3.0 */ function pods_register_related_object( $name, $label, $options = null ) { - return PodsForm::field_method( 'pick', 'register_related_object', $name, $label, $options ); } /** - * Require a component (always-on) + * Register an object with Pods. * - * @param string $component Component ID + * @since 2.8.0 * - * @return void + * @param array $object The object configuration. + * @param string $type The object type. * - * @since 2.3.0 + * @return true|WP_Error True if successful, or else an WP_Error with the problem. */ -function pods_require_component( $component ) { +function pods_register_object( array $object, $type ) { + $object['object_type'] = $type; + $object['storage_type'] = 'collection'; - add_filter( 'pods_component_require_' . $component, '__return_true' ); + $object_collection = Store::get_instance(); + $object_collection->register_object( $object ); + + return true; } /** - * Add a meta group of fields to add/edit forms - * - * @see PodsMeta::group_add + * Register a group and it's fields with Pods. * - * @param string|array $pod The pod or type of element to attach the group to. - * @param string $label Title of the edit screen section, visible to user. - * @param string|array $fields Either a comma separated list of text fields or an associative array containing field - * information. - * @param string $context (optional) The part of the page where the edit screen section should be shown - * ('normal', 'advanced', or 'side'). - * @param string $priority (optional) The priority within the context where the boxes should show ('high', - * 'core', 'default' or 'low'). - * @param string $type (optional) Type of the post to attach to. + * @since 2.8.0 * - * @return void + * @param array $group The group configuration. + * @param string $pod The pod to register to. + * @param array $field The list of group fields. * - * @since 2.0.0 - * @link https://pods.io/docs/pods-group-add/ + * @return true|WP_Error True if successful, or else an WP_Error with the problem. */ -function pods_group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default', $type = null ) { +function pods_register_group( array $group, $pod, array $fields ) { + $group['parent'] = 'pod/' . $pod; - if ( ! is_array( $pod ) && null !== $type ) { - $pod = array( - 'name' => $pod, - 'type' => $type, - ); + pods_register_object( $group, 'group' ); + + foreach ( $fields as $field ) { + pods_register_group_field( $field, $group['name'], $pod ); + } + + return true; +} + +/** + * Register a field with Pods. + * + * @since 2.8.0 + * + * @param array $field The field configuration. + * @param string $group The group to register to. + * @param string $pod The pod to register to. + * + * @return true|WP_Error True if successful, or else an WP_Error with the problem. + */ +function pods_register_group_field( array $field, $group, $pod ) { + $field['parent'] = 'pod/' . $pod; + $field['group'] = $group; + + pods_register_object( $field, 'field' ); + + return true; +} + +/** + * Register a block type with Pods. Always register during the `pods_blocks_api_init` action. + * + * @since 2.8.0 + * + * @param array $block The block configuration, compatible with `register_block_type()`. + * @param array $fields List of fields to use for inspector controls. + * + * @return true|WP_Error True if successful, or else an WP_Error with the problem. + * + * @see register_block_type + * @see Pods\Blocks\Types\Base + */ +function pods_register_block_type( array $block, array $fields = [] ) { + if ( empty( $block['namespace'] ) ) { + return new WP_Error( 'pods-blocks-api-block-type-invalid', __( 'Invalid block type configuration provided', 'pods' ) ); + } + + $block['object_type'] = 'block'; + $block['storage_type'] = 'collection'; + $block['name'] = pods_v( 'name', $block, pods_v( 'slug', $block ) ); + $block['label'] = pods_v( 'label', $block, pods_v( 'title', $block ) ); + $block['category'] = pods_v( 'category', $block, pods_v( 'collection', $block ) ); + + $object_collection = Store::get_instance(); + $object_collection->register_object( $block ); + + foreach ( $fields as $field ) { + $field['object_type'] = 'block-field'; + $field['storage_type'] = 'collection'; + $field['parent'] = 'block/' . $block['name']; + $field['name'] = pods_v( 'name', $field, pods_v( 'slug', $field ) ); + $field['label'] = pods_v( 'label', $field, pods_v( 'title', $field ) ); + + $object_collection->register_object( $field ); + } + + return true; +} + +/** + * Register a block collection with Pods. Always register during the `pods_blocks_api_init` action. + * + * @since 2.8.0 + * + * @param array $collection The block collection configuration, compatible with `block_categories` filter. + * + * @return true|WP_Error True if successful, or else an WP_Error with the problem. + * + * @see Pods\Blocks\Collections\Base + */ +function pods_register_block_collection( array $collection ) { + if ( empty( $collection['namespace'] ) ) { + return new WP_Error( 'pods-blocks-api-block-collection-invalid', __( 'Invalid block collection configuration provided', 'pods' ) ); + } + + $collection['object_type'] = 'block-collection'; + $collection['storage_type'] = 'collection'; + $collection['label'] = pods_v( 'label', $collection, pods_v( 'title', $collection ) ); + + $object_collection = Store::get_instance(); + $object_collection->register_object( $collection ); + + return true; +} + +/** + * Require a component (always-on) + * + * @param string $component Component ID + * + * @return void + * + * @since 2.3.0 + */ +function pods_require_component( $component ) { + add_filter( 'pods_component_require_' . $component, '__return_true' ); +} + +/** + * Add a meta group of fields to add/edit forms + * + * @see PodsMeta::group_add + * + * @param string|array $pod The pod or type of element to attach the group to. + * @param string $label Title of the edit screen section, visible to user. + * @param string|array $fields Either a comma separated list of text fields or an associative array containing field + * information. + * @param string $context (optional) The part of the page where the edit screen section should be shown + * ('normal', 'advanced', or 'side'). + * @param string $priority (optional) The priority within the context where the boxes should show ('high', + * 'core', 'default' or 'low'). + * @param string $type (optional) Type of the post to attach to. + * + * @return void + * + * @since 2.0.0 + * @link https://docs.pods.io/code/general-functions/pods-group-add/ + */ +function pods_group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default', $type = null ) { + if ( ! is_array( $pod ) && ! $pod instanceof Pods\Whatsit && null !== $type ) { + $pod = array( + 'name' => $pod, + 'type' => $type, + ); } pods_meta()->group_add( $pod, $label, $fields, $context, $priority ); @@ -2177,7 +2471,6 @@ function pods_group_add( $pod, $label, $fields, $context = 'normal', $priority = * @since 2.0.0 */ function pods_is_plugin_active( $plugin ) { - $active = false; if ( function_exists( 'is_plugin_active' ) ) { @@ -2213,7 +2506,6 @@ function pods_is_plugin_active( $plugin ) { * @since 2.3.0 */ function pods_no_conflict_check( $object_type = 'post' ) { - if ( 'post_type' === $object_type ) { $object_type = 'post'; } elseif ( 'term' === $object_type ) { @@ -2232,178 +2524,259 @@ function pods_no_conflict_check( $object_type = 'post' ) { } /** - * Turn off conflicting / recursive actions for an object type that Pods hooks into + * Get the list of meta hooks to add/remove for a specific object type. * - * @param string $object_type - * @param string $object + * @since 2.8.0 * - * @return bool + * @param string $object_type The object type. + * @param string|null $object The object name. * - * @since 2.0.0 + * @return array List of filters and actions for a specific object type. */ -function pods_no_conflict_on( $object_type = 'post', $object = null ) { - +function pods_meta_hook_list( $object_type = 'post', $object = null ) { if ( 'post_type' === $object_type ) { $object_type = 'post'; } elseif ( 'term' === $object_type ) { $object_type = 'taxonomy'; } - if ( ! class_exists( 'PodsInit' ) ) { - pods_init(); - } - - if ( ! empty( PodsInit::$no_conflict[ $object_type ] ) ) { - return true; - } - - if ( ! is_object( PodsInit::$meta ) ) { - return false; - } - - $no_conflict = array( - 'filter' => array(), - ); + $hooks = [ + 'filter' => [], + 'action' => [], + ]; // Filters = Usually get/update/delete meta functions // Actions = Usually insert/update/save/delete object functions - if ( 'post' === $object_type ) { + if ( 'post' === $object_type || 'media' === $object_type || 'all' === $object_type ) { + // Handle *_post_meta if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) { - // Handle *_post_meta if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) { - $no_conflict['filter'] = array( - array( 'get_post_metadata', array( PodsInit::$meta, 'get_post_meta' ), 10, 4 ), - ); + $hooks['filter']['get_post_metadata'] = [ 'get_post_metadata', [ PodsInit::$meta, 'get_post_meta' ], 10, 4 ]; } if ( ! pods_tableless() ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'add_post_metadata', array( PodsInit::$meta, 'add_post_meta' ), 10, 5 ), - array( 'update_post_metadata', array( PodsInit::$meta, 'update_post_meta' ), 10, 5 ), - array( 'delete_post_metadata', array( PodsInit::$meta, 'delete_post_meta' ), 10, 5 ), - ) - ); + $hooks['filter']['add_post_metadata'] = [ 'add_post_metadata', [ PodsInit::$meta, 'add_post_meta' ], 10, 5 ]; + $hooks['filter']['update_post_metadata'] = [ 'update_post_metadata', [ PodsInit::$meta, 'update_post_meta' ], 10, 5 ]; + $hooks['filter']['update_post_metadata_by_id'] = [ 'update_post_metadata_by_id', [ PodsInit::$meta, 'update_post_meta_by_id' ], 10, 4 ]; + $hooks['filter']['delete_post_metadata'] = [ 'delete_post_metadata', [ PodsInit::$meta, 'delete_post_meta' ], 10, 5 ]; + $hooks['filter']['delete_post_metadata_by_id'] = [ 'delete_post_metadata_by_id', [ PodsInit::$meta, 'delete_post_meta_by_id' ], 10, 2 ]; } } - $no_conflict['action'] = array( - array( 'transition_post_status', array( PodsInit::$meta, 'save_post_detect_new' ), 10, 3 ), - array( 'save_post', array( PodsInit::$meta, 'save_post' ), 10, 3 ), - array( 'wp_insert_post_data', array( PodsInit::$meta, 'save_post_track_changed_fields' ), 10, 2 ), - ); - } elseif ( 'taxonomy' === $object_type ) { + // Add meta box groups. + $hooks['action'][] = [ 'add_meta_boxes', [ PodsInit::$meta, 'meta_post_add' ], 10, 1 ]; + + // Other post-related hooks. + $hooks['filter'][] = [ 'enter_title_here', [ PodsInit::$meta, 'meta_post_enter_title_here' ], 10, 2 ]; + $hooks['filter'][] = [ 'wp_revisions_to_keep', [ PodsInit::$meta, 'meta_post_revisions_to_keep' ], 10, 2 ]; + + if ( 'post' === $object_type || 'all' === $object_type ) { + // Handle detecting new post. + $hooks['action'][] = [ 'transition_post_status', [ PodsInit::$meta, 'save_post_detect_new' ], 10, 3 ]; + + // Handle save. + $hooks['action'][] = [ 'save_post', [ PodsInit::$meta, 'save_post' ], 10, 3 ]; + + // Handle delete from relationships. + $hooks['action'][] = [ 'delete_post', [ PodsInit::$meta, 'delete_post' ], 10, 1 ]; + + // Track changed fields. + $hooks['action'][] = [ + 'wp_insert_post_data', + [ PodsInit::$meta, 'save_post_track_changed_fields' ], + 10, + 2, + ]; + } + } + + if ( 'taxonomy' === $object_type || 'all' === $object_type ) { + // Handle *_term_meta if ( apply_filters( 'pods_meta_handler', true, 'term' ) ) { - // Handle *_term_meta if ( apply_filters( 'pods_meta_handler_get', true, 'term' ) ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'get_term_metadata', array( PodsInit::$meta, 'get_term_meta' ), 10, 4 ), - ) - ); + $hooks['filter'][] = [ 'get_term_metadata', [ PodsInit::$meta, 'get_term_meta' ], 10, 4 ]; } if ( ! pods_tableless() ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'add_term_metadata', array( PodsInit::$meta, 'add_term_meta' ), 10, 5 ), - array( 'update_term_metadata', array( PodsInit::$meta, 'update_term_meta' ), 10, 5 ), - array( 'delete_term_metadata', array( PodsInit::$meta, 'delete_term_meta' ), 10, 5 ), - ) - ); + $hooks['filter']['add_term_metadata'] = [ 'add_term_metadata', [ PodsInit::$meta, 'add_term_meta' ], 10, 5 ]; + $hooks['filter']['update_term_metadata'] = [ 'update_term_metadata', [ PodsInit::$meta, 'update_term_meta' ], 10, 5 ]; + $hooks['filter']['update_term_metadata_by_id'] = [ 'update_term_metadata_by_id', [ PodsInit::$meta, 'update_term_meta_by_id' ], 10, 4 ]; + $hooks['filter']['delete_term_metadata'] = [ 'delete_term_metadata', [ PodsInit::$meta, 'delete_term_meta' ], 10, 5 ]; + $hooks['filter']['delete_term_metadata_by_id'] = [ 'delete_term_metadata_by_id', [ PodsInit::$meta, 'delete_term_meta_by_id' ], 10, 2 ]; } + } - $no_conflict['action'] = array( - array( 'edited_term', array( PodsInit::$meta, 'save_taxonomy' ), 10, 3 ), - array( 'create_term', array( PodsInit::$meta, 'save_taxonomy' ), 10, 3 ), - array( 'edit_terms', array( PodsInit::$meta, 'save_taxonomy_track_changed_fields' ), 10, 2 ), - ); - }//end if - } elseif ( 'media' === $object_type ) { - $no_conflict['filter'] = array( - array( 'attachment_fields_to_save', array( PodsInit::$meta, 'save_media' ), 10, 2 ), - array( 'wp_update_attachment_metadata', array( PodsInit::$meta, 'save_media' ), 10, 2 ), - array( 'wp_insert_attachment_data', array( PodsInit::$meta, 'save_post_track_changed_fields' ), 10, 2 ), - ); + // Handle save. + $hooks['action'][] = [ 'edited_term', [ PodsInit::$meta, 'save_taxonomy' ], 10, 3 ]; + $hooks['action'][] = [ 'create_term', [ PodsInit::$meta, 'save_taxonomy' ], 10, 3 ]; - if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) { - // Handle *_post_meta - if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'get_post_metadata', array( PodsInit::$meta, 'get_post_meta' ), 10, 4 ), - ) - ); - } + // Handle delete from relationships. + $hooks['action'][] = [ 'delete_term_taxonomy', [ PodsInit::$meta, 'delete_taxonomy' ], 10, 1 ]; - if ( ! pods_tableless() ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'add_post_metadata', array( PodsInit::$meta, 'add_post_meta' ), 10, 5 ), - array( 'update_post_metadata', array( PodsInit::$meta, 'update_post_meta' ), 10, 5 ), - array( 'delete_post_metadata', array( PodsInit::$meta, 'delete_post_meta' ), 10, 5 ), - ) - ); - } + // Handle form fields specific to the taxonomy. + if ( $object ) { + $hooks['action'][] = [ $object . '_edit_form_fields', [ PodsInit::$meta, 'meta_taxonomy' ], 10, 2 ]; + $hooks['action'][] = [ $object . '_add_form_fields', [ PodsInit::$meta, 'meta_taxonomy' ], 10, 1 ]; + } - $no_conflict['action'] = array(); - }//end if - } elseif ( 'user' === $object_type ) { + // Track changed fields. + $hooks['action'][] = [ + 'edit_terms', + [ PodsInit::$meta, 'save_taxonomy_track_changed_fields' ], + 10, + 2, + ]; + + /** + * Fires after a previously shared taxonomy term is split into two separate terms. + * + * @since 4.2.0 + * + * @param int $term_id ID of the formerly shared term. + * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. + * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. + * @param string $taxonomy Taxonomy for the split term. + */ + $hooks['action'][] = [ 'split_shared_term', [ PodsInit::$meta, 'split_shared_term' ], 10, 4 ]; + } + + if ( 'media' === $object_type || 'all' === $object_type ) { + // Handle old AJAX attachment saving. + $hooks['action'][] = [ 'wp_ajax_save-attachment-compat', [ PodsInit::$meta, 'save_media_ajax' ], 0, 1 ]; + + // Handle showing meta fields in modal. + $hooks['filter'][] = [ 'attachment_fields_to_edit', [ PodsInit::$meta, 'meta_media' ], 10, 2 ]; + + // Handle saving meta fields from modal. + $hooks['filter'][] = [ 'attachment_fields_to_save', [ PodsInit::$meta, 'save_media' ], 10, 2 ]; + + // Handle saving attachment metadata. + $hooks['filter'][] = [ 'wp_update_attachment_metadata', [ PodsInit::$meta, 'save_media' ], 10, 2 ]; + + // Handle delete. + $hooks['action'][] = [ 'delete_attachment', [ PodsInit::$meta, 'delete_media' ], 10, 1 ]; + + // Track changed fields. + $hooks['filter'][] = [ + 'wp_insert_attachment_data', + [ PodsInit::$meta, 'save_post_track_changed_fields' ], + 10, + 2, + ]; + } + + if ( 'user' === $object_type || 'all' === $object_type ) { + // Handle *_user_meta. if ( apply_filters( 'pods_meta_handler', true, 'user' ) ) { - // Handle *_term_meta if ( apply_filters( 'pods_meta_handler_get', true, 'user' ) ) { - $no_conflict['filter'] = array( - array( 'get_user_metadata', array( PodsInit::$meta, 'get_user_meta' ), 10, 4 ), - ); + $hooks['filter'][] = [ 'get_user_metadata', [ PodsInit::$meta, 'get_user_meta' ], 10, 4 ]; } if ( ! pods_tableless() ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'add_user_metadata', array( PodsInit::$meta, 'add_user_meta' ), 10, 5 ), - array( 'update_user_metadata', array( PodsInit::$meta, 'update_user_meta' ), 10, 5 ), - array( 'delete_user_metadata', array( PodsInit::$meta, 'delete_user_meta' ), 10, 5 ), - ) - ); + $hooks['filter']['add_user_metadata'] = [ 'add_user_metadata', [ PodsInit::$meta, 'add_user_meta' ], 10, 5 ]; + $hooks['filter']['update_user_metadata'] = [ 'update_user_metadata', [ PodsInit::$meta, 'update_user_meta' ], 10, 5 ]; + $hooks['filter']['update_user_metadata_by_id'] = [ 'update_user_metadata_by_id', [ PodsInit::$meta, 'update_user_meta_by_id' ], 10, 4 ]; + $hooks['filter']['delete_user_metadata'] = [ 'delete_user_metadata', [ PodsInit::$meta, 'delete_user_meta' ], 10, 5 ]; + $hooks['filter']['delete_user_metadata_by_id'] = [ 'delete_user_metadata_by_id', [ PodsInit::$meta, 'delete_user_meta_by_id' ], 10, 2 ]; } } - $no_conflict['action'] = array( - array( 'user_register', array( PodsInit::$meta, 'save_user' ) ), - array( 'profile_update', array( PodsInit::$meta, 'save_user' ), 10, 2 ), - array( 'pre_user_login', array( PodsInit::$meta, 'save_user_track_changed_fields' ) ), - ); - } elseif ( 'comment' === $object_type ) { + // Handle showing fields in form. + $hooks['action'][] = [ 'show_user_profile', [ PodsInit::$meta, 'meta_user' ], 10, 1 ]; + $hooks['action'][] = [ 'edit_user_profile', [ PodsInit::$meta, 'meta_user' ], 10, 1 ]; + + // Handle saving from registration form. + $hooks['action'][] = [ 'user_register', [ PodsInit::$meta, 'save_user' ], 10, 1 ]; + + // Handle saving from profile update. + $hooks['action'][] = [ 'profile_update', [ PodsInit::$meta, 'save_user' ], 10, 2 ]; + + // Track changed fields. + $hooks['filter'][] = [ 'pre_user_login', [ PodsInit::$meta, 'save_user_track_changed_fields' ], 10, 1 ]; + } + + if ( 'comment' === $object_type || 'all' === $object_type ) { if ( apply_filters( 'pods_meta_handler', true, 'comment' ) ) { - // Handle *_term_meta + // Handle *_comment_meta if ( apply_filters( 'pods_meta_handler_get', true, 'comment' ) ) { - $no_conflict['filter'] = array( - array( 'get_comment_metadata', array( PodsInit::$meta, 'get_comment_meta' ), 10, 4 ), - ); + $hooks['filter'][] = [ 'get_comment_metadata', [ PodsInit::$meta, 'get_comment_meta' ], 10, 4 ]; } if ( ! pods_tableless() ) { - $no_conflict['filter'] = array_merge( - $no_conflict['filter'], array( - array( 'add_comment_metadata', array( PodsInit::$meta, 'add_comment_meta' ), 10, 5 ), - array( 'update_comment_metadata', array( PodsInit::$meta, 'update_comment_meta' ), 10, 5 ), - array( 'delete_comment_metadata', array( PodsInit::$meta, 'delete_comment_meta' ), 10, 5 ), - ) - ); + $hooks['filter']['add_comment_metadata'] = [ 'add_comment_metadata', [ PodsInit::$meta, 'add_comment_meta' ], 10, 5 ]; + $hooks['filter']['update_comment_metadata'] = [ 'update_comment_metadata', [ PodsInit::$meta, 'update_comment_meta' ], 10, 5 ]; + $hooks['filter']['update_comment_metadata_by_id'] = [ 'update_comment_metadata_by_id', [ PodsInit::$meta, 'update_comment_meta_by_id' ], 10, 4 ]; + $hooks['filter']['delete_comment_metadata'] = [ 'delete_comment_metadata', [ PodsInit::$meta, 'delete_comment_meta' ], 10, 5 ]; + $hooks['filter']['delete_comment_metadata_by_id'] = [ 'delete_comment_metadata_by_id', [ PodsInit::$meta, 'delete_comment_meta_by_id' ], 10, 2 ]; } } - $no_conflict['action'] = array( - array( 'pre_comment_approved', array( PodsInit::$meta, 'validate_comment' ), 10, 2 ), - array( 'comment_post', array( PodsInit::$meta, 'save_comment' ) ), - array( 'edit_comment', array( PodsInit::$meta, 'save_comment' ) ), - array( 'wp_update_comment_data', array( PodsInit::$meta, 'save_comment_track_changed_fields' ), 10, 3 ), - ); - } elseif ( 'settings' === $object_type ) { - $no_conflict['filter'] = array(); + // Handle showing fields in form. + $hooks['action'][] = [ 'comment_form_logged_in_after', [ PodsInit::$meta, 'meta_comment_new_logged_in' ], 10, 2 ]; + $hooks['filter'][] = [ 'comment_form_default_fields', [ PodsInit::$meta, 'meta_comment_new' ], 10, 1 ]; - // @todo Better handle settings conflicts apart from each other - }//end if + // Add meta box groups. + $hooks['action'][] = [ 'add_meta_boxes_comment', [ PodsInit::$meta, 'meta_comment_add' ], 10, 1 ]; + + // Handle validation for fields. + $hooks['filter'][] = [ 'pre_comment_approved', [ PodsInit::$meta, 'validate_comment' ], 10, 2 ]; + + // Handle saving comment from frontend. + $hooks['action'][] = [ 'comment_post', [ PodsInit::$meta, 'save_comment' ], 10, 1 ]; + + // Handle saving comment from admin. + $hooks['action'][] = [ 'edit_comment', [ PodsInit::$meta, 'save_comment' ], 10, 1 ]; + + // Track changed fields. + $hooks['action'][] = [ 'wp_update_comment_data', [ PodsInit::$meta, 'save_comment_track_changed_fields' ], 10, 3 ]; + } + + if ( 'settings' === $object_type || 'all' === $object_type ) { + // @todo Patch core to provide $option back in filters, patch core to add filter pre_add_option to add_option. + + // Undesirable way to do things which is heavy and requires access to looping through all fields, pulled from PodsMeta::core(). + /*foreach ( self::$settings as $setting_pod ) { + foreach ( $setting_pod[ 'fields' ] as $option ) { + add_filter( 'pre_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( PodsInit::$meta, 'get_option' ), 10, 1 ); + add_action( 'add_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( PodsInit::$meta, 'add_option' ), 10, 2 ); + add_filter( 'pre_update_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( PodsInit::$meta, 'update_option' ), 10, 2 ); + } + }*/ + } + + return $hooks; +} + +/** + * Turn off conflicting / recursive actions for an object type that Pods hooks into + * + * @since 2.0.0 + * + * @param string $object_type The object type. + * @param string|null $object The object name. + * + * @return bool Whether no conflict mode was turned on. + */ +function pods_no_conflict_on( $object_type = 'post', $object = null ) { + if ( 'post_type' === $object_type ) { + $object_type = 'post'; + } elseif ( 'term' === $object_type ) { + $object_type = 'taxonomy'; + } + + if ( ! class_exists( 'PodsInit' ) ) { + pods_init(); + } + + if ( ! empty( PodsInit::$no_conflict[ $object_type ] ) ) { + return true; + } + + if ( ! is_object( PodsInit::$meta ) ) { + return false; + } + + $no_conflict = pods_meta_hook_list( $object_type ); $conflicted = false; @@ -2426,20 +2799,20 @@ function pods_no_conflict_on( $object_type = 'post', $object = null ) { } return false; - } /** * Turn on actions after running code during pods_conflict * - * @param string $object_type + * @since 2.0.0 * - * @return bool + * @param string $object_type The object type. + * @param string|null $object The object name. + * @param bool $force Whether to force turning all hooks back on even if they were already off. * - * @since 2.0.0 + * @return bool Whether no conflict mode was on and was successfully turned off. */ -function pods_no_conflict_off( $object_type = 'post' ) { - +function pods_no_conflict_off( $object_type = 'post', $object = null, $force = false ) { if ( 'post_type' === $object_type ) { $object_type = 'post'; } elseif ( 'term' === $object_type ) { @@ -2450,15 +2823,22 @@ function pods_no_conflict_off( $object_type = 'post' ) { pods_init(); } - if ( empty( PodsInit::$no_conflict[ $object_type ] ) ) { - return false; - } - if ( ! is_object( PodsInit::$meta ) ) { return false; } - $no_conflict = PodsInit::$no_conflict[ $object_type ]; + if ( $force ) { + // Turn ALL hooks back on. + $no_conflict = pods_meta_hook_list( $object_type, $object ); + } else { + // No conflict mode was not already on. + if ( empty( PodsInit::$no_conflict[ $object_type ] ) ) { + return false; + } + + // Only turn on the hooks we turned off for no conflict mode. + $no_conflict = PodsInit::$no_conflict[ $object_type ]; + } $conflicted = false; @@ -2472,6 +2852,10 @@ function pods_no_conflict_off( $object_type = 'post' ) { } } + if ( isset( PodsInit::$no_conflict['all'] ) ) { + unset( PodsInit::$no_conflict['all'] ); + } + if ( $conflicted ) { unset( PodsInit::$no_conflict[ $object_type ] ); @@ -2593,31 +2977,123 @@ function pods_reserved_keywords() { } /** - * Safely start a new session (without whitescreening on certain hosts, - * which have no session path or isn't writable) + * Get the value for a Pods setting. * - * @since 2.3.10 + * @since 2.8.0 + * + * @param string $setting_name The setting name. + * @param null $default The default value if the setting is not yet set. + * + * @return mixed The setting value. */ -function pods_session_start() { +function pods_get_setting( $setting_name, $default = null ) { + $settings = tribe( Settings::class ); - $save_path = session_save_path(); + return $settings->get_setting( $setting_name, $default ); +} - if ( false !== headers_sent() ) { - // Check if headers were sent. - return false; - } elseif ( false !== is_user_logged_in() ) { - // We do not need a session ID if there is a valid user logged in - return false; - } elseif ( defined( 'PODS_SESSION_AUTO_START' ) && ! PODS_SESSION_AUTO_START ) { - // Allow for bypassing Pods session autostarting. - return false; - } elseif ( ! defined( 'PANTHEON_SESSIONS_ENABLED' ) || ! PANTHEON_SESSIONS_ENABLED ) { +/** + * Get the Pods settings. + * + * @since 2.8.0 + * + * @return array The setting values. + */ +function pods_get_settings() { + $settings = tribe( Settings::class ); + + return $settings->get_settings(); +} + +/** + * Update the value for a Pods setting. + * + * @since 2.8.0 + * + * @param string $setting_name The setting name. + * @param mixed $setting_value The setting value. + */ +function pods_update_setting( $setting_name, $setting_value ) { + $settings = tribe( Settings::class ); + + $settings->update_setting( $setting_name, $setting_value ); +} + +/** + * Update the settings for a Pods. + * + * @since 2.8.0 + * + * @param array $setting_values The list of settings to update, pass null as a value to remove it. + */ +function pods_update_settings( $setting_values ) { + $settings = tribe( Settings::class ); + + $settings->update_settings( $setting_values ); +} + +/** + * Determine if Session Auto Start is enabled. + * + * @param bool $check_constant_only Whether to only check the constant. + * + * @since 2.8.0 + * + * @return bool|string|null Boolean if it is set to on or off, "auto" if set to auto, and null if $check_constant_only and constant is not set. + */ +function pods_session_auto_start( $check_constant_only = false ) { + if ( defined( 'PODS_SESSION_AUTO_START' ) ) { + return PODS_SESSION_AUTO_START; + } + + if ( $check_constant_only ) { + return null; + } + + $auto_start = pods_get_setting( 'session_auto_start', 'auto' ); + + // Check for "auto" string and return that. + if ( 'auto' === $auto_start ) { + return $auto_start; + } + + return FILTER_VAR( $auto_start, FILTER_VALIDATE_BOOLEAN ); +} + +/** + * Determine if we can use PHP sessions. + * + * @since 2.8.0 + * + * @param bool $only_env_check Whether to ignore constant/option/logged in checks. + * + * @return bool Whether we can use sessions. + */ +function pods_can_use_sessions( $only_env_check = false ) { + // Maybe check non-environment factors. + if ( ! $only_env_check ) { + // We do not need a session ID if there is a valid user logged in. + if ( is_user_logged_in() ) { + return false; + } + + // Allow for bypassing Pods session auto-starting. + if ( ! pods_session_auto_start() ) { + return false; + } + } + + if ( ! defined( 'PANTHEON_SESSIONS_ENABLED' ) || ! PANTHEON_SESSIONS_ENABLED ) { // We aren't using Pantheon WP Native Sessions plugin so let's check if the normal session will work. - if ( function_exists( 'session_status' ) && PHP_SESSION_DISABLED === session_status() ) { + $save_path = session_save_path(); + + if ( ! function_exists( 'session_status' ) || PHP_SESSION_DISABLED === session_status() ) { // Sessions are disabled. return false; - } elseif ( 0 === strpos( $save_path, 'tcp://' ) ) { + } + + if ( 0 === strpos( $save_path, 'tcp://' ) ) { // Allow for non-file based sessions, like Memcache. // This is OK, but we don't want to check if file_exists on next statement. } elseif ( empty( $save_path ) || ! @file_exists( $save_path ) || ! is_writable( $save_path ) ) { @@ -2628,21 +3104,32 @@ function pods_session_start() { // Check if session is already set. // In separate if clause, to also check for non-file based sessions. - if ( function_exists( 'session_status' ) ) { // PHP >=5.4. - if ( PHP_SESSION_ACTIVE === session_status() ) { - return false; - } - } else { // PHP <5.4. - if ( pods_session_id() ) { - return false; - } + if ( ! function_exists( 'session_status' ) || PHP_SESSION_ACTIVE === session_status() ) { + return false; } - // Start session - @session_start(); - + // Allow sessions. return true; +} +/** + * Safely start a new session (without white screening on certain hosts, + * which have no session path or the path is not writable). + * + * @since 2.3.10 + * + * @return boolean Whether the session was started. + */ +function pods_session_start() { + if ( false !== headers_sent() ) { + // Check if headers were sent. + return false; + } elseif ( ! pods_can_use_sessions() ) { + return false; + } + + // Start session + return @session_start(); } /** @@ -2650,14 +3137,14 @@ function pods_session_start() { * * @since 2.7.23 * - * @return string + * @return string The session ID. */ function pods_session_id() { - if ( defined( 'PODS_SESSION_AUTO_START' ) && ! PODS_SESSION_AUTO_START ) { + if ( ! pods_can_use_sessions() ) { return ''; } - if ( function_exists( 'session_status' ) && PHP_SESSION_DISABLED === session_status() ) { + if ( ! function_exists( 'session_status' ) || PHP_SESSION_DISABLED === session_status() ) { // Sessions are disabled. return ''; } @@ -2673,7 +3160,6 @@ function pods_session_id() { * @since 2.7.0 */ function pods_is_modal_window() { - $is_modal_window = false; if ( ! empty( $_GET['pods_modal'] ) || ! empty( $_POST['pods_modal'] ) ) { @@ -2693,10 +3179,9 @@ function pods_is_modal_window() { * @since 2.7.0 */ function pod_is_valid( $pod ) { - $is_valid = false; - if ( $pod && is_a( $pod, 'Pods' ) && $pod->valid() ) { + if ( $pod && $pod instanceof Pods && $pod->valid() ) { $is_valid = true; } @@ -2713,7 +3198,6 @@ function pod_is_valid( $pod ) { * @since 2.7.0 */ function pod_has_items( $pod ) { - $has_items = false; if ( pod_is_valid( $pod ) && ( $pod->id && $pod->exists() ) || ( ! empty( $pod->params ) && 0 < $pod->total() ) ) { @@ -2722,3 +3206,261 @@ function pod_has_items( $pod ) { return $has_items; } + +/** + * Merge one config into another for purposes of overriding certain arguments. + * + * @since 2.8.0 + * + * @param array|Field $config_to_merge_into The config to merge into. + * @param array|Field $config_to_merge_from The config to merge from. + * + * @return array|Field The final config result. + */ +function pods_config_merge_data( $config_to_merge_into, $config_to_merge_from ) { + // The configs already match. + if ( $config_to_merge_into === $config_to_merge_from ) { + return $config_to_merge_into; + } + + // Merge the config into the destination config if both are Value_Field. + if ( $config_to_merge_into instanceof Value_Field && $config_to_merge_from instanceof Value_Field ) { + $field_object_into = $config_to_merge_into->get_field_object(); + $field_value_into = $config_to_merge_into->get_field_value(); + + $field_object_from = $config_to_merge_from->get_field_object(); + $field_value_from = $config_to_merge_from->get_field_value(); + + $config_to_merge_into->set_field_object( pods_config_merge_data( $field_object_into, $field_object_from ) ); + $config_to_merge_into->set_field_value( $field_value_from ); + + return $config_to_merge_into; + } + + // Merge the config into the destination config. + if ( $config_to_merge_into instanceof Whatsit ) { + return $config_to_merge_into->set_args( $config_to_merge_from ); + } + + // Merge the destination config into the config but don't replace data. + if ( $config_to_merge_from instanceof Whatsit ) { + return $config_to_merge_from->set_args( $config_to_merge_into, false ); + } + + // The config was not an array. + if ( ! is_array( $config_to_merge_from ) ) { + return $config_to_merge_into; + } + + // The config was not an array. + if ( ! is_array( $config_to_merge_into ) ) { + return $config_to_merge_from; + } + + // Merge the config arrays together. + return array_merge( $config_to_merge_into, $config_to_merge_from ); +} + +/** + * Merge multiple configs into others for purposes of overriding certain arguments. + * + * @since 2.8.0 + * + * @param array[]|Field[] $configs_to_merge_into The configs to merge into. + * @param array[]|Field[] $configs_to_merge_from The configs to merge from. + * + * @return array[]|Field[] The final config results. + */ +function pods_config_merge_fields( $configs_to_merge_into, $configs_to_merge_from ) { + // The configs already match. + if ( $configs_to_merge_into === $configs_to_merge_from ) { + return $configs_to_merge_into; + } + + foreach ( $configs_to_merge_from as $key => $config_to_merge_from ) { + if ( ! isset( $config_to_merge_into[ $key ] ) ) { + $configs_to_merge_into[ $key ] = $config_to_merge_from; + + continue; + } + + $configs_to_merge_into[ $key ] = pods_config_merge_data( $config_to_merge_into[ $key ], $config_to_merge_from ); + } + + return $configs_to_merge_into; +} + +/** + * Get the list of all fields, including object fields, from a Pod configuration. + * + * @since 2.8.0 + * + * @param array|Pod|Pods $pod The Pod configuration array or object. + * + * @return array[]|Field[] The list of all fields, including object fields. + */ +function pods_config_get_all_fields( $pod ) { + if ( $pod instanceof Pod ) { + return $pod->get_all_fields(); + } + + $fields = (array) pods_v( 'fields', $pod, [] ); + $object_fields = (array) pods_v( 'object_fields', $pod, [] ); + + return pods_config_merge_fields( $fields, $object_fields ); +} + +/** + * Get the field object from a value field object. + * + * @since 2.8.0 + * + * @param Value_Field|Field $value_field The value field object. + * + * @return Field The field object. + */ +function pods_config_get_field_from_value_field( $value_field ) { + // Maybe get the field object. + if ( $value_field instanceof Value_Field ) { + return $value_field->get_field_object(); + } + + return $value_field; +} + +/** + * Get the list of all field objects from a list of value field objects. + * + * @since 2.8.0 + * + * @param Value_Field[]|Field[] $value_fields The list of value field objects. + * + * @return Field[] The list of all field objects. + */ +function pods_config_get_fields_from_value_fields( array $value_fields ) { + $all_fields = []; + + foreach ( $value_fields as $key => $field ) { + // Maybe get the field object. + if ( $field instanceof Value_Field ) { + $field = $field->get_field_object(); + } + + if ( is_int( $key ) ) { + $all_fields[] = $field; + } else { + $all_fields[ $key ] = $field; + } + } + + return $all_fields; +} + +/** + * Get the field data for a specific field matching from all fields, including object fields, from a Pod configuration. + * + * @since 2.8.0 + * + * @param string $field The field name to get. + * @param array|Pod|Pods $pod The Pod configuration array or object. + * @param null|string $arg The field argument to use when getting the field. + * + * @return array|Field|null The field data or null if not found. + */ +function pods_config_get_field_from_all_fields( $field, $pod, $arg = null ) { + // Get the pod data from the Pods object if it's there. + if ( $pod instanceof Pods ) { + $pod = $pod->pod_data; + } + + // Get the field directly from the Pod. + if ( $pod instanceof Pod ) { + return $pod->get_field( $field, $arg ); + } + + // The pod isn't there or valid. + if ( empty( $pod ) ) { + return null; + } + + $fields = (array) pods_v( 'fields', $pod, [] ); + $object_fields = (array) pods_v( 'object_fields', $pod, [] ); + + // Return the object field. + if ( isset( $object_fields[ $field ] ) ) { + return $object_fields[ $field ]; + } + + // Return the pod field. + if ( isset( $fields[ $field ] ) ) { + return $fields[ $field ]; + } + + // No field found. + return null; +} + +/** + * Get a normalized Pod configuration. + * + * @since 2.8.0 + * + * @param Pod|Pods|string $pod The Pod configuration object, Pods() object, or name. + * + * @return false|Pod The Pod object. + */ +function pods_config_for_pod( $pod ) { + if ( $pod instanceof Pod ) { + return $pod; + } + + if ( $pod instanceof Pods ) { + // Check if the $pod is invalid. + if ( ! $pod->valid() ) { + return false; + } + + return $pod->pod_data; + } + + if ( is_string( $pod ) ) { + try { + $api = pods_api(); + + $pod = $api->load_pod( [ 'name' => $pod ] ); + } catch ( Exception $exception ) { + return false; + } + + // Check if the $pod is invalid. + if ( ! $pod ) { + return false; + } + + return $pod; + } + + // @todo Support arrays in the future by migrating them into a Pod() object. + + return false; +} + +function is_pods_alternative_cache_activated() { + return function_exists( 'pods_alternative_cache_init' ); +} + +function is_pods_alternative_cache_activated_test() { + $result = [ + 'label' => __( 'You are using the Pods Team recommended Pods Alternative Cache plugin', 'pods' ), + 'status' => 'good', + 'badge' => [ + 'label' => __( 'Security' ), + 'color' => 'blue', + ], + 'description' => sprintf( '

            %s

            ', __( 'The Pods Alternative Cache plugin is useful to many who use Pods.' ) ), + 'actions' => sprintf( '

            %s

            ', esc_url( admin_url( 'plugins.php' ) ), __( 'Manage your plugins' ) ), + 'test' => 'is_pods_alternative_cache_activated', + ]; + + return $result; +} diff --git a/includes/media.php b/includes/media.php index fc03b96121..3c927390a0 100644 --- a/includes/media.php +++ b/includes/media.php @@ -13,7 +13,6 @@ * @since 2.0.5 */ function pods_image_id_from_field( $image ) { - $id = 0; if ( ! empty( $image ) ) { @@ -129,7 +128,6 @@ function pods_is_image_size( $size ) { * @since 2.0.5 */ function pods_image( $image, $size = 'thumbnail', $default = 0, $attributes = '', $force = false ) { - if ( ! $default && -1 !== $default ) { /** * Filter for default value. @@ -177,7 +175,6 @@ function pods_image( $image, $size = 'thumbnail', $default = 0, $attributes = '' * @since 2.0.5 */ function pods_image_url( $image, $size = 'thumbnail', $default = 0, $force = false ) { - if ( ! $default && -1 !== $default ) { /** * Filter for default value. @@ -228,13 +225,13 @@ function pods_image_url( $image, $size = 'thumbnail', $default = 0, $force = fal * @param string $url URL to media for import. * @param int $post_parent ID of post parent, default none. * @param boolean $featured Whether to set it as the featured (post thumbnail) of the post parent. + * @param boolean $strict Whether to return errors upon failure. * * @return int Attachment ID. * * @since 2.3.0 */ -function pods_attachment_import( $url, $post_parent = null, $featured = false ) { - +function pods_attachment_import( $url, $post_parent = null, $featured = false, $strict = false ) { $filename = explode( '?', $url ); $filename = $filename[0]; @@ -248,6 +245,10 @@ function pods_attachment_import( $url, $post_parent = null, $featured = false ) $uploads = wp_upload_dir( current_time( 'mysql' ) ); if ( ! ( $uploads && false === $uploads['error'] ) ) { + if ( $strict ) { + throw new \Exception( sprintf( 'Attachment import failed, uploads directory has a problem: %s', var_export( $uploads, true ) ) ); + } + return 0; } @@ -257,6 +258,10 @@ function pods_attachment_import( $url, $post_parent = null, $featured = false ) $file_data = @file_get_contents( $url ); if ( ! $file_data ) { + if ( $strict ) { + throw new \Exception( 'Attachment import failed, file_get_contents had a problem' ); + } + return 0; } @@ -269,6 +274,10 @@ function pods_attachment_import( $url, $post_parent = null, $featured = false ) $wp_filetype = wp_check_filetype( $filename ); if ( ! $wp_filetype['type'] || ! $wp_filetype['ext'] ) { + if ( $strict ) { + throw new \Exception( sprintf( 'Attachment import failed, filetype check failed: %s', var_export( $wp_filetype, true ) ) ); + } + return 0; } @@ -283,6 +292,10 @@ function pods_attachment_import( $url, $post_parent = null, $featured = false ) $attachment_id = wp_insert_attachment( $attachment, $new_file, $post_parent ); if ( is_wp_error( $attachment_id ) ) { + if ( $strict ) { + throw new \Exception( sprintf( 'Attachment import failed, wp_insert_attachment failed: %s', var_export( $attachment_id, true ) ) ); + } + return 0; } @@ -338,7 +351,6 @@ function pods_maybe_image_resize( $attachment_id, $size ) { * @since 2.3.0 */ function pods_image_resize( $attachment_id, $size ) { - $size_data = array(); if ( ! is_array( $size ) ) { @@ -416,7 +428,6 @@ function pods_image_resize( $attachment_id, $size ) { * @return string */ function pods_audio( $url, $args = false ) { - // Support arrays. if ( is_array( $url ) ) { $url = pods_v( 'ID', $url ); @@ -440,7 +451,6 @@ function pods_audio( $url, $args = false ) { } return wp_audio_shortcode( $audio_args ); - } /** @@ -456,7 +466,6 @@ function pods_audio( $url, $args = false ) { * @return string */ function pods_video( $url, $args = false ) { - // Support arrays. if ( is_array( $url ) ) { $url = pods_v( 'ID', $url ); @@ -480,7 +489,6 @@ function pods_video( $url, $args = false ) { } return wp_video_shortcode( $video_args ); - } /** diff --git a/init.php b/init.php index 0db54b0fc0..ad085fce60 100644 --- a/init.php +++ b/init.php @@ -1,66 +1,85 @@ ( { + matches: false, + addListener: () => {}, + removeListener: () => {}, +} ); + +global.lodash = lodash; +global._ = underscore; + +global.wp = { + data: { + registerStore, + combineReducers, + select, + dispatch, + withSelect, + withDispatch, + }, +}; + +global.Backbone = Backbone; +global.Backbone.Marionette = Mn; + +// @see PodsInit.php +global.PodsMn = Backbone.Marionette.noConflict(); diff --git a/jest.config.json b/jest.config.json new file mode 100644 index 0000000000..8f7a290be7 --- /dev/null +++ b/jest.config.json @@ -0,0 +1,13 @@ +{ + "preset": "@wordpress/jest-preset-default", + "roots": [ + "/ui/js/dfv/src/", + "/ui/js/blocks/src/" + ], + "setupFilesAfterEnv": [ + "/jest-setup-wordpress-globals.js" + ], + "testMatch": [ + "**/test/*.js" + ] +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..05fdf2dd4b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,75046 @@ +{ + "name": "pods", + "version": "2.8.0-rc-2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "version": "2.8.0-rc-2", + "license": "GPL-2.0+", + "dependencies": { + "@dnd-kit/core": "^3.1.1", + "@dnd-kit/modifiers": "^3.0.0", + "@dnd-kit/sortable": "^4.0.0", + "@dnd-kit/utilities": "2.0.0", + "@reduxjs/toolkit": "^1.5.1", + "@tippyjs/react": "^4.2.5", + "codemirror": "^5.60.0", + "faker": "^4.1.0", + "html-react-parser": "^0.13.0", + "immutability-helper": "^3.1.1", + "memoize-one": "^5.1.1", + "moment": "^2.29.1", + "react-codemirror2": "^7.2.1", + "react-datetime": "^3.1.1", + "react-quill": "^2.0.0-beta.4", + "react-select": "^4.3.1", + "sanitize-html": "^1.27.1", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/cli": "^7.13.14", + "@babel/core": "^7.13.15", + "@babel/plugin-external-helpers": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-react-jsx": "^7.13.12", + "@babel/plugin-transform-strict-mode": "^7.12.13", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.13.15", + "@babel/preset-react": "^7.13.13", + "@babel/register": "^7.13.14", + "@wordpress/api-fetch": "3.18.0", + "@wordpress/block-editor": "4.2.0", + "@wordpress/components": "9.9.0", + "@wordpress/data": "4.21.0", + "@wordpress/date": "3.10.0", + "@wordpress/dependency-extraction-webpack-plugin": "2.8.0", + "@wordpress/editor": "9.19.0", + "@wordpress/eslint-plugin": "7.1.0", + "@wordpress/jest-preset-default": "6.6.0", + "@wordpress/scripts": "12.6.1", + "@wordpress/server-side-render": "1.15.0", + "babel-eslint": "^10.0.1", + "babel-loader": "^8.2.2", + "babel-plugin-module-resolver": "^3.2.0", + "babel-plugin-transform-html-import-to-string": "0.0.1", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24", + "backbone": "~1.3.3", + "backbone.marionette": "^3.5.1", + "classnames": "^2.3.1", + "css-loader": "^2.1.1", + "deep-freeze": "0.0.1", + "enzyme-matchers": "^7.1.2", + "eslint": "^7.24.0", + "eslint-plugin-react": "^7.23.2", + "glob": "^7.1.6", + "grunt": "^1.3.0", + "grunt-cli": "^1.4.2", + "grunt-exec": "^3.0.0", + "grunt-text-replace": "^0.4.0", + "install": "^0.10.2", + "jest": "^25.0.0", + "jquery": "^3.6.0", + "jsdom": "^16.5.3", + "jsdom-global": "3.0.2", + "load-grunt-tasks": "^3.5.0", + "lodash": "^4.17.21", + "mocha": "^6.1.3", + "node-sass": "^4.14.1", + "npm": "^6.14.12", + "prop-types": "^15.7.2", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "rememo": "^3.0.0", + "sass-loader": "^7.1.0", + "sprintf-js": "^1.1.2", + "style-loader": "^0.23.1", + "terser-webpack-plugin": "^1.4.5", + "underscore": "~1.8.3", + "webpack": "^4.46.0", + "webpack-cli": "^3.3.12", + "webpack-merge": "^4.2.1" + }, + "engines": { + "node": ">=12.6.0", + "npm": ">=6.9.0" + }, + "funding": { + "type": "individual", + "url": "https://friends.pods.io/" + } + }, + "node_modules/@babel/cli": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.5.tgz", + "integrity": "sha512-poegjhRvXHWO0EAsnYajwYZuqcz7gyfxwfaecUESxDujrqOivf3zrjFbub8IJkrqEaz3fvJWh001EzxBub54fg==", + "dev": true, + "dependencies": { + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.2", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "devOptional": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "devOptional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "devOptional": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz", + "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==", + "dev": true, + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "devOptional": true, + "dependencies": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", + "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", + "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz", + "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "devOptional": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "devOptional": true, + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz", + "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-wrap-function": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "devOptional": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", + "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "devOptional": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "devOptional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "devOptional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz", + "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "devOptional": true, + "dependencies": { + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "devOptional": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "devOptional": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-external-helpers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.14.5.tgz", + "integrity": "sha512-q/B/hLX+nDGk73Xn529d7Ar4ih17J8pNBbsXafq8oXij0XfFEA/bks+u+6q5q04zO5o/qivjzui6BqzPfYShEg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz", + "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz", + "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-default-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", + "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-default-from": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz", + "integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.14.7", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", + "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", + "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-default-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", + "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", + "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", + "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", + "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz", + "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz", + "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", + "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", + "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", + "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", + "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", + "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-flow": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", + "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", + "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz", + "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz", + "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", + "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz", + "integrity": "sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", + "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-assign": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz", + "integrity": "sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", + "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.14.5.tgz", + "integrity": "sha512-NBqLEx1GxllIOXJInJAQbrnwwYJsV3WaMHIcOwD8rhYS0AabTWn7kHdHgPgu5RmHLU0q4DMxhAMu8ue/KampgQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.5.tgz", + "integrity": "sha512-07aqY1ChoPgIxsuDviptRpVkWCSbXWmzQqcgy65C6YSFOfPFvb/DX3bBRHh7pCd/PMEEYHYWUTSVkCbkVainYQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.5.tgz", + "integrity": "sha512-7RylxNeDnxc1OleDm0F5Q/BSL+whYRbOAR+bwgCxIr0L32v7UFh/pz1DLMZideAUxKT6eMoS2zQH6fyODLEi8Q==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.14.5.tgz", + "integrity": "sha512-rdwG/9jC6QybWxVe2UVOa7q6cnTpw8JRRHOxntG/h6g/guAOe6AhtQHJuJh5FwmnXIT1bdm5vC2/5huV8ZOorQ==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.14.5.tgz", + "integrity": "sha512-M/fmDX6n0cfHK/NLTcPmrfVAORKDhK8tyjDhyxlUjYyPYYO8FRWwuxBA3WBx8kWN/uBUuwGa3s/0+hQ9JIN3Tg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.5.tgz", + "integrity": "sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.14.5.tgz", + "integrity": "sha512-3X4HpBJimNxW4rhUy/SONPyNQHp5YRr0HhJdT2OH1BRp0of7u3Dkirc7x9FRJMKMqTBI079VZ1hzv7Ouuz///g==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", + "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "dev": true, + "dependencies": { + "regenerator-transform": "^0.14.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", + "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz", + "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", + "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", + "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-strict-mode": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-strict-mode/-/plugin-transform-strict-mode-7.14.5.tgz", + "integrity": "sha512-1oLnWpVtGIwDDxOcd2EuS79kj3f+xhYHoyGy8F7XS26v7ueFyTlglKlnXs5DQ6kyrodXp6eEXbLBISuauuSj/A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", + "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz", + "integrity": "sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.6", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", + "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", + "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/polyfill": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", + "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", + "deprecated": "๐Ÿšจ This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.", + "dev": true, + "dependencies": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz", + "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.14.7", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-async-generator-functions": "^7.14.7", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.14.5", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.14.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.14.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.14.5", + "@babel/plugin-transform-classes": "^7.14.5", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.7", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.14.5", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.14.5", + "@babel/plugin-transform-modules-systemjs": "^7.14.5", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.14.5", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.14.6", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.15.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", + "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-flow-strip-types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.14.5.tgz", + "integrity": "sha512-XFxBkjyObLvBaAvkx1Ie95Iaq4S/GUEIrejyrntQ/VCMKUYvKLoyKxOBzJ2kjA3b6rC9/KL6KXfDC2GqvLiNqQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-react-display-name": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.5", + "@babel/plugin-transform-react-jsx-development": "^7.14.5", + "@babel/plugin-transform-react-pure-annotations": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz", + "integrity": "sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/register": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.14.5.tgz", + "integrity": "sha512-TjJpGz/aDjFGWsItRBQMOFTrmTI9tr79CHOK+KIvLeCkbxuOAk2M5QHjvruIMGoo9OuccMh5euplPzc5FjAKGg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", + "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz", + "integrity": "sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==", + "dev": true, + "dependencies": { + "core-js-pure": "^3.15.0", + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "devOptional": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "devOptional": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "devOptional": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@choojs/findup": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@choojs/findup/-/findup-0.2.1.tgz", + "integrity": "sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==", + "dev": true, + "dependencies": { + "commander": "^2.15.1" + }, + "bin": { + "findup": "bin/findup.js" + } + }, + "node_modules/@choojs/findup/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "dependencies": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz", + "integrity": "sha512-QwaQ1IJHQHMMuAGOOYHQSx7h7vMZPfO97aDts8t5N/MY7n2QTDSnW+kF7uRQ1tVBkr6vJ+BqHWG5dlgGvwVjow==", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-3.1.1.tgz", + "integrity": "sha512-18YY5+1lTqJbGSg6JBSa/fjAOTUYAysFrQ5Ti8oppEPHFacQbC+owM51y2z2KN0LkDHBfGZKw2sFT7++ttwfpA==", + "dependencies": { + "@dnd-kit/accessibility": "^3.0.0", + "@dnd-kit/utilities": "^2.0.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/modifiers": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-3.0.0.tgz", + "integrity": "sha512-CmskqOcW4Bw61JP1Lqkx7cRzv9xQS/5seI+Q5eKhx+mS/MA5IrX2jgtMxvQ6PKYDnx2v/uHxqLNVhlvumtBTSQ==", + "license": "MIT", + "dependencies": { + "@dnd-kit/utilities": "^2.0.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^3.1.0" + } + }, + "node_modules/@dnd-kit/sortable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-4.0.0.tgz", + "integrity": "sha512-teYVFy6mQG/u6F6CaGxAkzPfiNJvguFzWfJ/zonYQRxfANHX6QJ6GziMG9KON/Ae9Q2ODJP8vib+guWJrDXeGg==", + "dependencies": { + "@dnd-kit/utilities": "^2.0.0", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^3.1.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-bjs49yMNzMM+BYRsBUhTqhTk6HEvhuY3leFt6Em6NaYGgygaMbtGbbXof/UXBv7rqyyi0OkmBBnrCCcxqS2t/g==", + "dependencies": { + "tslib": "^2.0.0" + } + }, + "node_modules/@emotion/cache": { + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", + "dev": true, + "dependencies": { + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + } + }, + "node_modules/@emotion/core": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz", + "integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/@emotion/css": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz", + "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==", + "dev": true, + "dependencies": { + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3", + "babel-plugin-emotion": "^10.0.27" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "dev": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "node_modules/@emotion/primitives-core": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/primitives-core/-/primitives-core-10.0.27.tgz", + "integrity": "sha512-fRBEDNPSFFOrBJ0OcheuElayrNTNdLF9DzMxtL0sFgsCFvvadlzwJHhJMSwEJuxwARm9GhVLr1p8G8JGkK98lQ==", + "dev": true, + "dependencies": { + "css-to-react-native": "^2.2.1" + }, + "peerDependencies": { + "@emotion/core": "^10.0.27", + "react": ">=16.3.0" + } + }, + "node_modules/@emotion/react": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.4.0.tgz", + "integrity": "sha512-4XklWsl9BdtatLoJpSjusXhpKv9YVteYKh9hPKP1Sxl+mswEFoUe0WtmtWjxEjkA51DQ2QRMCNOvKcSlCQ7ivg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^11.4.0", + "@emotion/serialize": "^1.0.2", + "@emotion/sheet": "^1.0.1", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/react/node_modules/@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "dependencies": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "node_modules/@emotion/react/node_modules/@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "dependencies": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/react/node_modules/@emotion/sheet": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.1.tgz", + "integrity": "sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==" + }, + "node_modules/@emotion/react/node_modules/@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "node_modules/@emotion/react/node_modules/csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + }, + "node_modules/@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "dev": true, + "dependencies": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + } + }, + "node_modules/@emotion/sheet": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==", + "dev": true + }, + "node_modules/@emotion/styled": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-10.0.27.tgz", + "integrity": "sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==", + "dev": true, + "dependencies": { + "@emotion/styled-base": "^10.0.27", + "babel-plugin-emotion": "^10.0.27" + }, + "peerDependencies": { + "@emotion/core": "^10.0.27", + "react": ">=16.3.0" + } + }, + "node_modules/@emotion/styled-base": { + "version": "10.0.31", + "resolved": "https://registry.npmjs.org/@emotion/styled-base/-/styled-base-10.0.31.tgz", + "integrity": "sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@emotion/is-prop-valid": "0.8.8", + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3" + }, + "peerDependencies": { + "@emotion/core": "^10.0.28", + "react": ">=16.3.0" + } + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==", + "dev": true + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "node_modules/@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==", + "dev": true + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "deprecated": "Moved to 'npm install @sideway/address'", + "dev": true + }, + "node_modules/@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true + }, + "node_modules/@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true + }, + "node_modules/@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "deprecated": "Switch to 'npm install joi'", + "dev": true, + "dependencies": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "node_modules/@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true, + "dependencies": { + "@hapi/hoek": "^8.3.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@itsjonq/is": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@itsjonq/is/-/is-0.0.2.tgz", + "integrity": "sha512-P0Ug+chfjCV1JV8MUxAGPz0BM76yDlR76AIfPwRZ6mAJW56k6b9j0s2cIcEsEAu0gNj/RJD1STw777AQyBN3CQ==", + "dev": true + }, + "node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/core/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/create-cache-key-function": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-26.6.2.tgz", + "integrity": "sha512-LgEuqU1f/7WEIPYqwLPIvvHuc1sB6gMVbT6zWhin3txYUNYK/kGQrC1F2WR4gR34YlI9bBtViTm5z98RqVZAaw==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@jest/create-cache-key-function/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "engines": { + "node": ">= 8.3" + }, + "optionalDependencies": { + "node-notifier": "^6.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.2", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz", + "integrity": "sha512-Fb8WxUFOBQVl+CX4MWet5o7eCc6Pj04rXIwVKZ6h1NnqTo45eOQW6aWyhG25NIODvWFwTDMwBsYxrQ3imxpetg==", + "dev": true, + "optional": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^5.1.2", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/move-file/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@popperjs/core": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", + "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-native-community/cli-debugger-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-5.0.1.tgz", + "integrity": "sha512-5gGKaaXYOVE423BUqxIfvfAVSj5Cg1cU/TpGbeg/iqpy2CfqyWqJB3tTuVUbOOiOvR5wbU8tti6pIi1pchJ+oA==", + "dev": true, + "peer": true, + "dependencies": { + "serve-static": "^1.13.1" + } + }, + "node_modules/@react-native-community/cli-hermes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-5.0.1.tgz", + "integrity": "sha512-nD+ZOFvu5MfjLB18eDJ01MNiFrzj8SDtENjGpf0ZRFndOWASDAmU54/UlU/wj8OzTToK1+S1KY7j2P2M1gleww==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-platform-android": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "chalk": "^3.0.0", + "hermes-profile-transformer": "^0.0.6", + "ip": "^1.1.5" + } + }, + "node_modules/@react-native-community/cli-hermes/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@react-native-community/cli-hermes/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-hermes/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@react-native-community/cli-hermes/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@react-native-community/cli-hermes/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-hermes/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-android": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-5.0.1.tgz", + "integrity": "sha512-qv9GJX6BJ+Y4qvV34vgxKwwN1cnveXUdP6y2YmTW7XoAYs5YUzKqHajpY58EyucAL2y++6+573t5y4U/9IIoww==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-tools": "^5.0.1", + "chalk": "^3.0.0", + "execa": "^1.0.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "jetifier": "^1.6.2", + "lodash": "^4.17.15", + "logkitty": "^0.7.1", + "slash": "^3.0.0", + "xmldoc": "^1.1.2" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-android/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-ios": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-5.0.1.tgz", + "integrity": "sha512-Nr/edBEYJfElgBNvjDevs2BuDicsvQaM8nYkTGgp33pyuCZRBxsYxQqfsNmnLalTzcYaebjWj6AnjUSxzQBWqg==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-tools": "^5.0.1", + "chalk": "^3.0.0", + "glob": "^7.1.3", + "js-yaml": "^3.13.1", + "lodash": "^4.17.15", + "plist": "^3.0.1", + "xcode": "^2.0.0" + } + }, + "node_modules/@react-native-community/cli-platform-ios/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@react-native-community/cli-platform-ios/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-ios/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@react-native-community/cli-platform-ios/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@react-native-community/cli-platform-ios/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-platform-ios/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-server-api": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-5.0.1.tgz", + "integrity": "sha512-OOxL+y9AOZayQzmSW+h5T54wQe+QBc/f67Y9QlWzzJhkKJdYx+S4VOooHoD5PFJzGbYaxhu2YF17p517pcEIIA==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "compression": "^1.7.1", + "connect": "^3.6.5", + "errorhandler": "^1.5.0", + "nocache": "^2.1.0", + "pretty-format": "^26.6.2", + "serve-static": "^1.13.1", + "ws": "^1.1.0" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@react-native-community/cli-server-api/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "node_modules/@react-native-community/cli-server-api/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-server-api/node_modules/ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "peer": true, + "dependencies": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "node_modules/@react-native-community/cli-tools": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-5.0.1.tgz", + "integrity": "sha512-XOX5w98oSE8+KnkMZZPMRT7I5TaP8fLbDl0tCu40S7Epz+Zz924n80fmdu6nUDIfPT1nV6yH1hmHmWAWTDOR+Q==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^3.0.0", + "lodash": "^4.17.15", + "mime": "^2.4.1", + "node-fetch": "^2.6.0", + "open": "^6.2.0", + "shell-quote": "1.6.1" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@react-native-community/cli-tools/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-tools/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@react-native-community/cli-types": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-5.0.1.tgz", + "integrity": "sha512-BesXnuFFlU/d1F3+sHhvKt8fUxbQlAbZ3hhMEImp9A6sopl8TEtryUGJ1dbazGjRXcADutxvjwT/i3LJVTIQug==", + "dev": true, + "peer": true, + "dependencies": { + "ora": "^3.4.0" + } + }, + "node_modules/@react-native/assets": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", + "integrity": "sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ==", + "dev": true, + "peer": true + }, + "node_modules/@react-native/normalize-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-1.0.0.tgz", + "integrity": "sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg==", + "dev": true, + "peer": true + }, + "node_modules/@react-native/polyfills": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz", + "integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==", + "dev": true, + "peer": true + }, + "node_modules/@reduxjs/toolkit": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.0.tgz", + "integrity": "sha512-eGL50G+Vj5AG5uD0lineb6rRtbs96M8+hxbcwkHpZ8LQcmt0Bm33WyBSnj5AweLkjQ7ZP+KFRDHiLMznljRQ3A==", + "dependencies": { + "immer": "^9.0.1", + "redux": "^4.1.0", + "redux-thunk": "^2.3.0", + "reselect": "^4.0.0" + }, + "peerDependencies": { + "react": "^16.14.0 || ^17.0.0", + "react-redux": "^7.2.1" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@sideway/address": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", + "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "dev": true, + "peer": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/address/node_modules/@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "dev": true, + "peer": true + }, + "node_modules/@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "dev": true, + "peer": true + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true, + "peer": true + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@stylelint/postcss-css-in-js": { + "version": "0.37.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", + "integrity": "sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==", + "dev": true, + "dependencies": { + "@babel/core": ">=7.9.0" + }, + "peerDependencies": { + "postcss": ">=7.0.0", + "postcss-syntax": ">=0.36.2" + } + }, + "node_modules/@stylelint/postcss-markdown": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz", + "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==", + "dev": true, + "dependencies": { + "remark": "^13.0.0", + "unist-util-find-all-after": "^3.0.2" + }, + "peerDependencies": { + "postcss": ">=7.0.0", + "postcss-syntax": ">=0.36.2" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dev": true, + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dev": true, + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@tannin/compile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.1.0.tgz", + "integrity": "sha512-n8m9eNDfoNZoxdvWiTfW/hSPhehzLJ3zW7f8E7oT6mCROoMNWCB4TYtv041+2FMAxweiE0j7i1jubQU4MEC/Gg==", + "dev": true, + "dependencies": { + "@tannin/evaluate": "^1.2.0", + "@tannin/postfix": "^1.1.0" + } + }, + "node_modules/@tannin/evaluate": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@tannin/evaluate/-/evaluate-1.2.0.tgz", + "integrity": "sha512-3ioXvNowbO/wSrxsDG5DKIMxC81P0QrQTYai8zFNY+umuoHWRPbQ/TuuDEOju9E+jQDXmj6yI5GyejNuh8I+eg==", + "dev": true + }, + "node_modules/@tannin/plural-forms": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/plural-forms/-/plural-forms-1.1.0.tgz", + "integrity": "sha512-xl9R2mDZO/qiHam1AgMnAES6IKIg7OBhcXqy6eDsRCdXuxAFPcjrej9HMjyCLE0DJ/8cHf0i5OQTstuBRhpbHw==", + "dev": true, + "dependencies": { + "@tannin/compile": "^1.1.0" + } + }, + "node_modules/@tannin/postfix": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", + "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==", + "dev": true + }, + "node_modules/@tippyjs/react": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.5.tgz", + "integrity": "sha512-YBLgy+1zznBNbx4JOoOdFXWMLXjBh9hLPwRtq3s8RRdrez2l3tPBRt2m2909wZd9S1KUeKjOOYYsnitccI9I3A==", + "dependencies": { + "tippy.js": "^6.3.1" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.14", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", + "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.0.tgz", + "integrity": "sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/cheerio": { + "version": "0.22.29", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.29.tgz", + "integrity": "sha512-rNX1PsrDPxiNiyLnRKiW2NXHJFHqx0Fl3J2WsZq0MTBspa/FgwlqhXJE2crIcc+/2IglLHtSWw7g053oUR8fOg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha512-cfBw6q6tT5sa1gSPFSRKzF/xxYrrmeiut7E0TxNBObiLSBTuFEHibcfEe3waQPEDbqBsq+ql/TOniw65EyDFMA==" + }, + "node_modules/@types/domutils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@types/domutils/-/domutils-1.7.3.tgz", + "integrity": "sha512-EucnS75OnnEdypNt+UpARisSF8eJBq4no+aVOis3Bs5kyABDXm1hEDv6jJxcMJPjR+a2YCrEANaW+BMT2QVG2Q==", + "dependencies": { + "domhandler": "^2.4.0" + } + }, + "node_modules/@types/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/@types/domutils/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@types/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-fCxmHS4ryCUCfV9+CJZY1UjkbR+6Al/EQdX5Jh03qBj9gdlPG5q+7uNoDgE/ZNXb3XNWSAQgqKIWnbRCbOyyWA==", + "dependencies": { + "@types/domhandler": "*", + "@types/domutils": "*", + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "node_modules/@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mime-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz", + "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.0.tgz", + "integrity": "sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg==" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "node_modules/@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "node_modules/@types/quill": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz", + "integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==", + "dependencies": { + "parchment": "^1.1.2" + } + }, + "node_modules/@types/react": { + "version": "16.14.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.10.tgz", + "integrity": "sha512-QadBsMyF6ldjEAXEhsmEW/L0uBDJT8yw7Qoe5sRnEKVrzMkiYoJwqoL5TKJOlArsn/wvIJM/XdVzkdL6+AS64Q==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "16.9.13", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.13.tgz", + "integrity": "sha512-34Hr3XnmUSJbUVDxIw/e7dhQn2BJZhJmlAaPyPwfTQyuVS9mV/CeyghFcXyvkJXxI7notQJz8mF8FeCVvloJrA==", + "dev": true, + "dependencies": { + "@types/react": "^16" + } + }, + "node_modules/@types/react/node_modules/csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, + "node_modules/@types/scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==", + "dev": true + }, + "node_modules/@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/@types/tapable": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", + "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==", + "dev": true + }, + "node_modules/@types/uglify-js": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", + "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/@types/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@types/unist": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==", + "dev": true + }, + "node_modules/@types/webpack": { + "version": "4.41.30", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.30.tgz", + "integrity": "sha512-GUHyY+pfuQ6haAfzu4S14F+R5iGRwN6b2FRNJY7U0NilmFAqbsOfK6j1HwuLBAqwRIT+pVdNDJGJ6e8rpp0KHA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "anymatch": "^3.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/@types/webpack-sources": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz", + "integrity": "sha512-MjM1R6iuw8XaVbtkCBz0N349cyqBjJHCbQiOeppe3VBeFvxqs74RKHAVt9LkxTnUWc7YLZOEsUfPUnmK6SBPKQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + } + }, + "node_modules/@types/webpack-sources/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/webpack/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/webpack/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "dependencies": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@wordpress/a11y": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.15.3.tgz", + "integrity": "sha512-uoCznHY3/TaNWeXutLI6juC198ykaBwZ34P51PNHHQqi3WzVoBhFx6AnAR/9Uupl3tZcekefpkVHy7AJHMAPIA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/dom-ready": "^2.13.2", + "@wordpress/i18n": "^3.20.0" + } + }, + "node_modules/@wordpress/api-fetch": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.18.0.tgz", + "integrity": "sha512-sNT/9yOC9G/G/6QOd4b1d4tckwWS1IrLVulxRFcyhBSorB0XCu07j40nQxhrPKANgi8dLawke4hlfJdlQ9CSZQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@wordpress/i18n": "^3.14.0", + "@wordpress/url": "^2.17.0" + } + }, + "node_modules/@wordpress/autop": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-2.12.2.tgz", + "integrity": "sha512-c3taxJCmf1Bib33GPm7ihrgFvuzKHycdyE+XWnpa9G3JgZUJTpssFSC5rC3VZ3u+QD8agStBtlOBOyxj6pjQSA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/babel-plugin-import-jsx-pragma": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-2.7.0.tgz", + "integrity": "sha512-yR+rSyfHKfevW84vKBOERpjEslD/o00CaYMftywVYOjsOQ8GLS6xv/VgDcpQ8JomJ9eRRInLRpeGKTM3lOa4xQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@wordpress/babel-preset-default": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-4.20.0.tgz", + "integrity": "sha512-VKPoC5We2GNxon5umOeZ7NIP4CfP7X5gqslSnNrLW4kD1XgmbVaCs2ISFF8+mObVVb6KAzbaUjI6OWljcUb5UA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.9", + "@babel/plugin-transform-react-jsx": "^7.12.7", + "@babel/plugin-transform-runtime": "^7.12.1", + "@babel/preset-env": "^7.12.7", + "@babel/runtime": "^7.12.5", + "@wordpress/babel-plugin-import-jsx-pragma": "^2.7.0", + "@wordpress/browserslist-config": "^2.7.0", + "@wordpress/element": "^2.19.0", + "@wordpress/warning": "^1.3.0", + "core-js": "^3.6.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/babel-preset-default/node_modules/core-js": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/@wordpress/base-styles": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@wordpress/base-styles/-/base-styles-3.5.4.tgz", + "integrity": "sha512-5JfLnkQMqaefuoMkqUJMBC8m9RpXJqaaOykxuy9y3uk+s2ENbMGXSUjbzw+anO3SIRORKnHmRkgofcSoqvWV5w==", + "dev": true + }, + "node_modules/@wordpress/blob": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-2.13.2.tgz", + "integrity": "sha512-Us71BMrvjiMjW9WTV1UzZbEBd+Q7W05P0WW+Tfo6qHJLBMYXPDN9dP9s6JhK6fzzL+U/PzotMJwA6P85BqL30w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-directory": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-directory/-/block-directory-1.19.3.tgz", + "integrity": "sha512-bqoyYqbbJUtES6pv63xaSXlX+JE3fb9ADtPtN/7XrVJzDROJmbXTnNC8Ct7YBdjuCnolgjrykF0mXSytVMGoBg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/edit-post": "^3.27.3", + "@wordpress/editor": "^9.26.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/plugins": "^2.25.3", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/block-editor/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/blocks/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "peerDependencies": { + "@wp-g2/create-styles": "^0.0.154", + "reakit-utils": "^0.15.1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "dependencies": { + "@emotion/primitives-core": "10.0.27" + }, + "peerDependencies": { + "react-native": ">=0.14.0 <1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/components/node_modules/react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/data/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/editor": { + "version": "9.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.26.3.tgz", + "integrity": "sha512-W3F/UnpjdEISkKqGv4NdwTgdzre3Ak3O6JGxaB4xWyFi6o4uz8ldlKpfacU9GJaX1wV1ajM8RkHGNDgyejPPdA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "rememo": "^3.0.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/editor/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wordpress/server-side-render": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.21.3.tgz", + "integrity": "sha512-pS2+LmTQX8S61TvaC+UyXqmFnQSXcJ3wcr3RPX1EwmpvlMuXlqdW8N5Y1TWuOT1G/ZDAwvTilLAlxeAMqrYSXA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/@wp-g2/create-styles/node_modules/@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/block-directory/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/block-directory/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/block-directory/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/block-directory/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-directory/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-directory/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/block-directory/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/block-directory/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/block-directory/node_modules/react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "dependencies": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@wordpress/block-directory/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@wordpress/block-directory/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-directory/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/block-directory/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-directory/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-directory/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/block-directory/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/block-editor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-4.2.0.tgz", + "integrity": "sha512-qBIgbjG683Y1PK9aw5UPdiwrpRDIqePL7PHw6KsD45peTCpPJouZXcC6aQq0UV1qOuxE0Zykp33vkjsDDCjTXA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@wordpress/a11y": "^2.11.0", + "@wordpress/blob": "^2.9.0", + "@wordpress/blocks": "^6.19.0", + "@wordpress/components": "^9.9.0", + "@wordpress/compose": "^3.18.0", + "@wordpress/data": "^4.21.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/dom": "^2.12.0", + "@wordpress/element": "^2.15.0", + "@wordpress/hooks": "^2.9.0", + "@wordpress/html-entities": "^2.8.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/icons": "^2.3.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/keyboard-shortcuts": "^1.8.0", + "@wordpress/keycodes": "^2.14.0", + "@wordpress/rich-text": "^3.19.0", + "@wordpress/shortcode": "^2.9.0", + "@wordpress/token-list": "^1.11.0", + "@wordpress/url": "^2.17.0", + "@wordpress/viewport": "^2.20.0", + "@wordpress/wordcount": "^2.10.0", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "react-autosize-textarea": "^3.0.2", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "traverse": "^0.6.6" + } + }, + "node_modules/@wordpress/block-library": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-2.29.3.tgz", + "integrity": "sha512-bOhiBmvOMmlOYuO8z+TZzhfLDGcpz1BnupW7nqkWvlJhaJ9sCbRu8Hrar+dti1tYHn+anmC3aJ0f+w0kvWPysg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/editor": "^9.26.3", + "@wordpress/element": "^2.20.3", + "@wordpress/escape-html": "^1.12.2", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/viewport": "^2.26.3", + "classnames": "^2.2.5", + "fast-average-color": "4.3.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "react-easy-crop": "^3.0.0", + "tinycolor2": "^1.4.2" + } + }, + "node_modules/@wordpress/block-library/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/block-library/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "peerDependencies": { + "@wp-g2/create-styles": "^0.0.154", + "reakit-utils": "^0.15.1" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "dependencies": { + "@emotion/primitives-core": "10.0.27" + }, + "peerDependencies": { + "react-native": ">=0.14.0 <1" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/components/node_modules/react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/editor": { + "version": "9.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.26.3.tgz", + "integrity": "sha512-W3F/UnpjdEISkKqGv4NdwTgdzre3Ak3O6JGxaB4xWyFi6o4uz8ldlKpfacU9GJaX1wV1ajM8RkHGNDgyejPPdA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "rememo": "^3.0.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/server-side-render": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.21.3.tgz", + "integrity": "sha512-pS2+LmTQX8S61TvaC+UyXqmFnQSXcJ3wcr3RPX1EwmpvlMuXlqdW8N5Y1TWuOT1G/ZDAwvTilLAlxeAMqrYSXA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/block-library/node_modules/@wp-g2/create-styles/node_modules/@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/block-library/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/block-library/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/block-library/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/block-library/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/block-library/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/block-library/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/block-library/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-library/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-library/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/block-library/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/block-library/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/block-library/node_modules/react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "dependencies": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@wordpress/block-library/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@wordpress/block-library/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/block-library/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/block-library/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-library/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/block-library/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/block-library/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/block-serialization-default-parser": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-3.10.2.tgz", + "integrity": "sha512-0vyHHTcEw3ijY+stJqCf0iVR4bHpb84dbTZVaT2VSzISGzeVuAJpcYhIJMHvDTMcX1E2pgAfanIL8xloS6W7gQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/blocks": { + "version": "6.25.2", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-6.25.2.tgz", + "integrity": "sha512-dYleqt8o030Bw2dV6HKrafhcTQf/AqOAVagA9rBKRVfl6ABrm26Gb8YsgwTMMrxIIGRy9uqqqNWH1o8ae3JE2A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@wordpress/autop": "^2.11.0", + "@wordpress/blob": "^2.12.0", + "@wordpress/block-serialization-default-parser": "^3.9.0", + "@wordpress/compose": "^3.24.0", + "@wordpress/data": "^4.26.2", + "@wordpress/deprecated": "^2.11.0", + "@wordpress/dom": "^2.16.1", + "@wordpress/element": "^2.19.0", + "@wordpress/hooks": "^2.11.0", + "@wordpress/html-entities": "^2.10.0", + "@wordpress/i18n": "^3.17.0", + "@wordpress/icons": "^2.9.0", + "@wordpress/is-shallow-equal": "^3.0.0", + "@wordpress/shortcode": "^2.12.0", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.1", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/blocks/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/blocks/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/browserslist-config": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.7.0.tgz", + "integrity": "sha512-pB45JlfmHuEigNFZ1X+CTgIsOT3/TTb9iZxw1DHXge/7ytY8FNhtcNwTfF9IgnS6/xaFRZBqzw4DyH4sP1Lyxg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/components": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-9.9.0.tgz", + "integrity": "sha512-EtDQ7sf7GuEMo+oWW7CDob0YrVynxR+t0FXGDZw3IP8msKAvVmsCD0DoSEOfX/DTWNaaHstaw6xE4+Tgk1XUWQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@emotion/core": "^10.0.22", + "@emotion/css": "^10.0.22", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.11.0", + "@wordpress/compose": "^3.18.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/dom": "^2.12.0", + "@wordpress/element": "^2.15.0", + "@wordpress/hooks": "^2.9.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/icons": "^2.3.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/keycodes": "^2.14.0", + "@wordpress/primitives": "^1.6.0", + "@wordpress/rich-text": "^3.19.0", + "@wordpress/warning": "^1.2.0", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^4.0.5", + "gradient-parser": "^0.1.5", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "react-use-gesture": "^7.0.15", + "reakit": "^1.1.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^7.0.2" + } + }, + "node_modules/@wordpress/components/node_modules/@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "dependencies": { + "@emotion/primitives-core": "10.0.27" + }, + "peerDependencies": { + "react-native": ">=0.14.0 <1" + } + }, + "node_modules/@wordpress/components/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/components/node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/components/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/components/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/components/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/components/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/components/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/components/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/components/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/components/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/components/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/components/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/components/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/components/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/components/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/components/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/components/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/components/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/components/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/components/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/components/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/components/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/components/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/components/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/components/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/components/node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@wordpress/components/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/compose": { + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.25.3.tgz", + "integrity": "sha512-tCO2EnJCkCH548OqA0uU8V1k/1skz2QwBlHs8ZQSpimqUS4OWWsAlndCEFe4U4vDTqFt2ow7tzAir+05Cw8MAg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/priority-queue": "^1.11.2", + "clipboard": "^2.0.1", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.1.0", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/compose/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/core-data": { + "version": "2.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-2.26.3.tgz", + "integrity": "sha512-cbwOXB5AM37kBiZUUiXdSkbyJFNJ6CtkhkHkUvKoWkvvwLfGDre+BITr60NPJgw9o+MgsM/RfcBAsdRnz8/uJA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/element": "^2.20.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/url": "^2.22.2", + "equivalent-key-map": "^0.2.2", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/data": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.21.0.tgz", + "integrity": "sha512-+KU4+XKtVUqnPRBUlqD5yJXQNVoAPBZsp6KWNojd9Zhm4Sg/+8DGNo+fSpt5RQ+VJmUoRAqAk8UifQ6LZSuzQg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@wordpress/compose": "^3.18.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/element": "^2.15.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/priority-queue": "^1.7.0", + "@wordpress/redux-routine": "^3.10.0", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/data-controls": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/data-controls/-/data-controls-1.21.3.tgz", + "integrity": "sha512-aLpx/HvKaxCQfWSLGIz699SB9Guyq8Yoq5XLlH8eNWnf/8HkQg8hQ6yagDY8BinV/t8HScc5A7a6n6pvZNGtjg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3" + } + }, + "node_modules/@wordpress/data-controls/node_modules/@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "node_modules/@wordpress/data-controls/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/data-controls/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/date": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.10.0.tgz", + "integrity": "sha512-MEwPn1jzYfWGD2qmQkN0dvtzyARmYHC6zh2l/wAgN7tDdqSWXnS/n0RY9RmJVTxLYyHed+MNMTJiuI35aQsXPg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "moment": "^2.22.1", + "moment-timezone": "^0.5.16" + } + }, + "node_modules/@wordpress/dependency-extraction-webpack-plugin": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-2.8.0.tgz", + "integrity": "sha512-fEOsSl1kYY8gkiAe7OM9IopmSOtaAug37OQwKVeda5fK6xLsnpqprP5iwHHOApNWMEzgmVGS6/iW5IZoi7qv/A==", + "dev": true, + "dependencies": { + "json2php": "^0.0.4", + "webpack": "^4.8.3", + "webpack-sources": "^1.3.0" + } + }, + "node_modules/@wordpress/deprecated": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.12.3.tgz", + "integrity": "sha512-qr+yDfTQfI3M4h6oY6IeHWwoHr4jxbILjSlV+Ht6Jjto9Owap6OuzSqR13Ev4xqIoG4C7b5B3gZXVfwVDae1zg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^2.12.3" + } + }, + "node_modules/@wordpress/dom": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.18.0.tgz", + "integrity": "sha512-tM2WeQuSObl3nzWjUTF0/dyLnA7sdl/MXaSe32D64OF89bjSyJvjUipI7gjKzI3kJ7ddGhwcTggGvSB06MOoCQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/dom-ready": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-2.13.2.tgz", + "integrity": "sha512-COH7n2uZfBq4FtluSbl37N3nCEcdMXzV42ETCWKUcumiP1Zd3qnkfQKcsxTaHWY8aVt/358RvJ7ghWe3xAd+fg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/edit-post": { + "version": "3.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-3.27.3.tgz", + "integrity": "sha512-rxnW8zJrM+lK8oFyRCGykjcYUF3NcNm2+sm7po/kDT5pRB84Rbq8OxZBcIqvTbpbtjzkkBP+pwtiaTxRpQ1BPw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/block-library": "^2.29.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/editor": "^9.26.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/interface": "^2.0.2", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/plugins": "^2.25.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/url": "^2.22.2", + "@wordpress/viewport": "^2.26.3", + "@wordpress/warning": "^1.4.2", + "classnames": "^2.2.5", + "framer-motion": "^4.1.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "rememo": "^3.0.0", + "uuid": "8.3.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/block-editor/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/blocks/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "peerDependencies": { + "@wp-g2/create-styles": "^0.0.154", + "reakit-utils": "^0.15.1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "dependencies": { + "@emotion/primitives-core": "10.0.27" + }, + "peerDependencies": { + "react-native": ">=0.14.0 <1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/components/node_modules/react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/data/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/editor": { + "version": "9.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.26.3.tgz", + "integrity": "sha512-W3F/UnpjdEISkKqGv4NdwTgdzre3Ak3O6JGxaB4xWyFi6o4uz8ldlKpfacU9GJaX1wV1ajM8RkHGNDgyejPPdA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "rememo": "^3.0.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/editor/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/server-side-render": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.21.3.tgz", + "integrity": "sha512-pS2+LmTQX8S61TvaC+UyXqmFnQSXcJ3wcr3RPX1EwmpvlMuXlqdW8N5Y1TWuOT1G/ZDAwvTilLAlxeAMqrYSXA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/@wp-g2/create-styles/node_modules/@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/edit-post/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/edit-post/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/edit-post/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/edit-post/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/edit-post/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/edit-post/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/edit-post/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/edit-post/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/edit-post/node_modules/react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "dependencies": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@wordpress/edit-post/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@wordpress/edit-post/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/edit-post/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/edit-post/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/edit-post/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/edit-post/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/edit-post/node_modules/uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@wordpress/edit-post/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/editor": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.19.0.tgz", + "integrity": "sha512-rQp94jf0SPyqJVX1D8j8eCaanhsUEilctx0t3DLR3C+T2/wO0Tdk/b0Ws+F+PttNb4TUxFiN1S4QdTyB298EJQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@wordpress/api-fetch": "^3.18.0", + "@wordpress/autop": "^2.9.0", + "@wordpress/blob": "^2.9.0", + "@wordpress/block-directory": "^1.12.0", + "@wordpress/block-editor": "^4.2.0", + "@wordpress/blocks": "^6.19.0", + "@wordpress/components": "^9.9.0", + "@wordpress/compose": "^3.18.0", + "@wordpress/core-data": "^2.19.0", + "@wordpress/data": "^4.21.0", + "@wordpress/data-controls": "^1.15.0", + "@wordpress/date": "^3.10.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/element": "^2.15.0", + "@wordpress/hooks": "^2.9.0", + "@wordpress/html-entities": "^2.8.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/icons": "^2.3.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/keyboard-shortcuts": "^1.8.0", + "@wordpress/keycodes": "^2.14.0", + "@wordpress/media-utils": "^1.14.0", + "@wordpress/notices": "^2.7.0", + "@wordpress/rich-text": "^3.19.0", + "@wordpress/server-side-render": "^1.15.0", + "@wordpress/url": "^2.17.0", + "@wordpress/viewport": "^2.20.0", + "@wordpress/wordcount": "^2.10.0", + "classnames": "^2.2.5", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "react-autosize-textarea": "^3.0.2", + "redux-optimist": "^1.0.0", + "refx": "^3.0.0", + "rememo": "^3.0.0" + } + }, + "node_modules/@wordpress/element": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.20.3.tgz", + "integrity": "sha512-f4ZPTDf9CxiiOXiMxc4v1K7jcBMT4dsiehVOpkKzCDKboNXp4qVf8oe5PE23VGZNEjcOj5Mkg9hB57R0nqvMTw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^1.12.2", + "lodash": "^4.17.19", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/escape-html": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.12.2.tgz", + "integrity": "sha512-FabgSwznhdaUwe6hr1CsGpgxQbzqEoGevv73WIL1B9GvlZ6csRWodgHfWh4P6fYqpzxFL4WYB8wPJ1PdO32XFA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/eslint-plugin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.1.0.tgz", + "integrity": "sha512-FTrKkpEa8vZg7/7M6GBhd1YW24hnh5rFGzKgKX4MGyB0Jw8GGSwld9J23eRbQ5JQWGFP/tmOMeiu6W1/arxy7Q==", + "dev": true, + "dependencies": { + "@wordpress/prettier-config": "^0.3.0", + "babel-eslint": "^10.1.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^26.0.0", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.0.5", + "requireindex": "^1.2.0" + }, + "peerDependencies": { + "eslint": "^6 || ^7" + } + }, + "node_modules/@wordpress/eslint-plugin/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/eslint-plugin/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/hooks": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.12.3.tgz", + "integrity": "sha512-LmKiwKldZt6UYqOxV/a6+eUFXdvALFnB/pQx3RmrMvO64sgFhfR6dhrlv+uVbuuezSuv8dce1jx8lUWAT0krMA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/html-entities": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.11.2.tgz", + "integrity": "sha512-WIdEGO9/o7tuTV3jpLHhFC/NBBnNdJeG9nRZbEyb37CL1fvqJA85hTugyDOhGzOVIAtpFTc6kr/gMJK1oTdopw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/i18n": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.20.0.tgz", + "integrity": "sha512-SIoOJFB4UrrYAScS4H91CYCLW9dX3Ghv8pBKc/yHGculb1AdGr6gRMlmJxZV62Cn3CZ4Ga86c+FfR+GiBu0JPg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^2.12.3", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + } + }, + "node_modules/@wordpress/icons": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-2.10.3.tgz", + "integrity": "sha512-hVXArGOHLE5pL1G3rHNzsUEuTR4/G6lB+enKYwhYSSIqWuSbyXbZq3nvibxpepPrLy9B3d5t6aR6QUmjMVzIcQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/element": "^2.20.3", + "@wordpress/primitives": "^1.12.3" + } + }, + "node_modules/@wordpress/interface": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@wordpress/interface/-/interface-2.0.2.tgz", + "integrity": "sha512-yuuVRpcCAgKVPRj/C/c7vEjj64GdVxYOL5c9H+yvjPcMEazb36lquL2Xz846dtcCBO0/8sxz3wk5NI6sSwG/tw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/plugins": "^2.25.3", + "@wordpress/viewport": "^2.26.3", + "classnames": "^2.2.5", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/interface/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/interface/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "peerDependencies": { + "@wp-g2/create-styles": "^0.0.154", + "reakit-utils": "^0.15.1" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "dependencies": { + "@emotion/primitives-core": "10.0.27" + }, + "peerDependencies": { + "react-native": ">=0.14.0 <1" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/components/node_modules/react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/data/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "node_modules/@wordpress/interface/node_modules/@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wordpress/interface/node_modules/@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/interface/node_modules/@wp-g2/create-styles/node_modules/@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/interface/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/interface/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/interface/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/interface/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/interface/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/interface/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/interface/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/interface/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/interface/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/interface/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/interface/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/interface/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/interface/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/interface/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@wordpress/interface/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/interface/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/interface/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/interface/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/interface/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/interface/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/is-shallow-equal": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-2.3.0.tgz", + "integrity": "sha512-BUVCYZNDoT5fRJGoam/nI2Sn8QELu5z/pFe7UL+szFqQqNnMibdWqN/KoW/YO7WLJqqqTRhAs/Fa51g4oXRyHQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2" + } + }, + "node_modules/@wordpress/jest-console": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.10.0.tgz", + "integrity": "sha512-iS1GSO+o7+p2PhvScOquD+IK7WqmVxa2s9uTUQyNEo06f9EUv6KNw0B1iZ00DpbgLqDCiczfdCNapC816UXIIA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "jest-matcher-utils": "^25.3.0", + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "jest": ">=24" + } + }, + "node_modules/@wordpress/jest-preset-default": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-6.6.0.tgz", + "integrity": "sha512-9HbKUNRMUCooXAKt+6jj5SZjDMtWoR9yMb9bJ5eCd9wUfrfQ/x2nUJK/RXiv1aI85HHmzl5KfQquZF76lYEkcw==", + "dev": true, + "dependencies": { + "@jest/reporters": "^25.3.0", + "@wordpress/jest-console": "^3.10.0", + "babel-jest": "^25.3.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "enzyme-to-json": "^3.4.4" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "jest": ">=25" + } + }, + "node_modules/@wordpress/keyboard-shortcuts": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-1.14.3.tgz", + "integrity": "sha512-p7dvsaAckYRwFp5FeaeYm1IrA2KoXFq3D9mFALftdDQuLkx3XRk6f0IjgxYTePcWM5hS2Bc07UCAcNKyouFIGw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/element": "^2.20.3", + "@wordpress/keycodes": "^2.19.3", + "lodash": "^4.17.19", + "rememo": "^3.0.0" + } + }, + "node_modules/@wordpress/keyboard-shortcuts/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/keyboard-shortcuts/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/keycodes": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.19.3.tgz", + "integrity": "sha512-8rNdmP5M1ifTgLIL0dt/N1uTGsq/Rx1ydCXy+gg24WdxBRhyu5sudNVCtascVXo26aIfOH9OJRdqRZZTEORhog==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/media-utils": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-1.20.3.tgz", + "integrity": "sha512-938LnUQPMhC6mKMJ4/fILC0+jseSg3b6ABdhSDkdOQdrSVKy+zabfd/w1BQ9I5MnsuviLsAyeaq5alpTmdHTwg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blob": "^2.13.2", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/media-utils/node_modules/@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "node_modules/@wordpress/notices": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-2.13.3.tgz", + "integrity": "sha512-lutDWWlw5r+EYSHZvJ/l4fHNharjPvF92EexoHjk+B9pVzxMtbtJv2dHeffu8BjcuYvke8OJbydlUYaa0SoeLQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/data": "^4.27.3", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/notices/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/notices/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/npm-package-json-lint-config": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-3.1.0.tgz", + "integrity": "sha512-SYRWpzpQaSsBUiRO+ssqg6AHjgCF4j2npstGTGaKdVs/B720fLFzeyONuMmo1ZtMb9v6MyEWxVz5ON6dDgmVYg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "npm-package-json-lint": ">=3.6.0" + } + }, + "node_modules/@wordpress/plugins": { + "version": "2.25.3", + "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-2.25.3.tgz", + "integrity": "sha512-I61O0cWT2nSXEuOP/C2bmgRU7Hhj6e/SXaUKJyfZd7hs16Ihp1a2NJh23jDhFS3wZ/4SY7bZgRnVNGRaBZAacw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/icons": "^2.10.3", + "lodash": "^4.17.19", + "memize": "^1.1.0" + } + }, + "node_modules/@wordpress/postcss-plugins-preset": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-plugins-preset/-/postcss-plugins-preset-1.6.0.tgz", + "integrity": "sha512-WPToVlX99PiUSSxSbwAR2wJtIpbcnnRkB48sIIkDvw7rCpSWkh6OLuzfj0o5g+JCYuNL1OnQXFA8EtydNEZ9Sw==", + "dev": true, + "dependencies": { + "@wordpress/base-styles": "^3.3.0", + "@wordpress/postcss-themes": "^2.6.0", + "autoprefixer": "^9.8.6", + "postcss-custom-properties": "^10.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/postcss-themes": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-themes/-/postcss-themes-2.6.0.tgz", + "integrity": "sha512-Q22s1KSVdtoK0Z0ND06V2QwTx/U4KvJhWFmoI8IzYW/LGlk8BkQJhHH157Y9vFliwpMlQpqfXW6/zOg2XtvHzQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.32" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/prettier-config": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.3.0.tgz", + "integrity": "sha512-wL1ztV+so5Ttwz23lDmb8ZmREmND96sf+Dh/kbP2nyAw/DWt3K8uj31qbczVmjwfoetTiRoH9Z1CasgPs4bccg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/primitives": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-1.12.3.tgz", + "integrity": "sha512-LIF44bVlJS7CJEVmk6TLuV6HZMdj5iwkyM8do4ukGY6qnZIzrXpBablgJeDBcyjzWrWRLn+w+tiZ/8l+2egoVA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/element": "^2.20.3", + "classnames": "^2.2.5" + } + }, + "node_modules/@wordpress/priority-queue": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-1.11.2.tgz", + "integrity": "sha512-ulwmUOklY3orn1xXpcPnTyGWV5B/oycxI+cHZ6EevBVgM5sq+BW3xo0PKLR/MMm6UNBtFTu/71QAJrNZcD6V1g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/redux-routine": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-3.14.2.tgz", + "integrity": "sha512-aqi4UtvMP/+NhULxyCR8ktG0v4BJVTRcMpByAqDg7Oabq2sz2LPuShxd5UY8vxQYQY9t1uUJbslhom4ytcohWg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "rungen": "^0.3.2" + } + }, + "node_modules/@wordpress/reusable-blocks": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-1.2.3.tgz", + "integrity": "sha512-Q6jXwbTYg2Uu/kAdqkwosp2IYjOE9qgvkE+m4UpMtRyQDpjMunN3i3gGb/J7UexybtyjfH75VibZbYrjoUP+OQ==", + "dev": true, + "dependencies": { + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/block-editor/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/blocks/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "peerDependencies": { + "@wp-g2/create-styles": "^0.0.154", + "reakit-utils": "^0.15.1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "dependencies": { + "@emotion/primitives-core": "10.0.27" + }, + "peerDependencies": { + "react-native": ">=0.14.0 <1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/components/node_modules/react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/data/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wp-g2/create-styles/node_modules/@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/reusable-blocks/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/reusable-blocks/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "dependencies": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@wordpress/reusable-blocks/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/rich-text": { + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.25.3.tgz", + "integrity": "sha512-FdqL1/rHTsRxZ1gW1UEWuy0URmUEqMzj5hcAbOhHFPO5m0ENrkzC9bBa195KqZBSNSmBmXnDZdHu4UJUolzcZg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/escape-html": "^1.12.2", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "rememo": "^3.0.0" + } + }, + "node_modules/@wordpress/rich-text/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/rich-text/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/scripts": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-12.6.1.tgz", + "integrity": "sha512-pDLtACFrP5gUA414qrE49dUrR7yMy40+//1e/5Nx821lnmDb7GAGWGo1gX4lJ2gbfSjePwmRoZe6Mph87vSnLQ==", + "dev": true, + "dependencies": { + "@svgr/webpack": "^5.2.0", + "@wordpress/babel-preset-default": "^4.20.0", + "@wordpress/dependency-extraction-webpack-plugin": "^2.9.0", + "@wordpress/eslint-plugin": "^7.4.0", + "@wordpress/jest-preset-default": "^6.6.0", + "@wordpress/npm-package-json-lint-config": "^3.1.0", + "@wordpress/postcss-plugins-preset": "^1.6.0", + "@wordpress/prettier-config": "^0.4.0", + "babel-jest": "^25.3.0", + "babel-loader": "^8.1.0", + "chalk": "^4.0.0", + "check-node-version": "^3.1.1", + "clean-webpack-plugin": "^3.0.0", + "cross-spawn": "^5.1.0", + "css-loader": "^3.5.2", + "dir-glob": "^3.0.1", + "eslint": "^7.1.0", + "eslint-plugin-markdown": "^1.0.2", + "ignore-emit-webpack-plugin": "^2.0.6", + "jest": "^25.3.0", + "jest-puppeteer": "^4.4.0", + "markdownlint": "^0.18.0", + "markdownlint-cli": "^0.21.0", + "mini-css-extract-plugin": "^0.9.0", + "minimist": "^1.2.0", + "npm-package-json-lint": "^5.0.0", + "postcss-loader": "^3.0.0", + "prettier": "npm:wp-prettier@2.2.1-beta-1", + "puppeteer": "npm:puppeteer-core@3.0.0", + "read-pkg-up": "^1.0.1", + "resolve-bin": "^0.4.0", + "sass": "^1.26.11", + "sass-loader": "^8.0.2", + "source-map-loader": "^0.2.4", + "stylelint": "^13.6.0", + "stylelint-config-wordpress": "^17.0.0", + "terser-webpack-plugin": "^3.0.3", + "thread-loader": "^2.1.3", + "url-loader": "^3.0.0", + "webpack": "^4.42.0", + "webpack-bundle-analyzer": "^3.6.1", + "webpack-cli": "^3.3.11", + "webpack-livereload-plugin": "^2.3.0" + }, + "bin": { + "wp-scripts": "bin/wp-scripts.js" + }, + "engines": { + "node": ">=10", + "npm": ">=6.9" + } + }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/dependency-extraction-webpack-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-2.9.0.tgz", + "integrity": "sha512-Eo8ByPd3iZ6az4UmdLD2xYLp1/7os/H80l28Y5OlS4DozkD3vcWCBReynWoBax74u3oJ9wWN5b/8oSxGwIKXYQ==", + "dev": true, + "dependencies": { + "json2php": "^0.0.4", + "webpack-sources": "^1.3.0" + }, + "peerDependencies": { + "webpack": "^4.8.3 || ^5.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/eslint-plugin": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.4.0.tgz", + "integrity": "sha512-HJpDYz2drtC9rY8MiYtYJ3cimioEIweGyb3P2DQTjUZ3sC4AGg+97PhXLHUdKfsFQ31JRxyLS9kKuGdDVBwWww==", + "dev": true, + "dependencies": { + "@wordpress/prettier-config": "^0.4.0", + "babel-eslint": "^10.1.0", + "cosmiconfig": "^7.0.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^30.2.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.2.1-beta-1", + "requireindex": "^1.2.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6.9" + }, + "peerDependencies": { + "eslint": "^6 || ^7" + } + }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/prettier-config": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.4.0.tgz", + "integrity": "sha512-7c4VeugkCwDkaHSD7ffxoP0VC5c///gCTEAT032OhI5Rik2dPxE3EkNAB2NhotGE8M4dMAg4g5Wj2OWZIn8TFw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/scripts/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/scripts/node_modules/cacache": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "dev": true, + "dependencies": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/scripts/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/scripts/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/scripts/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/scripts/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@wordpress/scripts/node_modules/css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/eslint-plugin-jsdoc": { + "version": "30.7.13", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.7.13.tgz", + "integrity": "sha512-YM4WIsmurrp0rHX6XiXQppqKB8Ne5ATiZLJe2+/fkp9l9ExXFr43BbAbjZaVrpCT+tuPYOZ8k1MICARHnURUNQ==", + "dev": true, + "dependencies": { + "comment-parser": "^0.7.6", + "debug": "^4.3.1", + "jsdoctypeparser": "^9.0.0", + "lodash": "^4.17.20", + "regextras": "^0.7.1", + "semver": "^7.3.4", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/scripts/node_modules/find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/@wordpress/scripts/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/scripts/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/scripts/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/jsdoctypeparser": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==", + "dev": true, + "bin": { + "jsdoctypeparser": "bin/jsdoctypeparser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/scripts/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/@wordpress/scripts/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@wordpress/scripts/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/scripts/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/scripts/node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@wordpress/scripts/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/scripts/node_modules/postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "dependencies": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@wordpress/scripts/node_modules/postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "dependencies": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "node_modules/@wordpress/scripts/node_modules/prettier": { + "name": "wp-prettier", + "version": "2.2.1-beta-1", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.2.1-beta-1.tgz", + "integrity": "sha512-+JHkqs9LC/JPp51yy1hzs3lQ7qeuWCwOcSzpQNeeY/G7oSpnF61vxt7hRh87zNRTr6ob2ndy0W8rVzhgrcA+Gw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@wordpress/scripts/node_modules/sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0", + "sass": "^1.3.0", + "webpack": "^4.36.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/@wordpress/scripts/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@wordpress/scripts/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/scripts/node_modules/tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/scripts/node_modules/terser-webpack-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz", + "integrity": "sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA==", + "dev": true, + "dependencies": { + "cacache": "^15.0.5", + "find-cache-dir": "^3.3.1", + "jest-worker": "^26.2.1", + "p-limit": "^3.0.2", + "schema-utils": "^2.6.6", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.8.0", + "webpack-sources": "^1.4.3" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/scripts/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@wordpress/server-side-render": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.15.0.tgz", + "integrity": "sha512-umRhtIVtWd2vqHPdDOk7qF3crld1OnOyyKrjAzTZAdlosqHsExgvcRvEri1YPs7R181wcbyNWoJdNp6ITIVsKg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@wordpress/api-fetch": "^3.18.0", + "@wordpress/components": "^9.9.0", + "@wordpress/data": "^4.21.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/element": "^2.15.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/url": "^2.17.0", + "lodash": "^4.17.15" + } + }, + "node_modules/@wordpress/shortcode": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-2.13.2.tgz", + "integrity": "sha512-n4O5O66ARGY+h1SCvt0uOIQAJ6B4hd6EjULAWRNYgQuuF9mdhcczpGvSH76BssuvLN6bJU1RjsVy7m56kqO5xw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19", + "memize": "^1.1.0" + } + }, + "node_modules/@wordpress/token-list": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.15.3.tgz", + "integrity": "sha512-UrAnXgn05wmlS0GLPoxHZBtjjzB7TA4wX/1MV57LcLngifUKKPuNl0kMur/bQcPU+AAczbHKy/0vSvKHiZdoNg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/url": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.22.2.tgz", + "integrity": "sha512-aqpYKQXzyzkCOm+GzZRYlLb+wh58g0cwR1PaKAl0UXaBS4mdS+X6biMriylb4P8CVC/RR7CSw5XI20JC24KDwQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19", + "react-native-url-polyfill": "^1.1.2" + } + }, + "node_modules/@wordpress/url/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@wordpress/url/node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@wordpress/url/node_modules/@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "dependencies": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + }, + "bin": { + "react-native": "build/bin.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react-native": ">=0.64.0-rc.0 || 0.0.0-*" + } + }, + "node_modules/@wordpress/url/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@wordpress/url/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@wordpress/url/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/url/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@wordpress/url/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/url/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/url/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/@wordpress/url/node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@wordpress/url/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/url/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/url/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/url/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/url/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/url/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/@wordpress/url/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@wordpress/url/node_modules/react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@wordpress/url/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "node_modules/@wordpress/url/node_modules/react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "17.0.1" + } + }, + "node_modules/@wordpress/url/node_modules/react-native-url-polyfill": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.3.0.tgz", + "integrity": "sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ==", + "dev": true, + "dependencies": { + "whatwg-url-without-unicode": "8.0.0-3" + }, + "peerDependencies": { + "react-native": "*" + } + }, + "node_modules/@wordpress/url/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@wordpress/url/node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/@wordpress/url/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/url/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@wordpress/url/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/url/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@wordpress/viewport": { + "version": "2.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.26.3.tgz", + "integrity": "sha512-CjTMPgWDmcBIa3sEd3wcIhULFsJgStiHJWEtRVHfM2fp/ZApaXrvldHJJxkoHhT5OuLet9JlNnNoD1ZvcUoE1g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "lodash": "^4.17.19" + } + }, + "node_modules/@wordpress/viewport/node_modules/@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "node_modules/@wordpress/viewport/node_modules/@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/warning": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-1.4.2.tgz", + "integrity": "sha512-MjrkSp6Jyfx+92AE32A83P503noUtGb6//BYUH4GiWzzzSNhDHgbQ0UcOJwJaEYK166DxSNpMk/JXc4YENi1Cw==", + "dev": true + }, + "node_modules/@wordpress/wordcount": { + "version": "2.15.2", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.15.2.tgz", + "integrity": "sha512-y7dltZQrdtUatzpDVpZxNfXeDva4xRw30lO57MkxmeqlWOpZCrgCK7czNbebTC1CUXZ9xbKiOrNdnFgE6CnoOw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19" + } + }, + "node_modules/@wp-g2/components": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/components/-/components-0.0.160.tgz", + "integrity": "sha512-44qUtiF5Nl/srD7Vzbpcd0im/EIej04fOdDfa0lfDxXJDNK3RRtSSEwCRhok/M5SKCmvYbZKRUx2K0ugXNqK0Q==", + "dev": true, + "dependencies": { + "@popperjs/core": "^2.5.4", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "csstype": "^3.0.3", + "downshift": "^6.0.15", + "framer-motion": "^2.1.0", + "highlight-words-core": "^1.2.2", + "history": "^4.9.0", + "lodash": "^4.17.19", + "path-to-regexp": "^1.7.0", + "react-colorful": "4.4.4", + "react-textarea-autosize": "^8.2.0", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.4" + }, + "peerDependencies": { + "@wordpress/i18n": ">=3.17.0", + "@wordpress/icons": ">=2.9", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wp-g2/components/node_modules/csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, + "node_modules/@wp-g2/components/node_modules/downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/@wp-g2/components/node_modules/framer-motion": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-2.9.5.tgz", + "integrity": "sha512-epSX4Co1YbDv0mjfHouuY0q361TpHE7WQzCp/xMTilxy4kXd+Z23uJzPVorfzbm1a/9q1Yu8T5bndaw65NI4Tg==", + "dev": true, + "dependencies": { + "framesync": "^4.1.0", + "hey-listen": "^1.0.8", + "popmotion": "9.0.0-rc.20", + "style-value-types": "^3.1.9", + "tslib": "^1.10.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@wp-g2/components/node_modules/framesync": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-4.1.0.tgz", + "integrity": "sha512-MmgZ4wCoeVxNbx2xp5hN/zPDCbLSKiDt4BbbslK7j/pM2lg5S0vhTNv1v8BCVb99JPIo6hXBFdwzU7Q4qcAaoQ==", + "dev": true, + "dependencies": { + "hey-listen": "^1.0.5" + } + }, + "node_modules/@wp-g2/components/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/@wp-g2/components/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/@wp-g2/components/node_modules/popmotion": { + "version": "9.0.0-rc.20", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-9.0.0-rc.20.tgz", + "integrity": "sha512-f98sny03WuA+c8ckBjNNXotJD4G2utG/I3Q23NU69OEafrXtxxSukAaJBxzbtxwDvz3vtZK69pu9ojdkMoBNTg==", + "dev": true, + "dependencies": { + "framesync": "^4.1.0", + "hey-listen": "^1.0.8", + "style-value-types": "^3.1.9", + "tslib": "^1.10.0" + } + }, + "node_modules/@wp-g2/components/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@wp-g2/components/node_modules/react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/@wp-g2/components/node_modules/style-value-types": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-3.2.0.tgz", + "integrity": "sha512-ih0mGsrYYmVvdDi++/66O6BaQPRPRMQHoZevNNdMMcPlP/cH28Rnfsqf1UEba/Bwfuw9T8BmIMwbGdzsPwQKrQ==", + "dev": true, + "dependencies": { + "hey-listen": "^1.0.8", + "tslib": "^1.10.0" + } + }, + "node_modules/@wp-g2/components/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@wp-g2/context": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/context/-/context-0.0.160.tgz", + "integrity": "sha512-50wSQCZkdZEexP88Ljutskn7/klT2Id1ks4GpzKDSBM8kadrfNdr2iabjgJdFLIH33S+r4dzEnzLs9SFtqUgwg==", + "dev": true, + "dependencies": { + "@wp-g2/create-styles": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "lodash": "^4.17.19" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/compose": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-4.1.2.tgz", + "integrity": "sha512-9QdldUzcsmBPB9hj3tzPMdjHktM8FNvRqXIW2Ese0MFLV8gvrRP1JQ6tstxW59AtuRgVw0nWz2fSt0nmsjnN8Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/dom": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/keycodes": "^3.1.1", + "@wordpress/priority-queue": "^2.1.1", + "clipboard": "^2.0.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.1.0", + "use-memo-one": "^1.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/data": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-5.1.2.tgz", + "integrity": "sha512-QtDlGaa6SvQmll24DDvQ0CvbtD70u0XEFPfSC7gWGFO0/mpBkrmZLUCth17cC3kfdjn+5BgefKGV3/uvHjJFqA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^4.1.2", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/priority-queue": "^2.1.1", + "@wordpress/redux-routine": "^4.1.1", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "redux": "^4.1.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/deprecated": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-3.1.1.tgz", + "integrity": "sha512-0hILlCNhf0DukFo3hMWybf9q507cxnIHhC1GQ1crZtTqzKS2QY2C1/77V4YGPdBShUj5j1dPriYCzfB5jFFgqQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/dom": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-3.1.1.tgz", + "integrity": "sha512-NkNkgczdQweWXXiP7uaXmuu58JsRU/WN9OTWT0pVTZumTQKsvm0Fcs55jt3NBG+X/F80DC+DPVW6+sTKv0Lqxg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/element": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-3.1.1.tgz", + "integrity": "sha512-OaqKQVEV3CCTdrx/G7fMbmxhrxjApobHUAGAVYCCR1MIqScfluYJRLWFLx8tlkl/Qm/UbF9IfdXS1lphufvYog==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^2.1.1", + "lodash": "^4.17.21", + "react": "^16.13.1", + "react-dom": "^16.13.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/escape-html": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.1.1.tgz", + "integrity": "sha512-ZIkLxGLBhXkZu3t0yF82/brPV5aCOGCXGiH0EMV8GCohhXCNIfQwwFrZ5gd5NyNX5Q8alTLsiA84azJd+n0XiQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/hooks": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.1.1.tgz", + "integrity": "sha512-9f6H9WBwu6x/MM4ZCVLGGBuMiBcyaLapmAku5IwcWaeB2PtPduwjmk2NfGx35TuhBQD554DUg8WtTjIS019UAg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/i18n": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.1.1.tgz", + "integrity": "sha512-Ra/hxR8WCLqDp2P49Ibr9ANhZZZ8WHnsO+4WG3XDarJ3lmzux0TcRThDKRCcYHsW3pzieARmrEa/BOlYD7ZEjQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/keycodes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-3.1.1.tgz", + "integrity": "sha512-lLJTl/PJv0F5c02YfFdzS/sspmMM3kWYcix8sXsAQgjzLkOMizSQySBa3bpT2t5auN0YQ34YVyeupVfoY+evOQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^4.1.1", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/priority-queue": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-2.1.1.tgz", + "integrity": "sha512-e4x4B+1F2wXejqjNr6L3LTf5aO7gzy/9MWy5pUgg1rlo8z+B73OyOUmK39WOnzFtzmwTbFqgzzCwY5JqIaZe2g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wordpress/redux-routine": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-4.1.1.tgz", + "integrity": "sha512-wjHASkmDPiOhnTZGn43kBj5RDVnSTRpj3EHL8boUGmOMiEFm/bUAfefhyvlo9ksBF4ZQm2pJjJTWtp5zE1drgg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "rungen": "^0.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/context/node_modules/@wp-g2/create-styles": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.160.tgz", + "integrity": "sha512-2/q8jcB9wIyfxkoCfNhz+9otRmAbDwfgk3nSEFhyz9ExR+OCqNUWqmITE3TZ4hYaSsV8E/gUUO4JjnPPy989bA==", + "dev": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/hash": "^0.8.0", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.160", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wp-g2/styles": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/styles/-/styles-0.0.160.tgz", + "integrity": "sha512-o91jxb0ZwEDRJrtVVjnqn3qTAXjnxZ1fX5KF3Q7oz776lMZPHsyfC0hvqnOz0w7zqaZZpdWtVQRShgrYXN6JHw==", + "dev": true, + "dependencies": { + "@wp-g2/create-styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/compose": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-4.1.2.tgz", + "integrity": "sha512-9QdldUzcsmBPB9hj3tzPMdjHktM8FNvRqXIW2Ese0MFLV8gvrRP1JQ6tstxW59AtuRgVw0nWz2fSt0nmsjnN8Q==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/dom": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/keycodes": "^3.1.1", + "@wordpress/priority-queue": "^2.1.1", + "clipboard": "^2.0.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.1.0", + "use-memo-one": "^1.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/data": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-5.1.2.tgz", + "integrity": "sha512-QtDlGaa6SvQmll24DDvQ0CvbtD70u0XEFPfSC7gWGFO0/mpBkrmZLUCth17cC3kfdjn+5BgefKGV3/uvHjJFqA==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^4.1.2", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/priority-queue": "^2.1.1", + "@wordpress/redux-routine": "^4.1.1", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "redux": "^4.1.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/deprecated": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-3.1.1.tgz", + "integrity": "sha512-0hILlCNhf0DukFo3hMWybf9q507cxnIHhC1GQ1crZtTqzKS2QY2C1/77V4YGPdBShUj5j1dPriYCzfB5jFFgqQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/dom": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-3.1.1.tgz", + "integrity": "sha512-NkNkgczdQweWXXiP7uaXmuu58JsRU/WN9OTWT0pVTZumTQKsvm0Fcs55jt3NBG+X/F80DC+DPVW6+sTKv0Lqxg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/element": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-3.1.1.tgz", + "integrity": "sha512-OaqKQVEV3CCTdrx/G7fMbmxhrxjApobHUAGAVYCCR1MIqScfluYJRLWFLx8tlkl/Qm/UbF9IfdXS1lphufvYog==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^2.1.1", + "lodash": "^4.17.21", + "react": "^16.13.1", + "react-dom": "^16.13.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/escape-html": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.1.1.tgz", + "integrity": "sha512-ZIkLxGLBhXkZu3t0yF82/brPV5aCOGCXGiH0EMV8GCohhXCNIfQwwFrZ5gd5NyNX5Q8alTLsiA84azJd+n0XiQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/hooks": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.1.1.tgz", + "integrity": "sha512-9f6H9WBwu6x/MM4ZCVLGGBuMiBcyaLapmAku5IwcWaeB2PtPduwjmk2NfGx35TuhBQD554DUg8WtTjIS019UAg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/i18n": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.1.1.tgz", + "integrity": "sha512-Ra/hxR8WCLqDp2P49Ibr9ANhZZZ8WHnsO+4WG3XDarJ3lmzux0TcRThDKRCcYHsW3pzieARmrEa/BOlYD7ZEjQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/keycodes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-3.1.1.tgz", + "integrity": "sha512-lLJTl/PJv0F5c02YfFdzS/sspmMM3kWYcix8sXsAQgjzLkOMizSQySBa3bpT2t5auN0YQ34YVyeupVfoY+evOQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^4.1.1", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/priority-queue": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-2.1.1.tgz", + "integrity": "sha512-e4x4B+1F2wXejqjNr6L3LTf5aO7gzy/9MWy5pUgg1rlo8z+B73OyOUmK39WOnzFtzmwTbFqgzzCwY5JqIaZe2g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wordpress/redux-routine": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-4.1.1.tgz", + "integrity": "sha512-wjHASkmDPiOhnTZGn43kBj5RDVnSTRpj3EHL8boUGmOMiEFm/bUAfefhyvlo9ksBF4ZQm2pJjJTWtp5zE1drgg==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "rungen": "^0.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wp-g2/styles/node_modules/@wp-g2/create-styles": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.160.tgz", + "integrity": "sha512-2/q8jcB9wIyfxkoCfNhz+9otRmAbDwfgk3nSEFhyz9ExR+OCqNUWqmITE3TZ4hYaSsV8E/gUUO4JjnPPy989bA==", + "dev": true, + "dependencies": { + "@emotion/core": "^10.1.1", + "@emotion/hash": "^0.8.0", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.160", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "peerDependencies": { + "@wordpress/data": ">=4.26", + "@wordpress/is-shallow-equal": ">=3.0", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@wp-g2/utils": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.160.tgz", + "integrity": "sha512-4FhezjKyeYVb+3PZahW1kmqXpCvVvuJM97EcGqkKf+u4Qf66J3n1niHgfnRbn8aNydYK6EFze+6/UL48U35z1w==", + "dev": true, + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "peer": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/absolute-path": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", + "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=", + "dev": true, + "peer": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/airbnb-prop-types": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", + "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", + "dev": true, + "dependencies": { + "array.prototype.find": "^2.1.1", + "function.prototype.name": "^1.1.2", + "is-regex": "^1.1.0", + "object-is": "^1.1.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.13.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0-alpha" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", + "dev": true, + "peer": true + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-fragments": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", + "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", + "dev": true, + "peer": true, + "dependencies": { + "colorette": "^1.0.7", + "slice-ansi": "^2.0.0", + "strip-ansi": "^5.0.0" + } + }, + "node_modules/ansi-fragments/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-fragments/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-fragments/node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-fragments/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/anymatch/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/appdirsjs": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.5.tgz", + "integrity": "sha512-UyaAyzj+7XLoKhbXJi4zoAw8IDXCiLNCKfQEiuCsCCTkDmiG1vpCliQn/MoUvO3DZqCN1i6gOahokcFtNSIrVA==", + "dev": true, + "peer": true + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "node_modules/array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true, + "peer": true + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true, + "peer": true + }, + "node_modules/array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true, + "peer": true + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.0.tgz", + "integrity": "sha512-TfO1gz+tLm+Bswq0FBOXPqAchtCr2Rn48T8dLJoRFl8NoEosjZmzptmuo1X8aZBzZcqsR1W8U761tjACJtngTQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.find": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz", + "integrity": "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "peer": true + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-types": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", + "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", + "dev": true, + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "dev": true + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true, + "optional": true + }, + "node_modules/async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "dev": true, + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/autosize": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", + "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ==", + "dev": true + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/axe-core": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz", + "integrity": "sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, + "node_modules/babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", + "dev": true, + "peer": true, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "eslint": ">= 4.12.1" + } + }, + "node_modules/babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "dependencies": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-loader": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", + "dev": true, + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^1.4.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/babel-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/babel-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/babel-loader/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-emotion": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz", + "integrity": "sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-module-resolver": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", + "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", + "dev": true, + "dependencies": { + "find-babel-config": "^1.1.0", + "glob": "^7.1.2", + "pkg-up": "^2.0.0", + "reselect": "^3.0.1", + "resolve": "^1.4.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/babel-plugin-module-resolver/node_modules/reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=", + "dev": true + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz", + "integrity": "sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.14.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "node_modules/babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", + "dev": true, + "peer": true + }, + "node_modules/babel-plugin-transform-html-import-to-string": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-html-import-to-string/-/babel-plugin-transform-html-import-to-string-0.0.1.tgz", + "integrity": "sha1-lJFSUV2q12TPVcUasXh9IG3s+J0=", + "dev": true + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", + "dev": true + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", + "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-fbjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + }, + "engines": { + "node": ">= 8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/backbone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.3.3.tgz", + "integrity": "sha1-TMgOp8sWMaxHSInOQPL4vGg7KZk=", + "dev": true, + "dependencies": { + "underscore": ">=1.8.3" + } + }, + "node_modules/backbone.marionette": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/backbone.marionette/-/backbone.marionette-3.5.1.tgz", + "integrity": "sha1-yyLKaM+YbLzan9tUT7eF3Wb48kg=", + "dev": true, + "dependencies": { + "backbone.radio": "^2.0.0" + }, + "peerDependencies": { + "backbone": "~1.3.3", + "underscore": "~1.8.3" + } + }, + "node_modules/backbone.radio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/backbone.radio/-/backbone.radio-2.0.0.tgz", + "integrity": "sha1-u+hnKzc+MT+Z820vvPWD/nfQT0I=", + "dev": true, + "peerDependencies": { + "backbone": "^1.3.3", + "underscore": "^1.8.3" + } + }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "dependencies": { + "inherits": "~2.0.0" + }, + "engines": { + "node": "0.4 || >=0.5.8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "dev": true, + "dependencies": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/body-scroll-lock": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz", + "integrity": "sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==", + "dev": true + }, + "node_modules/body/node_modules/bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", + "dev": true + }, + "node_modules/body/node_modules/raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "dev": true, + "dependencies": { + "bytes": "1", + "string_decoder": "0.10" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/body/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/bplist-creator": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", + "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", + "dev": true, + "peer": true, + "dependencies": { + "stream-buffers": "~2.2.0" + } + }, + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "peer": true, + "dependencies": { + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brcast": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brcast/-/brcast-2.0.2.tgz", + "integrity": "sha512-Tfn5JSE7hrUlFcOoaLzVvkbgIemIorMIyoMr3TgvszWW7jFt2C9PdeMLtysYD9RU0MmU17b69+XJG1eRY2OBRg==", + "dev": true + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "devOptional": true, + "dependencies": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001242", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz", + "integrity": "sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug==", + "devOptional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/check-node-version": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/check-node-version/-/check-node-version-3.3.0.tgz", + "integrity": "sha512-OAtp7prQf+8YYKn2UB/fK1Ppb9OT+apW56atoKYUvucYLPq69VozOY0B295okBwCKymk2cictrS3qsdcZwyfzw==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "map-values": "^1.0.1", + "minimist": "^1.2.0", + "object-filter": "^1.0.2", + "object.assign": "^4.0.4", + "run-parallel": "^1.1.4", + "semver": "^5.0.3" + }, + "bin": { + "check-node-version": "bin.js" + } + }, + "node_modules/check-node-version/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", + "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "css-what": "^5.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/chokidar/node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/chokidar/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/chokidar/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/circular-json-es6": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/circular-json-es6/-/circular-json-es6-2.0.2.tgz", + "integrity": "sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/clean-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", + "dev": true, + "dependencies": { + "@types/webpack": "^4.4.31", + "del": "^4.1.1" + }, + "engines": { + "node": ">=8.9.0" + }, + "peerDependencies": { + "webpack": "*" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "peer": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboard": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", + "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", + "dev": true, + "dependencies": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/codemirror": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.0.tgz", + "integrity": "sha512-Xnl3304iCc8nyVZuRkzDVVwc794uc9QNX0UcPGeNic1fbzkSrO4l4GVXho9tRNKBgPYZXgocUqXyfIv3BILhCQ==" + }, + "node_modules/collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "devOptional": true + }, + "node_modules/colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true, + "peer": true + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/comment-parser": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz", + "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "peer": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "peer": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz", + "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==", + "dev": true + }, + "node_modules/computed-style": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz", + "integrity": "sha1-fzRP2FhLLkJb7cpKGvwOMAuwXXQ=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/consolidated-events": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/consolidated-events/-/consolidated-events-2.0.2.tgz", + "integrity": "sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "devOptional": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-concurrently/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "dev": true, + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-js-compat": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz", + "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/core-js-pure": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.2.tgz", + "integrity": "sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-emotion": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.27.tgz", + "integrity": "sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==", + "dev": true, + "dependencies": { + "@emotion/cache": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-loader": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", + "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "dev": true, + "dependencies": { + "camelcase": "^5.2.0", + "icss-utils": "^4.1.0", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.14", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.6", + "postcss-modules-scope": "^2.1.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/css-loader/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/css-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/css-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/css-loader/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/css-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=", + "dev": true + }, + "node_modules/css-select": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "node_modules/css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "dev": true, + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/css-to-react-native/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/csstype": { + "version": "2.6.17", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", + "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==", + "dev": true + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cwd": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", + "integrity": "sha1-FyQAaUBXwioTsM8WFix+S3p/5Wc=", + "dev": true, + "dependencies": { + "find-pkg": "^0.1.2", + "fs-exists-sync": "^0.1.0" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", + "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/dayjs": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.5.tgz", + "integrity": "sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g==", + "dev": true, + "peer": true + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "devOptional": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-equal-ident": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz", + "integrity": "sha1-BvS4nlNxDNbOpKd4HHqVZkLejck=", + "dev": true, + "dependencies": { + "lodash.isequal": "^3.0" + } + }, + "node_modules/deep-equal-ident/node_modules/lodash.isequal": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz", + "integrity": "sha1-HDXrO27wzR/1F0Pj6jz3/f/ay2Q=", + "dev": true, + "dependencies": { + "lodash._baseisequal": "^3.0.0", + "lodash._bindcallback": "^3.0.0" + } + }, + "node_modules/deep-extend": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/deep-freeze": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", + "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "peer": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "dev": true + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "dev": true, + "peer": true + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/direction": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", + "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==", + "dev": true, + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/document.contains": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/document.contains/-/document.contains-1.0.2.tgz", + "integrity": "sha512-YcvYFs15mX8m3AO1QNQy3BlIpSMfNRj3Ujk2BEJxsZG+HZf7/hZ6jr7mDpXrF8q+ff95Vef5yjhiZxm8CGJr6Q==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-helpers/node_modules/csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + }, + "node_modules/dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz", + "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/downshift": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-4.1.0.tgz", + "integrity": "sha512-GODZOZC65a8n8YD/S/87hR2t5PJfqZ7+lwEBJsNi/AJnhImfle+CFD/ZPde4l+nB8QNHfn0GbE1W9djEFOj1yQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.4.5", + "compute-scroll-into-view": "^1.0.9", + "prop-types": "^15.7.2", + "react-is": "^16.9.0" + }, + "peerDependencies": { + "react": ">=0.14.9" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.766", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.766.tgz", + "integrity": "sha512-u2quJ862q9reRKh/je3GXis3w38+RoXH1J9N3XjtsS6NzmUAosNsyZgUVFZPN/ZlJ3v6T0rTyZR3q/J5c6Sy5w==", + "devOptional": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/emotion": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.27.tgz", + "integrity": "sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==", + "dev": true, + "dependencies": { + "babel-plugin-emotion": "^10.0.27", + "create-emotion": "^10.0.27" + } + }, + "node_modules/emotion-theming": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/emotion-theming/-/emotion-theming-10.0.27.tgz", + "integrity": "sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@emotion/weak-memoize": "0.2.5", + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@emotion/core": "^10.0.27", + "react": ">=16.3.0" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/enhanced-resolve/node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "peer": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/enzyme": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", + "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", + "dev": true, + "dependencies": { + "array.prototype.flat": "^1.2.3", + "cheerio": "^1.0.0-rc.3", + "enzyme-shallow-equal": "^1.0.1", + "function.prototype.name": "^1.1.2", + "has": "^1.0.3", + "html-element-map": "^1.2.0", + "is-boolean-object": "^1.0.1", + "is-callable": "^1.1.5", + "is-number-object": "^1.0.4", + "is-regex": "^1.0.5", + "is-string": "^1.0.5", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.7.0", + "object-is": "^1.0.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1", + "object.values": "^1.1.1", + "raf": "^3.4.1", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.2.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/enzyme-adapter-react-16": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz", + "integrity": "sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==", + "dev": true, + "dependencies": { + "enzyme-adapter-utils": "^1.14.0", + "enzyme-shallow-equal": "^1.0.4", + "has": "^1.0.3", + "object.assign": "^4.1.2", + "object.values": "^1.1.2", + "prop-types": "^15.7.2", + "react-is": "^16.13.1", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "peerDependencies": { + "enzyme": "^3.0.0", + "react": "^16.0.0-0", + "react-dom": "^16.0.0-0" + } + }, + "node_modules/enzyme-adapter-react-16/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/enzyme-adapter-utils": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz", + "integrity": "sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==", + "dev": true, + "dependencies": { + "airbnb-prop-types": "^2.16.0", + "function.prototype.name": "^1.1.3", + "has": "^1.0.3", + "object.assign": "^4.1.2", + "object.fromentries": "^2.0.3", + "prop-types": "^15.7.2", + "semver": "^5.7.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "peerDependencies": { + "react": "0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0" + } + }, + "node_modules/enzyme-adapter-utils/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/enzyme-matchers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz", + "integrity": "sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==", + "dev": true, + "dependencies": { + "circular-json-es6": "^2.0.1", + "deep-equal-ident": "^1.1.1" + }, + "peerDependencies": { + "enzyme": ">=3.4.0" + } + }, + "node_modules/enzyme-shallow-equal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", + "integrity": "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==", + "dev": true, + "dependencies": { + "has": "^1.0.3", + "object-is": "^1.1.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/enzyme-to-json": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.6.2.tgz", + "integrity": "sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg==", + "dev": true, + "dependencies": { + "@types/cheerio": "^0.22.22", + "lodash": "^4.17.21", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "enzyme": "^3.4.0" + } + }, + "node_modules/equivalent-key-map": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/equivalent-key-map/-/equivalent-key-map-0.2.2.tgz", + "integrity": "sha512-xvHeyCDbZzkpN4VHQj/n+j2lOwL0VWszG30X4cOrc9Y7Tuo2qCdZK/0AMod23Z5dCtNUbaju6p0rwOhHUk05ew==", + "dev": true + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dev": true, + "dependencies": { + "string-template": "~0.2.1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "dev": true, + "peer": true, + "dependencies": { + "stackframe": "^1.1.1" + } + }, + "node_modules/errorhandler": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", + "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", + "dev": true, + "peer": true, + "dependencies": { + "accepts": "~1.3.7", + "escape-html": "~1.0.3" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "dependencies": { + "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^2.5.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "26.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz", + "integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==", + "dev": true, + "dependencies": { + "comment-parser": "^0.7.4", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.1.0", + "lodash": "^4.17.15", + "regextras": "^0.7.1", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", + "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.0.2", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^3.1.0", + "language-tags": "^1.0.5" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/eslint-plugin-markdown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-1.0.2.tgz", + "integrity": "sha512-BfvXKsO0K+zvdarNc801jsE/NTLmig4oKhZ1U3aSUgTf2dB/US5+CrfGxMsCK2Ki1vS1R3HPok+uYpufFndhzw==", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "remark-parse": "^5.0.0", + "unified": "^6.1.2" + }, + "engines": { + "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz", + "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.4", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "node_modules/eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/exec-sh": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", + "dev": true + }, + "node_modules/execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": "^8.12.0 || >=9.7.0" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect-puppeteer": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-4.4.0.tgz", + "integrity": "sha512-6Ey4Xy2xvmuQu7z7YQtMsaMV0EHJRpVxIDOd5GRrm04/I3nkTKIutELfECsLp6le+b3SSa3cXhPiw6PgqzxYWA==", + "dev": true + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expect/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/expect/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" + }, + "node_modules/fast-average-color": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-4.3.0.tgz", + "integrity": "sha512-k8FXd6+JeXoItmdNqB3hMwFgArryjdYBLuzEM8fRY/oztd/051yhSHU6GUrMOfIQU9dDHyFDcIAkGrQKlYtpDA==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fast-memoize": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "dev": true, + "dependencies": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-babel-config/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-file-up": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz", + "integrity": "sha1-z2gJG8+fMApA2kEbN9pczlovvqA=", + "dev": true, + "dependencies": { + "fs-exists-sync": "^0.1.0", + "resolve-dir": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-parent-dir": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.1.tgz", + "integrity": "sha512-o4UcykWV/XN9wm+jMEtWLPlV8RXCZnMhQI6F6OdHeSez7iiJWePw8ijOlskJZMsaQoGR/b7dH6lO02HhaTN7+A==", + "dev": true + }, + "node_modules/find-pkg": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-0.1.2.tgz", + "integrity": "sha1-G9wiwG42NlUy4qJIBGhUuXiNpVc=", + "dev": true, + "dependencies": { + "find-file-up": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-process": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.4.tgz", + "integrity": "sha512-rRSuT1LE4b+BFK588D2V8/VG9liW0Ark1XJgroxZXI0LtwmQJOb490DvDYvbm+Hek9ETFzTutGfJ90gumITPhQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "debug": "^4.1.1" + }, + "bin": { + "find-process": "bin/find-process.js" + } + }, + "node_modules/find-process/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/find-process/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/find-process/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/find-process/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/find-process/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/find-process/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-process/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "dependencies": { + "glob": "~5.0.0" + }, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/findup-sync/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat/node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/flatted": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", + "dev": true + }, + "node_modules/flow-parser": { + "version": "0.121.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", + "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/framer-motion": { + "version": "4.1.17", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-4.1.17.tgz", + "integrity": "sha512-thx1wvKzblzbs0XaK2X0G1JuwIdARcoNOW7VVwjO8BUltzXPyONGAElLu6CiCScsOQRI7FIk/45YTFtJw5Yozw==", + "dev": true, + "dependencies": { + "framesync": "5.3.0", + "hey-listen": "^1.0.8", + "popmotion": "9.3.6", + "style-value-types": "4.1.4", + "tslib": "^2.1.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": ">=16.8 || ^17.0.0", + "react-dom": ">=16.8 || ^17.0.0" + } + }, + "node_modules/framesync": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz", + "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.4.tgz", + "integrity": "sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz", + "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "dependencies": { + "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "devOptional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getobject": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.1.tgz", + "integrity": "sha512-tj18lLe+917AACr6BdVoUuHnBPTVd9BEJp1vxnMZ58ztNvuxz9Ufa+wf3g37tlGITH35jggwZ2d9lcgHJJgXfQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/gettext-parser": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz", + "integrity": "sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA==", + "dev": true, + "dependencies": { + "encoding": "^0.1.12", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-cache": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/global-cache/-/global-cache-1.2.1.tgz", + "integrity": "sha512-EOeUaup5DgWKlCMhA9YFqNRIlZwoxt731jCh47WBV9fQqHgXhr3Fa55hfgIUqilIcPsfdNKN7LHjrNY+Km40KA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "is-symbol": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true, + "dependencies": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-modules/node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "node_modules/globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "dev": true, + "dependencies": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "dev": true, + "dependencies": { + "delegate": "^3.1.2" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "node_modules/gradient-parser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/gradient-parser/-/gradient-parser-0.1.5.tgz", + "integrity": "sha1-DH4heVWeXOfY1x9EI6+TcQCyJIw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "node_modules/grunt": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.4.1.tgz", + "integrity": "sha512-ZXIYXTsAVrA7sM+jZxjQdrBOAg7DyMUplOMhTaspMRExei+fD0BTwdWXnn0W5SXqhb/Q/nlkzXclSi3IH55PIA==", + "dev": true, + "dependencies": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.2", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "bin": { + "grunt": "bin/grunt" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "dependencies": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "bin": { + "grunt": "bin/grunt" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-cli/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/grunt-exec": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-3.0.0.tgz", + "integrity": "sha512-cgAlreXf3muSYS5LzW0Cc4xHK03BjFOYk0MqCQ/MZ3k1Xz2GU7D+IAJg4UKicxpO+XdONJdx/NJ6kpy2wI+uHg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + }, + "peerDependencies": { + "grunt": ">=0.4" + } + }, + "node_modules/grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "dependencies": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "dependencies": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-legacy-log-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/grunt-legacy-log-utils/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/grunt-legacy-log-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/grunt-legacy-log-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/grunt-legacy-log-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-legacy-log-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "dependencies": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/grunt-legacy-util/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/grunt-text-replace": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/grunt-text-replace/-/grunt-text-replace-0.4.0.tgz", + "integrity": "sha1-252c5Z4v5J2id+nbwZXD4Rz7FsI=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/grunt/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/grunt/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hermes-engine": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.7.2.tgz", + "integrity": "sha512-E2DkRaO97gwL98LPhgfkMqhHiNsrAjIfEk3wWYn2Y31xdkdWn0572H7RnVcGujMJVqZNJvtknxlpsUb8Wzc3KA==", + "dev": true, + "peer": true + }, + "node_modules/hermes-profile-transformer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz", + "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==", + "dev": true, + "peer": true, + "dependencies": { + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hermes-profile-transformer/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "dev": true + }, + "node_modules/highlight-words-core": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words-core/-/highlight-words-core-1.2.2.tgz", + "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg==", + "dev": true + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/hpq": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/hpq/-/hpq-1.3.0.tgz", + "integrity": "sha512-fvYTvdCFOWQupGxqkahrkA+ERBuMdzkxwtUdKrxR6rmMd4Pfl+iZ1QiQYoaZ0B/v0y59MOMnz3XFUWbT50/NWA==", + "dev": true + }, + "node_modules/html-dom-parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-0.3.0.tgz", + "integrity": "sha512-WDEYpO5gHGKuJbf0rwndGq7yUHJ4xboNj9l9mRGw5RsKFc3jfRozCsGAMu69zXxt4Ol8UkbqubKxu8ys0BLKtA==", + "dependencies": { + "@types/domhandler": "2.4.1", + "domhandler": "2.4.2", + "htmlparser2": "3.10.1" + } + }, + "node_modules/html-dom-parser/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/html-dom-parser/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/html-dom-parser/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/html-dom-parser/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/html-dom-parser/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/html-dom-parser/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/html-dom-parser/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "node_modules/html-dom-parser/node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/html-dom-parser/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/html-element-map": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz", + "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==", + "dev": true, + "dependencies": { + "array.prototype.filter": "^1.0.0", + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-react-parser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-0.13.0.tgz", + "integrity": "sha512-hU94hE2p9xhMM61EOoiY3Kr+DfzH/uY7hGeVXQpGFRjgbYRUeyuSKORDNMIaY8IAcuHQ6Ov9pJ3x94Wvso/OmQ==", + "dependencies": { + "@types/htmlparser2": "3.10.1", + "html-dom-parser": "0.3.0", + "react-property": "1.0.1", + "style-to-object": "0.3.0" + }, + "peerDependencies": { + "react": "^0.14 || ^15 || ^16" + } + }, + "node_modules/html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-emit-webpack-plugin": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/ignore-emit-webpack-plugin/-/ignore-emit-webpack-plugin-2.0.6.tgz", + "integrity": "sha512-/zC18RWCC2wz4ZwnS4UoujGWzvSKy28DLjtE+jrGBOXej6YdmityhBDzE8E0NlktEqi4tgdNbydX8B6G4haHSQ==", + "dev": true + }, + "node_modules/image-size": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", + "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", + "dev": true, + "peer": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/immer": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.5.tgz", + "integrity": "sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutability-helper": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-3.1.1.tgz", + "integrity": "sha512-Q0QaXjPjwIju/28TsugCHNEASwoCcJSyJV3uO1sOIQGI0jKgm9f41Lvz0DZj3n46cNCyAZTsEYoY4C2bVRUzyQ==" + }, + "node_modules/import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "dependencies": { + "import-from": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", + "dev": true, + "bin": { + "in-install": "in-install.js", + "in-publish": "in-publish.js", + "not-in-install": "not-in-install.js", + "not-in-publish": "not-in-publish.js" + } + }, + "node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/install": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/install/-/install-0.10.4.tgz", + "integrity": "sha512-+IRyOastuPmLVx9zlVXJoKErSqz1Ma5at9A7S8yfsj3W+Kg95faPoh3bPDtMrZ/grz4PRmXzrswmlzfLlYyLOw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true, + "peer": true + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/irregular-plurals": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", + "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "optional": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dependencies": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-touch-device": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-touch-device/-/is-touch-device-1.0.1.tgz", + "integrity": "sha512-LAYzo9kMT1b2p19L/1ATGt2XcSilnzNlyvq6c0pbPRVisLbAPpLqr53tIJS00kvrTkj0HtR8U7+u8X0yR8lPSw==", + "dev": true + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz", + "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", + "dev": true, + "dependencies": { + "@jest/core": "^25.5.4", + "import-local": "^3.0.2", + "jest-cli": "^25.5.4" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-changed-files": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-cli": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", + "dev": true, + "dependencies": { + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "prompts": "^2.0.1", + "realpath-native": "^2.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-dev-server": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-4.4.0.tgz", + "integrity": "sha512-STEHJ3iPSC8HbrQ3TME0ozGX2KT28lbT4XopPxUm2WimsX3fcB3YOptRh12YphQisMhfqNSNTZUmWyT3HEXS2A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "cwd": "^0.10.0", + "find-process": "^1.4.3", + "prompts": "^2.3.0", + "spawnd": "^4.4.0", + "tree-kill": "^1.2.2", + "wait-on": "^3.3.0" + } + }, + "node_modules/jest-dev-server/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-dev-server/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-dev-server/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-dev-server/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-dev-server/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-dev-server/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "dependencies": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "dependencies": { + "xmlchars": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "dependencies": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "dependencies": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-environment-puppeteer": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-puppeteer/-/jest-environment-puppeteer-4.4.0.tgz", + "integrity": "sha512-iV8S8+6qkdTM6OBR/M9gKywEk8GDSOe05hspCs5D8qKSwtmlUfdtHfB4cakdc68lC6YfK3AUsLirpfgodCHjzQ==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "cwd": "^0.10.0", + "jest-dev-server": "^4.4.0", + "merge-deep": "^3.0.2" + } + }, + "node_modules/jest-environment-puppeteer/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-environment-puppeteer/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-puppeteer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-environment-puppeteer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-environment-puppeteer/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-puppeteer/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 8.3" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/jest-haste-map/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-haste-map/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "dev": true, + "dependencies": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-puppeteer": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/jest-puppeteer/-/jest-puppeteer-4.4.0.tgz", + "integrity": "sha512-ZaiCTlPZ07B9HW0erAWNX6cyzBqbXMM7d2ugai4epBDKpKvRDpItlRQC6XjERoJELKZsPziFGS0OhhUvTvQAXA==", + "dev": true, + "dependencies": { + "expect-puppeteer": "^4.4.0", + "jest-environment-puppeteer": "^4.4.0" + }, + "peerDependencies": { + "puppeteer": ">= 1.5.0 < 3" + } + }, + "node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-snapshot": "^25.5.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", + "dev": true, + "dependencies": { + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "string-length": "^3.1.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jetifier": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", + "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==", + "dev": true, + "peer": true, + "bin": { + "jetifier": "bin/jetify", + "jetifier-standalone": "bin/jetifier-standalone", + "jetify": "bin/jetify" + } + }, + "node_modules/joi": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.0.tgz", + "integrity": "sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==", + "dev": true, + "peer": true, + "dependencies": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/joi/node_modules/@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "dev": true, + "peer": true + }, + "node_modules/joi/node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, + "peer": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", + "dev": true + }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsc-android": { + "version": "245459.0.0", + "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-245459.0.0.tgz", + "integrity": "sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==", + "dev": true, + "peer": true + }, + "node_modules/jscodeshift": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.11.0.tgz", + "integrity": "sha512-SdRK2C7jjs4k/kT2mwtO07KJN9RnjxtKn03d9JVj6c3j9WwaLcFYsICYDnLAzY0hp+wG2nxl+Cm2jWLiNVYb8g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.1.6", + "@babel/parser": "^7.1.6", + "@babel/plugin-proposal-class-properties": "^7.1.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.1.0", + "@babel/plugin-proposal-optional-chaining": "^7.1.0", + "@babel/plugin-transform-modules-commonjs": "^7.1.0", + "@babel/preset-flow": "^7.0.0", + "@babel/preset-typescript": "^7.1.0", + "@babel/register": "^7.0.0", + "babel-core": "^7.0.0-bridge.0", + "colors": "^1.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^3.1.10", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.20.3", + "temp": "^0.8.1", + "write-file-atomic": "^2.3.0" + }, + "bin": { + "jscodeshift": "bin/jscodeshift.js" + }, + "peerDependencies": { + "@babel/preset-env": "^7.1.6" + } + }, + "node_modules/jscodeshift/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "peer": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "peer": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "peer": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "peer": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "peer": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "peer": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "peer": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jscodeshift/node_modules/write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/jsdoctypeparser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", + "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "dev": true, + "bin": { + "jsdoctypeparser": "bin/jsdoctypeparser" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsdom": { + "version": "16.6.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", + "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.5", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom-global": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsdom-global/-/jsdom-global-3.0.2.tgz", + "integrity": "sha1-a9KZwTsMRiay2iwDk81DhdYGrLk=", + "dev": true, + "peerDependencies": { + "jsdom": ">=10.0.0" + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "devOptional": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "dev": true, + "dependencies": { + "string-convert": "^0.2.0" + } + }, + "node_modules/json2php": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/json2php/-/json2php-0.0.4.tgz", + "integrity": "sha1-a9haHdpqXdfpECK7JEA8wbfC7jQ=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "devOptional": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", + "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz", + "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==", + "dev": true + }, + "node_modules/language-subtag-registry": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", + "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "dependencies": { + "language-subtag-registry": "~0.3.2" + } + }, + "node_modules/lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/liftup/node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/liftup/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftup/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftup/node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/line-height": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz", + "integrity": "sha1-SxIF7d4YKHKl76PI9iCzGHqcVMk=", + "dev": true, + "dependencies": { + "computed-style": "~0.1.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/livereload-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", + "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", + "dev": true + }, + "node_modules/load-grunt-tasks": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz", + "integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=", + "dev": true, + "dependencies": { + "arrify": "^1.0.0", + "multimatch": "^2.0.0", + "pkg-up": "^1.0.0", + "resolve-pkg": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "grunt": ">=0.4.0" + } + }, + "node_modules/load-grunt-tasks/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-grunt-tasks/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-grunt-tasks/node_modules/pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash._baseisequal": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz", + "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=", + "dev": true, + "dependencies": { + "lodash.isarray": "^3.0.0", + "lodash.istypedarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "node_modules/lodash.differencewith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.differencewith/-/lodash.differencewith-4.5.0.tgz", + "integrity": "sha1-uvr7yRi1UVTheRdqALsK76rIVLc=", + "dev": true + }, + "node_modules/lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "node_modules/lodash.istypedarray": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", + "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=", + "dev": true + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "dev": true, + "peer": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/logkitty": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", + "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-fragments": "^0.2.1", + "dayjs": "^1.8.15", + "yargs": "^15.1.0" + }, + "bin": { + "logkitty": "bin/logkitty.js" + } + }, + "node_modules/lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "dependencies": { + "tmpl": "1.0.x" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-values/-/map-values-1.0.1.tgz", + "integrity": "sha1-douOecAJvytk/ugG4ip7HEGQyZA=", + "dev": true + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, + "node_modules/markdownlint": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.18.0.tgz", + "integrity": "sha512-nQAfK9Pbq0ZRoMC/abNGterEnV3kL8MZmi0WHhw8WJKoIbsm3cXGufGsxzCRvjW15cxe74KWcxRSKqwplS26Bw==", + "dev": true, + "dependencies": { + "markdown-it": "10.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.21.0.tgz", + "integrity": "sha512-gvnczz3W3Wgex851/cIQ/2y8GNhY+EVK8Ael8kRd8hoSQ0ps9xjhtwPwMyJPoiYbAoPxG6vSBFISiysaAbCEZg==", + "dev": true, + "dependencies": { + "commander": "~2.9.0", + "deep-extend": "~0.5.1", + "get-stdin": "~5.0.1", + "glob": "~7.1.2", + "ignore": "~5.1.4", + "js-yaml": "~3.13.1", + "jsonc-parser": "~2.2.0", + "lodash.differencewith": "~4.5.0", + "lodash.flatten": "~4.4.0", + "markdownlint": "~0.18.0", + "markdownlint-rule-helpers": "~0.6.0", + "minimatch": "~3.0.4", + "rc": "~1.2.7" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/markdownlint-cli/node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/markdownlint-cli/node_modules/get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/markdownlint-cli/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/markdownlint-cli/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/markdownlint-rule-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.6.0.tgz", + "integrity": "sha512-LiZVAbg9/cqkBHtLNNqHV3xuy4Y2L/KuGU6+ZXqCT9NnCdEkIoxeI5/96t+ExquBY0iHy2CVWxPH16nG1RKQVQ==", + "dev": true + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", + "integrity": "sha512-K4FcPETOMTwe7KL2LK0orMhpOmWD2wRGwWWpbZy0fyArwsyIKR8YJVz8+efBAh3BO4zPqlSICu4vsLTRRqtFAg==", + "dev": true + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.3.tgz", + "integrity": "sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "clone-deep": "^0.2.4", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep/node_modules/clone-deep": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", + "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", + "dev": true, + "dependencies": { + "for-own": "^0.1.3", + "is-plain-object": "^2.0.1", + "kind-of": "^3.0.2", + "lazy-cache": "^1.0.3", + "shallow-clone": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep/node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep/node_modules/shallow-clone": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", + "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.1", + "kind-of": "^2.0.1", + "lazy-cache": "^0.2.3", + "mixin-object": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep/node_modules/shallow-clone/node_modules/kind-of": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", + "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", + "dev": true, + "dependencies": { + "is-buffer": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-deep/node_modules/shallow-clone/node_modules/lazy-cache": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", + "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/metro": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.64.0.tgz", + "integrity": "sha512-G2OC08Rzfs0kqnSEuKo2yZxR+/eNUpA93Ru45c60uN0Dw3HPrDi+ZBipgFftC6iLE0l+6hu8roFFIofotWxybw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "absolute-path": "^0.0.0", + "accepts": "^1.3.7", + "async": "^2.4.0", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "error-stack-parser": "^2.0.6", + "fs-extra": "^1.0.0", + "graceful-fs": "^4.1.3", + "image-size": "^0.6.0", + "invariant": "^2.2.4", + "jest-haste-map": "^26.5.2", + "jest-worker": "^26.0.0", + "lodash.throttle": "^4.1.1", + "metro-babel-register": "0.64.0", + "metro-babel-transformer": "0.64.0", + "metro-cache": "0.64.0", + "metro-cache-key": "0.64.0", + "metro-config": "0.64.0", + "metro-core": "0.64.0", + "metro-hermes-compiler": "0.64.0", + "metro-inspector-proxy": "0.64.0", + "metro-minify-uglify": "0.64.0", + "metro-react-native-babel-preset": "0.64.0", + "metro-resolver": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "metro-symbolicate": "0.64.0", + "metro-transform-plugins": "0.64.0", + "metro-transform-worker": "0.64.0", + "mime-types": "^2.1.27", + "mkdirp": "^0.5.1", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.1", + "rimraf": "^2.5.4", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "strip-ansi": "^6.0.0", + "temp": "0.8.3", + "throat": "^5.0.0", + "ws": "^1.1.5", + "yargs": "^15.3.1" + }, + "bin": { + "metro": "src/cli.js" + } + }, + "node_modules/metro-babel-register": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.64.0.tgz", + "integrity": "sha512-Kf6YvE3kIRumGnjK0Q9LqGDIdnsX9eFGtNBmBuCVDuB9wGGA/5CgX8We8W7Y44dz1RGTcHJRhfw5iGg+pwC3aQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/register": "^7.0.0", + "escape-string-regexp": "^1.0.5" + } + }, + "node_modules/metro-babel-transformer": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.64.0.tgz", + "integrity": "sha512-itZaxKTgmKGEZWxNzbSZBc22NngrMZzoUNuU92aHSTGkYi2WH4XlvzEHsstmIKHMsRVKl75cA+mNmgk4gBFJKw==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.0.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1" + } + }, + "node_modules/metro-cache": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.64.0.tgz", + "integrity": "sha512-QvGfxe/1QQYM9XOlR8W1xqE9eHDw/AgJIgYGn/TxZxBu9Zga+Rgs1omeSZju45D8w5VWgMr83ma5kACgzvOecg==", + "dev": true, + "peer": true, + "dependencies": { + "metro-core": "0.64.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4" + } + }, + "node_modules/metro-cache-key": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.64.0.tgz", + "integrity": "sha512-O9B65G8L/fopck45ZhdRosyVZdMtUQuX5mBWEC1NRj02iWBIUPLmYMjrunqIe8vHipCMp3DtTCm/65IlBmO8jg==", + "dev": true, + "peer": true + }, + "node_modules/metro-cache/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/metro-config": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.64.0.tgz", + "integrity": "sha512-QhM4asnX5KhlRWaugwVGNNXhX0Z85u5nK0UQ/A90bBb4xWyXqUe20e788VtdA75rkQiiI6wXTCIHWT0afbnjwQ==", + "dev": true, + "peer": true, + "dependencies": { + "cosmiconfig": "^5.0.5", + "jest-validate": "^26.5.2", + "metro": "0.64.0", + "metro-cache": "0.64.0", + "metro-core": "0.64.0", + "metro-runtime": "0.64.0" + } + }, + "node_modules/metro-config/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-config/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/metro-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/metro-config/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/metro-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/metro-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/metro-config/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/metro-config/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-config/node_modules/jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-config/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/metro-config/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "node_modules/metro-config/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/metro-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/metro-core": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.64.0.tgz", + "integrity": "sha512-v8ZQ5j72EaUwamQ8pLfHlOHTyp7SbdazvHPzFGDpHnwIQqIT0Bw3Syg8R4regTlVG3ngpeSEAi005UITljmMcQ==", + "dev": true, + "peer": true, + "dependencies": { + "jest-haste-map": "^26.5.2", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.64.0" + } + }, + "node_modules/metro-core/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-core/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/metro-core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/metro-core/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "peer": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/metro-core/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/metro-core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/metro-core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/metro-core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/metro-core/node_modules/jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/metro-core/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-core/node_modules/jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-core/node_modules/jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro-core/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/metro-core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/metro-hermes-compiler": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.64.0.tgz", + "integrity": "sha512-CLAjVDWGAoGhbi2ZyPHnH5YDdfrDIx6+tzFWfHGIMTZkYBXsYta9IfYXBV8lFb6BIbrXLjlXZAOoosknetMPOA==", + "dev": true, + "peer": true + }, + "node_modules/metro-inspector-proxy": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.64.0.tgz", + "integrity": "sha512-KywbH3GNSz9Iqw4UH3smgaV2dBHHYMISeN7ORntDL/G+xfgPc6vt13d+zFb907YpUcXj5N0vdoiAHI5V/0y8IA==", + "dev": true, + "peer": true, + "dependencies": { + "connect": "^3.6.5", + "debug": "^2.2.0", + "ws": "^1.1.5", + "yargs": "^15.3.1" + }, + "bin": { + "metro-inspector-proxy": "src/cli.js" + } + }, + "node_modules/metro-inspector-proxy/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/metro-inspector-proxy/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, + "node_modules/metro-inspector-proxy/node_modules/ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "peer": true, + "dependencies": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "node_modules/metro-minify-uglify": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.64.0.tgz", + "integrity": "sha512-DRwRstqXR5qfte9Nuwoov5dRXxL7fJeVlO5fGyOajWeO3+AgPjvjXh/UcLJqftkMWTPGUFuzAD5/7JC5v5FLWw==", + "dev": true, + "peer": true, + "dependencies": { + "uglify-es": "^3.1.9" + } + }, + "node_modules/metro-react-native-babel-preset": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.64.0.tgz", + "integrity": "sha512-HcZ0RWQRuJfpPiaHyFQJzcym+/dDIVUPwUAXWoub/C4GkGu+mPjp8vqK6g0FxokCnnI2TK0gZTza2IDfiNNscQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/metro-react-native-babel-transformer": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.64.0.tgz", + "integrity": "sha512-K1sHO3ODBFCr7uEiCQ4RvVr+cQg0EHQF8ChVPnecGh/WDD8udrTq9ECwB0dRfMjAvlsHtRUlJm6ZSI8UPgum2w==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.0.0", + "babel-preset-fbjs": "^3.3.0", + "metro-babel-transformer": "0.64.0", + "metro-react-native-babel-preset": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/metro-resolver": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.64.0.tgz", + "integrity": "sha512-cJ26Id8Zf+HmS/1vFwu71K3u7ep/+HeXXAJIeVDYf+niE7AWB9FijyMtAlQgbD8elWqv1leJCnQ/xHRFBfGKYA==", + "dev": true, + "peer": true, + "dependencies": { + "absolute-path": "^0.0.0" + } + }, + "node_modules/metro-runtime": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.64.0.tgz", + "integrity": "sha512-m7XbWOaIOeFX7YcxUhmnOi6Pg8EaeL89xyZ+quZyZVF1aNoTr4w8FfbKxvijpjsytKHIZtd+43m2Wt5JrqyQmQ==", + "dev": true, + "peer": true + }, + "node_modules/metro-source-map": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.64.0.tgz", + "integrity": "sha512-OCG2rtcp5cLEGYvAbfkl6mEc0J2FPRP4/UCEly+juBk7hawS9bCBMBfhJm/HIsvY1frk6nT2Vsl1O8YBbwyx2g==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "invariant": "^2.2.4", + "metro-symbolicate": "0.64.0", + "nullthrows": "^1.1.1", + "ob1": "0.64.0", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + } + }, + "node_modules/metro-symbolicate": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.64.0.tgz", + "integrity": "sha512-qIi+YRrDWnLVmydj6gwidYLPaBsakZRibGWSspuXgHAxOI3UuLwlo4dpQ73Et0gyHjI7ZvRMRY8JPiOntf9AQQ==", + "dev": true, + "peer": true, + "dependencies": { + "invariant": "^2.2.4", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "through2": "^2.0.1", + "vlq": "^1.0.0" + }, + "bin": { + "metro-symbolicate": "src/index.js" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/metro-transform-plugins": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.64.0.tgz", + "integrity": "sha512-iTIRBD/wBI98plfxj8jAoNUUXfXLNlyvcjPtshhpGvdwu9pzQilGfnDnOaaK+vbITcOk9w5oQectXyJwAqTr1A==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "nullthrows": "^1.1.1" + } + }, + "node_modules/metro-transform-worker": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.64.0.tgz", + "integrity": "sha512-wegRtK8GyLF6IPZRBJp+zsORgA4iX0h1DRpknyAMDCtSbJ4VU2xV/AojteOgAsDvY3ucAGsvfuZLNDJHUdUNHQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/parser": "^7.0.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.3.0", + "metro": "0.64.0", + "metro-babel-transformer": "0.64.0", + "metro-cache": "0.64.0", + "metro-cache-key": "0.64.0", + "metro-hermes-compiler": "0.64.0", + "metro-source-map": "0.64.0", + "metro-transform-plugins": "0.64.0", + "nullthrows": "^1.1.1" + } + }, + "node_modules/metro/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro/node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/metro/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/metro/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "peer": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/metro/node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "peer": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/metro/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/metro/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/metro/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/metro/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/metro/node_modules/fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "node_modules/metro/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/metro/node_modules/jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/metro/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro/node_modules/jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro/node_modules/jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "peer": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/metro/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/metro/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/metro/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/metro/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, + "node_modules/metro/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/metro/node_modules/temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "dev": true, + "engines": [ + "node >=0.8.0" + ], + "peer": true, + "dependencies": { + "os-tmpdir": "^1.0.0", + "rimraf": "~2.2.6" + } + }, + "node_modules/metro/node_modules/temp/node_modules/rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true, + "peer": true, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/metro/node_modules/ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "peer": true, + "dependencies": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/micromatch/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/micromatch/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/micromatch/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dev": true, + "dependencies": { + "mime-db": "1.48.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "devOptional": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mitt": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", + "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==", + "dev": true + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "dev": true, + "dependencies": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-object/node_modules/for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "dev": true, + "dependencies": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/mocha/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/mocha/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/mocha/node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "dev": true, + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moo": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", + "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==", + "dev": true + }, + "node_modules/mousetrap": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz", + "integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==", + "dev": true + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/move-concurrently/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true + }, + "node_modules/multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "dependencies": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nearley": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", + "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "bin": { + "nearley-railroad": "bin/nearley-railroad.js", + "nearley-test": "bin/nearley-test.js", + "nearley-unparse": "bin/nearley-unparse.js", + "nearleyc": "bin/nearleyc.js" + }, + "funding": { + "type": "individual", + "url": "https://nearley.js.org/#give-to-nearley" + } + }, + "node_modules/nearley/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "dev": true, + "peer": true, + "dependencies": { + "minimatch": "^3.0.2" + }, + "engines": { + "node": ">= 0.10.5" + } + }, + "node_modules/node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node_modules/node-environment-flags/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true, + "peer": true, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "dependencies": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "dev": true, + "optional": true, + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + } + }, + "node_modules/node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "devOptional": true + }, + "node_modules/node-sass": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "bin": { + "node-sass": "bin/node-sass" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/node-sass/node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/node-sass/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/node-stream-zip": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.13.6.tgz", + "integrity": "sha512-c7tRSVkLNOHvasWgmZ2d86cDgTWEygnkuuHNOY9c0mR3yLZtQTTrGvMaJ/fPs6+LOJn3240y30l5sjLaXFtcvw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/antelle" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-wheel": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz", + "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=", + "dev": true + }, + "node_modules/npm": { + "version": "6.14.13", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.13.tgz", + "integrity": "sha512-SRl4jJi0EBHY2xKuu98FLRMo3VhYQSA6otyLnjSEiHoSG/9shXCFNJy9tivpUJvtkN9s6VDdItHa5Rn+fNBzag==", + "bundleDependencies": [ + "abbrev", + "ansicolors", + "ansistyles", + "aproba", + "archy", + "bin-links", + "bluebird", + "byte-size", + "cacache", + "call-limit", + "chownr", + "ci-info", + "cli-columns", + "cli-table3", + "cmd-shim", + "columnify", + "config-chain", + "debuglog", + "detect-indent", + "detect-newline", + "dezalgo", + "editor", + "figgy-pudding", + "find-npm-prefix", + "fs-vacuum", + "fs-write-stream-atomic", + "gentle-fs", + "glob", + "graceful-fs", + "has-unicode", + "hosted-git-info", + "iferr", + "imurmurhash", + "infer-owner", + "inflight", + "inherits", + "ini", + "init-package-json", + "is-cidr", + "json-parse-better-errors", + "JSONStream", + "lazy-property", + "libcipm", + "libnpm", + "libnpmaccess", + "libnpmhook", + "libnpmorg", + "libnpmsearch", + "libnpmteam", + "libnpx", + "lock-verify", + "lockfile", + "lodash._baseindexof", + "lodash._baseuniq", + "lodash._bindcallback", + "lodash._cacheindexof", + "lodash._createcache", + "lodash._getnative", + "lodash.clonedeep", + "lodash.restparam", + "lodash.union", + "lodash.uniq", + "lodash.without", + "lru-cache", + "meant", + "mississippi", + "mkdirp", + "move-concurrently", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-cache-filename", + "npm-install-checks", + "npm-lifecycle", + "npm-package-arg", + "npm-packlist", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "once", + "opener", + "osenv", + "pacote", + "path-is-inside", + "promise-inflight", + "qrcode-terminal", + "query-string", + "qw", + "read-cmd-shim", + "read-installed", + "read-package-json", + "read-package-tree", + "read", + "readable-stream", + "readdir-scoped-modules", + "request", + "retry", + "rimraf", + "safe-buffer", + "semver", + "sha", + "slide", + "sorted-object", + "sorted-union-stream", + "ssri", + "stringify-package", + "tar", + "text-table", + "tiny-relative-date", + "uid-number", + "umask", + "unique-filename", + "unpipe", + "update-notifier", + "uuid", + "validate-npm-package-license", + "validate-npm-package-name", + "which", + "worker-farm", + "write-file-atomic" + ], + "dev": true, + "dependencies": { + "abbrev": "~1.1.1", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "aproba": "^2.0.0", + "archy": "~1.0.0", + "bin-links": "^1.1.8", + "bluebird": "^3.5.5", + "byte-size": "^5.0.1", + "cacache": "^12.0.3", + "call-limit": "^1.1.1", + "chownr": "^1.1.4", + "ci-info": "^2.0.0", + "cli-columns": "^3.1.2", + "cli-table3": "^0.5.1", + "cmd-shim": "^3.0.3", + "columnify": "~1.5.4", + "config-chain": "^1.1.12", + "debuglog": "*", + "detect-indent": "~5.0.0", + "detect-newline": "^2.1.0", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "fs-vacuum": "~1.2.10", + "fs-write-stream-atomic": "~1.0.10", + "gentle-fs": "^2.3.1", + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "has-unicode": "~2.0.1", + "hosted-git-info": "^2.8.9", + "iferr": "^1.0.2", + "imurmurhash": "*", + "infer-owner": "^1.0.4", + "inflight": "~1.0.6", + "inherits": "^2.0.4", + "ini": "^1.3.8", + "init-package-json": "^1.10.3", + "is-cidr": "^3.0.0", + "json-parse-better-errors": "^1.0.2", + "JSONStream": "^1.3.5", + "lazy-property": "~1.0.0", + "libcipm": "^4.0.8", + "libnpm": "^3.0.1", + "libnpmaccess": "^3.0.2", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "libnpx": "^10.2.4", + "lock-verify": "^2.1.0", + "lockfile": "^1.0.4", + "lodash._baseindexof": "*", + "lodash._baseuniq": "~4.6.0", + "lodash._bindcallback": "*", + "lodash._cacheindexof": "*", + "lodash._createcache": "*", + "lodash._getnative": "*", + "lodash.clonedeep": "~4.5.0", + "lodash.restparam": "*", + "lodash.union": "~4.6.0", + "lodash.uniq": "~4.5.0", + "lodash.without": "~4.4.0", + "lru-cache": "^5.1.1", + "meant": "^1.0.2", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.5", + "move-concurrently": "^1.0.1", + "node-gyp": "^5.1.0", + "nopt": "^4.0.3", + "normalize-package-data": "^2.5.0", + "npm-audit-report": "^1.3.3", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "^3.0.2", + "npm-lifecycle": "^3.1.5", + "npm-package-arg": "^6.1.1", + "npm-packlist": "^1.4.8", + "npm-pick-manifest": "^3.0.2", + "npm-profile": "^4.0.4", + "npm-registry-fetch": "^4.0.7", + "npm-user-validate": "^1.0.1", + "npmlog": "~4.1.2", + "once": "~1.4.0", + "opener": "^1.5.2", + "osenv": "^0.1.5", + "pacote": "^9.5.12", + "path-is-inside": "~1.0.2", + "promise-inflight": "~1.0.1", + "qrcode-terminal": "^0.12.0", + "query-string": "^6.8.2", + "qw": "~1.0.1", + "read": "~1.0.7", + "read-cmd-shim": "^1.0.5", + "read-installed": "~4.0.3", + "read-package-json": "^2.1.1", + "read-package-tree": "^5.3.1", + "readable-stream": "^3.6.0", + "readdir-scoped-modules": "^1.1.0", + "request": "^2.88.0", + "retry": "^0.12.0", + "rimraf": "^2.7.1", + "safe-buffer": "^5.1.2", + "semver": "^5.7.1", + "sha": "^3.0.0", + "slide": "~1.1.6", + "sorted-object": "~2.0.1", + "sorted-union-stream": "~2.1.3", + "ssri": "^6.0.2", + "stringify-package": "^1.0.1", + "tar": "^4.4.13", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "unique-filename": "^1.1.1", + "unpipe": "~1.0.0", + "update-notifier": "^2.5.0", + "uuid": "^3.3.3", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "~3.0.0", + "which": "^1.3.1", + "worker-farm": "^1.7.0", + "write-file-atomic": "^2.4.3" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "6 >=6.2.0 || 8 || >=9.3.0" + } + }, + "node_modules/npm-package-json-lint": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-5.1.0.tgz", + "integrity": "sha512-gPGpoFTbt0H4uPlubAKqHORg4+GObXqeYJh5ovkkSv76ua+t29vzRP4Qhm+9N/Q59Z3LT0tCmpoDlbTcNB7Jcg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.2", + "ajv-errors": "^1.0.1", + "chalk": "^4.0.0", + "cosmiconfig": "^6.0.0", + "debug": "^4.1.1", + "globby": "^11.0.0", + "ignore": "^5.1.4", + "is-plain-obj": "^2.1.0", + "jsonc-parser": "^2.2.1", + "log-symbols": "^4.0.0", + "meow": "^6.1.0", + "plur": "^4.0.0", + "semver": "^7.3.2", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.0" + }, + "bin": { + "npmPkgJsonLint": "src/cli.js" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/npm-package-json-lint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm-package-json-lint/node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm-package-json-lint/node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm-package-json-lint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm-package-json-lint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/npm-package-json-lint/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-package-json-lint/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-json-lint/node_modules/map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/meow": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", + "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-json-lint/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-package-json-lint/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-package-json-lint/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/agent-base": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/npm/node_modules/agentkeepalive": { + "version": "3.5.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/npm/node_modules/ansi-align": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^2.0.0" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/ansicolors": { + "version": "0.3.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/ansistyles": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/are-we-there-yet": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/npm/node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/asap": { + "version": "2.0.6", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/asn1": { + "version": "0.2.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/npm/node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/aws4": { + "version": "1.8.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/npm/node_modules/bin-links": { + "version": "1.1.8", + "dev": true, + "inBundle": true, + "license": "Artistic-2.0", + "dependencies": { + "bluebird": "^3.5.3", + "cmd-shim": "^3.0.0", + "gentle-fs": "^2.3.0", + "graceful-fs": "^4.1.15", + "npm-normalize-package-bin": "^1.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "node_modules/npm/node_modules/bluebird": { + "version": "3.5.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/boxen": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm/node_modules/buffer-from": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/builtins": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/byline": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/byte-size": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "12.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/npm/node_modules/call-limit": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/camelcase": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/capture-stack-trace": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/chalk": { + "version": "2.4.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "2.0.10", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/cli-boxes": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/cli-table3": { + "version": "0.5.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/npm/node_modules/cliui": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/npm/node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/clone": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "node_modules/npm/node_modules/code-point-at": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "1.9.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.1.1" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/colors": { + "version": "1.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/npm/node_modules/columnify": { + "version": "1.5.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "node_modules/npm/node_modules/combined-stream": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/npm/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/concat-stream": { + "version": "1.6.2", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/npm/node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/config-chain": { + "version": "1.1.12", + "dev": true, + "inBundle": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/npm/node_modules/configstore": { + "version": "3.1.5", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^4.2.1", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/copy-concurrently": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/npm/node_modules/copy-concurrently/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/copy-concurrently/node_modules/iferr": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/create-error-class": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "capture-stack-trace": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/lru-cache": { + "version": "4.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/yallist": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/crypto-random-string": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/cyclist": { + "version": "0.2.2", + "dev": true, + "inBundle": true + }, + "node_modules/npm/node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/debuglog": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/decode-uri-component": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/npm/node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/npm/node_modules/defaults": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/npm/node_modules/define-properties": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/npm/node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/detect-indent": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/detect-newline": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/dezalgo": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/dot-prop": { + "version": "4.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/dotenv": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.6.0" + } + }, + "node_modules/npm/node_modules/duplexer3": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/duplexify": { + "version": "3.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/npm/node_modules/duplexify/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/duplexify/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/npm/node_modules/editor": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "~0.4.13" + } + }, + "node_modules/npm/node_modules/end-of-stream": { + "version": "1.4.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/errno": { + "version": "0.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/npm/node_modules/es-abstract": { + "version": "1.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/es-to-primitive": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/es6-promise": { + "version": "4.2.8", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/es6-promisify": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/npm/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm/node_modules/execa": { + "version": "0.7.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/execa/node_modules/get-stream": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/extend": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/fast-json-stable-stringify": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/figgy-pudding": { + "version": "3.5.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/find-npm-prefix": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/flush-write-stream": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "node_modules/npm/node_modules/flush-write-stream/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/flush-write-stream/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/form-data": { + "version": "2.3.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/npm/node_modules/from2": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/npm/node_modules/from2/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/from2/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "1.2.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/npm/node_modules/fs-minipass/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/npm/node_modules/fs-vacuum": { + "version": "1.2.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/npm/node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/iferr": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/gauge": { + "version": "2.7.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/npm/node_modules/gauge/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/genfun": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/gentle-fs": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "Artistic-2.0", + "dependencies": { + "aproba": "^1.1.2", + "chownr": "^1.1.2", + "cmd-shim": "^3.0.3", + "fs-vacuum": "^1.2.10", + "graceful-fs": "^4.1.11", + "iferr": "^0.1.5", + "infer-owner": "^1.0.4", + "mkdirp": "^0.5.1", + "path-is-inside": "^1.0.2", + "read-cmd-shim": "^1.0.1", + "slide": "^1.1.6" + } + }, + "node_modules/npm/node_modules/gentle-fs/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/gentle-fs/node_modules/iferr": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/npm/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/global-dirs": { + "version": "0.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/got": { + "version": "6.7.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/got/node_modules/get-stream": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/har-schema": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/har-validator": { + "version": "5.1.5", + "deprecated": "this library is no longer supported", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/npm/node_modules/har-validator/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/has": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/npm/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/has-symbols": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "2.8.9", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "3.8.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "4", + "debug": "3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/npm/node_modules/http-signature": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "2.2.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/npm/node_modules/humanize-ms": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.4.23", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/iferr": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/npm/node_modules/import-lazy": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/infer-owner": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/ini": { + "version": "1.3.8", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "1.10.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + } + }, + "node_modules/npm/node_modules/ip": { + "version": "1.1.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/is-callable": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/is-ci": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ci-info": "^1.5.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/npm/node_modules/is-ci/node_modules/ci-info": { + "version": "1.6.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^2.0.10" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/is-date-object": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-installed-globally": { + "version": "0.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/is-npm": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-obj": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-path-inside": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-redirect": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-regex": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/is-retry-allowed": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/is-symbol": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/json-parse-better-errors": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-schema": { + "version": "0.2.3", + "dev": true, + "inBundle": true + }, + "node_modules/npm/node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/JSONStream": { + "version": "1.3.5", + "dev": true, + "inBundle": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/jsprim": { + "version": "1.4.1", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/npm/node_modules/latest-version": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "package-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/lazy-property": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libcipm": { + "version": "4.0.8", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "graceful-fs": "^4.1.11", + "ini": "^1.3.5", + "lock-verify": "^2.1.0", + "mkdirp": "^0.5.1", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "pacote": "^9.1.0", + "read-package-json": "^2.0.13", + "rimraf": "^2.6.2", + "worker-farm": "^1.6.0" + } + }, + "node_modules/npm/node_modules/libnpm": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.3", + "find-npm-prefix": "^1.0.2", + "libnpmaccess": "^3.0.2", + "libnpmconfig": "^1.2.1", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmpublish": "^1.1.2", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "lock-verify": "^2.0.2", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "npm-profile": "^4.0.2", + "npm-registry-fetch": "^4.0.0", + "npmlog": "^4.1.2", + "pacote": "^9.5.3", + "read-package-json": "^2.0.13", + "stringify-package": "^1.0.0" + } + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "get-stream": "^4.0.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "node_modules/npm/node_modules/libnpmconfig": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + } + }, + "node_modules/npm/node_modules/libnpmconfig/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/libnpmconfig/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/libnpmconfig/node_modules/p-limit": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/libnpmconfig/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/libnpmconfig/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "5.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "lodash.clonedeep": "^4.5.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0", + "semver": "^5.5.1", + "ssri": "^6.0.1" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "node_modules/npm/node_modules/libnpx": { + "version": "10.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "dotenv": "^5.0.1", + "npm-package-arg": "^6.0.0", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.0", + "update-notifier": "^2.3.0", + "which": "^1.3.0", + "y18n": "^4.0.0", + "yargs": "^14.2.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/lock-verify": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^6.1.0", + "semver": "^5.4.1" + } + }, + "node_modules/npm/node_modules/lockfile": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "signal-exit": "^3.0.2" + } + }, + "node_modules/npm/node_modules/lodash._baseindexof": { + "version": "3.1.0", + "extraneous": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash._baseuniq": { + "version": "4.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + } + }, + "node_modules/npm/node_modules/lodash._bindcallback": { + "version": "3.0.1", + "extraneous": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash._cacheindexof": { + "version": "3.0.2", + "extraneous": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash._createcache": { + "version": "3.1.2", + "extraneous": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "lodash._getnative": "^3.0.0" + } + }, + "node_modules/npm/node_modules/lodash._createset": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash._getnative": { + "version": "3.9.1", + "extraneous": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash._root": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash.clonedeep": { + "version": "4.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash.restparam": { + "version": "3.6.1", + "extraneous": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash.union": { + "version": "4.6.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash.uniq": { + "version": "4.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lodash.without": { + "version": "4.4.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/lowercase-keys": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/npm/node_modules/make-dir": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "5.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + } + }, + "node_modules/npm/node_modules/meant": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mime-db": { + "version": "1.35.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/mime-types": { + "version": "2.1.19", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mime-db": "~1.35.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/minizlib": { + "version": "1.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/npm/node_modules/mississippi": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/npm/node_modules/mkdirp/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/move-concurrently": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/npm/node_modules/move-concurrently/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "0.0.7", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/node-fetch-npm": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.1.2", + "request": "^2.88.0", + "rimraf": "^2.6.3", + "semver": "^5.7.1", + "tar": "^4.4.12", + "which": "^1.3.1" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm/node_modules/normalize-package-data/node_modules/resolve": { + "version": "1.10.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "1.3.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cli-table3": "^0.5.0", + "console-control-strings": "^1.1.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm/node_modules/npm-cache-filename": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "node_modules/npm/node_modules/npm-lifecycle": { + "version": "3.1.5", + "dev": true, + "inBundle": true, + "license": "Artistic-2.0", + "dependencies": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.15", + "node-gyp": "^5.0.2", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + } + }, + "node_modules/npm/node_modules/npm-logical-tree": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "6.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "1.4.8", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "4.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.1.2 || 2", + "figgy-pudding": "^3.4.1", + "npm-registry-fetch": "^4.0.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "4.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "JSONStream": "^1.3.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/npm-run-path": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/npmlog": { + "version": "4.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/npm/node_modules/number-is-nan": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/oauth-sign": { + "version": "0.9.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/object-keys": { + "version": "1.0.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/npm/node_modules/object.getownpropertydescriptors": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/npm/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/opener": { + "version": "1.5.2", + "dev": true, + "inBundle": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/npm/node_modules/os-homedir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/os-tmpdir": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/osenv": { + "version": "0.1.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/npm/node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/package-json": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "9.5.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-normalize-package-bin": "^1.0.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + } + }, + "node_modules/npm/node_modules/pacote/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/npm/node_modules/parallel-transform": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/npm/node_modules/parallel-transform/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/parallel-transform/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/path-is-inside": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/npm/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/path-parse": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/pify": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/prepend-http": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/process-nextick-args": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/npm/node_modules/promise-retry/node_modules/retry": { + "version": "0.10.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "0.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "1" + } + }, + "node_modules/npm/node_modules/proto-list": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/protoduck": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "genfun": "^5.0.0" + } + }, + "node_modules/npm/node_modules/prr": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/pseudomap": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/psl": { + "version": "1.1.29", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/npm/node_modules/pumpify": { + "version": "1.5.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/npm/node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/npm/node_modules/punycode": { + "version": "1.4.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/qs": { + "version": "6.5.2", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/npm/node_modules/query-string": { + "version": "6.8.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/qw": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/rc": { + "version": "1.2.8", + "dev": true, + "inBundle": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "1.0.7", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/npm/node_modules/read-installed": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "debuglog": "^1.0.1", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/npm/node_modules/read-package-json": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.1", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/npm/node_modules/read-package-tree": { + "version": "5.3.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "node_modules/npm/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/npm/node_modules/registry-auth-token": { + "version": "3.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/npm/node_modules/registry-url": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/request": { + "version": "2.88.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/require-main-filename": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/npm/node_modules/run-queue": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/npm/node_modules/run-queue/node_modules/aproba": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm/node_modules/semver-diff": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "semver": "^5.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/sha": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "(BSD-2-Clause OR MIT)", + "dependencies": { + "graceful-fs": "^4.1.2" + } + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/slide": { + "version": "1.1.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip": "1.1.5", + "smart-buffer": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "4.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/npm/node_modules/sorted-object": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/npm/node_modules/sorted-union-stream": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "from2": "^1.3.0", + "stream-iterate": "^1.1.0" + } + }, + "node_modules/npm/node_modules/sorted-union-stream/node_modules/from2": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.10" + } + }, + "node_modules/npm/node_modules/sorted-union-stream/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/sorted-union-stream/node_modules/readable-stream": { + "version": "1.1.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/npm/node_modules/sorted-union-stream/node_modules/string_decoder": { + "version": "0.10.31", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.5", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/split-on-first": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/sshpk": { + "version": "1.14.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "dashdash": "^1.12.0", + "getpass": "^0.1.1", + "safer-buffer": "^2.0.2" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + }, + "optionalDependencies": { + "bcrypt-pbkdf": "^1.0.0", + "ecc-jsbn": "~0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + } + }, + "node_modules/npm/node_modules/ssri": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/npm/node_modules/stream-each": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/npm/node_modules/stream-iterate": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.1.5", + "stream-shift": "^1.0.0" + } + }, + "node_modules/npm/node_modules/stream-iterate/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/stream-iterate/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/stream-shift": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/strict-uri-encode": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/npm/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/string-width": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/stringify-package": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/strip-eof": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "5.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "4.4.13", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "2.9.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/npm/node_modules/term-size": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "execa": "^0.7.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/through": { + "version": "2.3.8", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/through2": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "node_modules/npm/node_modules/through2/node_modules/readable-stream": { + "version": "2.3.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/npm/node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/npm/node_modules/timed-out": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tough-cookie": { + "version": "2.4.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "inBundle": true, + "license": "Unlicense", + "optional": true + }, + "node_modules/npm/node_modules/typedarray": { + "version": "0.0.6", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/uid-number": { + "version": "0.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/umask": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/npm/node_modules/unique-string": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "crypto-random-string": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/npm/node_modules/unzip-response": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/update-notifier": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/uri-js": { + "version": "4.4.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/npm/node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/url-parse-lax": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "prepend-http": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/util-extend": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/util-promisify": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/npm/node_modules/uuid": { + "version": "3.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/npm/node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/npm/node_modules/which": { + "version": "1.3.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/npm/node_modules/which-module": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/wide-align": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2" + } + }, + "node_modules/npm/node_modules/wide-align/node_modules/string-width": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/widest-line": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/worker-farm": { + "version": "1.7.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "2.4.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/npm/node_modules/xdg-basedir": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/xtend": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/npm/node_modules/y18n": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/yallist": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/yargs": { + "version": "14.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "node_modules/npm/node_modules/yargs-parser": { + "version": "15.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/npm/node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true, + "peer": true + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ob1": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.64.0.tgz", + "integrity": "sha512-CO1N+5dhvy+MoAwxz8+fymEUcwsT4a+wHhrHFb02LppcJdHxgcBWviwEhUwKOD2kLMQ7ijrrzybOqpGcqEtvpQ==", + "dev": true, + "peer": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-filter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-filter/-/object-filter-1.0.2.tgz", + "integrity": "sha1-rwt5f/6+r4pSxmN87b6IFs/sG8g=", + "dev": true + }, + "node_modules/object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.entries": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "peer": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/open/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "peer": true, + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=" + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true, + "optional": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==", + "dev": true, + "peer": true, + "dependencies": { + "base64-js": "^1.5.1", + "xmlbuilder": "^9.0.7", + "xmldom": "^0.5.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "node_modules/popmotion": { + "version": "9.3.6", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-9.3.6.tgz", + "integrity": "sha512-ZTbXiu6zIggXzIliMi8LGxXBF5ST+wkpXGEjeTUDUOCdSQ356hij/xjeUdv0F8zCQNeqB1+PR5/BB+gC+QLAPw==", + "dev": true, + "dependencies": { + "framesync": "5.3.0", + "hey-listen": "^1.0.8", + "style-value-types": "4.1.4", + "tslib": "^2.1.0" + } + }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/portfinder/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-custom-properties": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-10.0.0.tgz", + "integrity": "sha512-55BPj5FudpCiPZzBaO+MOeqmwMDa+nV9/0QBJBfhZjYg6D9hE+rW9lpMBLTJoF4OTXnS5Po4yM1nMlgkPbCxFg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.17", + "postcss-values-parser": "^4.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/postcss-html": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", + "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "dev": true, + "dependencies": { + "htmlparser2": "^3.10.0" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-html/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/postcss-html/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/postcss-html/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/postcss-html/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/postcss-html/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/postcss-html/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/postcss-html/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/postcss-html/node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/postcss-html/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-load-config/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-load-config/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-load-config/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-load-config/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/postcss-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", + "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^3.3.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", + "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "dev": true, + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.26" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-sass": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz", + "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.3.0", + "postcss": "^7.0.21" + } + }, + "node_modules/postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "dev": true, + "peerDependencies": { + "postcss": ">=5.0.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "node_modules/postcss-values-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-4.0.0.tgz", + "integrity": "sha512-R9x2D87FcbhwXUmoCXJR85M1BLII5suXRuXibGYyBJ7lVDEpRIdKZh4+8q5S+/+A4m0IoG1U5tFw39asyhX/Hw==", + "dev": true, + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "postcss": "^7.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/postcss-values-parser/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/postcss/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prettier": { + "name": "wp-prettier", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.0.5.tgz", + "integrity": "sha512-5GCgdeevIXwR3cW4Qj5XWC5MO1iSCz8+IPn0mMw6awAt/PBiey8yyO7MhePRsaMqghJAhg6Q3QLYWSnUHWkG6A==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/pretty-format/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "peer": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "dev": true, + "dependencies": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer": { + "name": "puppeteer-core", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-3.0.0.tgz", + "integrity": "sha512-oWjZFGMc0q2ak+8OxdmMffS79LIT0UEtmpV4h1/AARvESIqqKljf8mrfP+dQ2kas7XttsAZIxRBuWu7Y5JH8KQ==", + "dev": true, + "dependencies": { + "@types/mime-types": "^2.1.0", + "debug": "^4.1.0", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "mime-types": "^2.1.25", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "engines": { + "node": ">=10.18.1" + } + }, + "node_modules/puppeteer/node_modules/agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "dependencies": { + "agent-base": "5", + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/puppeteer/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/quill": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "dependencies": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + } + }, + "node_modules/quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "dependencies": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/quill-delta/node_modules/fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dev": true, + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=", + "dev": true + }, + "node_modules/randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "dependencies": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/re-resizable": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.9.0.tgz", + "integrity": "sha512-3cUDG81ylyqI0Pdgle/RHwwRYq0ORZzsUaySOCO8IbEtNyaRtrIHYm/jMQ5pjcNiKCxR3vsSymIQZHwJq4gg2Q==", + "dev": true, + "dependencies": { + "fast-memoize": "^2.5.1" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0", + "react-dom": "^16.13.1 || ^17.0.0" + } + }, + "node_modules/react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-addons-shallow-compare": { + "version": "15.6.3", + "resolved": "https://registry.npmjs.org/react-addons-shallow-compare/-/react-addons-shallow-compare-15.6.3.tgz", + "integrity": "sha512-EDJbgKTtGRLhr3wiGDXK/+AEJ59yqGS+tKE6mue0aNXT6ZMR7VJbbzIiT6akotmHg1BLj46ElJSb+NBMp80XBg==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0" + } + }, + "node_modules/react-autosize-textarea": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-3.0.3.tgz", + "integrity": "sha512-iOSZK7RUuJ+iEwkJ9rqYciqtjQgrG1CCRFL6h8Bk61kODnRyEq4tS74IgXpI1t4S6jBBZVm+6ugaU+tWTlVxXg==", + "dev": true, + "dependencies": { + "autosize": "^4.0.0", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0", + "react-dom": "^0.14.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/react-codemirror2": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-7.2.1.tgz", + "integrity": "sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==", + "peerDependencies": { + "codemirror": "5.x", + "react": ">=15.5 <=16.x" + } + }, + "node_modules/react-colorful": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-4.4.4.tgz", + "integrity": "sha512-01V2/6rr6sa1vaZntWZJXZxnU7ew02NG2rqq0eoVp4d3gFU5Ug9lDzNMbr+8ns0byXsJbBR8LbwQTlAjz6x7Kg==", + "dev": true, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/react-dates": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-17.2.0.tgz", + "integrity": "sha512-RDlerU8DdRRrlYS0MQ7Z9igPWABGLDwz6+ykBNff67RM3Sset2TDqeuOr+R5o00Ggn5U47GeLsGcSDxlZd9cHw==", + "dev": true, + "dependencies": { + "airbnb-prop-types": "^2.10.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "is-touch-device": "^1.0.1", + "lodash": "^4.1.1", + "object.assign": "^4.1.0", + "object.values": "^1.0.4", + "prop-types": "^15.6.1", + "react-addons-shallow-compare": "^15.6.2", + "react-moment-proptypes": "^1.6.0", + "react-outside-click-handler": "^1.2.0", + "react-portal": "^4.1.5", + "react-with-styles": "^3.2.0", + "react-with-styles-interface-css": "^4.0.2" + }, + "peerDependencies": { + "moment": "^2.18.1", + "react": "^0.14 || ^15.5.4 || ^16.1.1", + "react-dom": "^0.14 || ^15.5.4 || ^16.1.1" + } + }, + "node_modules/react-datetime": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/react-datetime/-/react-datetime-3.1.1.tgz", + "integrity": "sha512-gHCTjAniCcMb6jdXpz+MpVe/uCeaHNDOofg+l41nLlJI3uBLBMV40CQbGB2TCTUpCzGT1mCs4vQzKGMjXO/WWQ==", + "dependencies": { + "prop-types": "^15.5.7" + }, + "peerDependencies": { + "moment": "^2.16.0", + "react": "^16.5.0 || ^17.0.0" + } + }, + "node_modules/react-devtools-core": { + "version": "4.13.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.13.5.tgz", + "integrity": "sha512-k+P5VSKM6P22Go9IQ8dJmjj9fbztvKt1iRDI/4wS5oTvd1EnytIJMYB59wZt+D3kgp64jklNX/MRmY42xAQ08g==", + "dev": true, + "peer": true, + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "node_modules/react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/react-easy-crop": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-3.5.2.tgz", + "integrity": "sha512-cwSGO/wk42XDpEyrdAcnQ6OJetVDZZO2ry1i19+kSGZQ750aN06RU9y9z95B5QI6sW3SnaWQRKv5r5GSqVV//g==", + "dev": true, + "dependencies": { + "normalize-wheel": "^1.0.1", + "tslib": "2.0.1" + }, + "peerDependencies": { + "react": ">=16.4.0", + "react-dom": ">=16.4.0" + } + }, + "node_modules/react-easy-crop/node_modules/tslib": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", + "dev": true + }, + "node_modules/react-input-autosize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", + "integrity": "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==", + "dependencies": { + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-merge-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", + "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/react-moment-proptypes": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/react-moment-proptypes/-/react-moment-proptypes-1.8.1.tgz", + "integrity": "sha512-Er940DxWoObfIqPrZNfwXKugjxMIuk1LAuEzn23gytzV6hKS/sw108wibi9QubfMN4h+nrlje8eUCSbQRJo2fQ==", + "dev": true, + "dependencies": { + "moment": ">=1.6.0" + }, + "peerDependencies": { + "moment": ">=1.6.0" + } + }, + "node_modules/react-native-codegen": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.6.tgz", + "integrity": "sha512-cMvrUelD81wiPitEPiwE/TCNscIVauXxmt4NTGcy18HrUd0WRWXfYzAQGXm0eI87u3NMudNhqFj2NISJenxQHg==", + "dev": true, + "peer": true, + "dependencies": { + "flow-parser": "^0.121.0", + "jscodeshift": "^0.11.0", + "nullthrows": "^1.1.1" + } + }, + "node_modules/react-outside-click-handler": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-outside-click-handler/-/react-outside-click-handler-1.3.0.tgz", + "integrity": "sha512-Te/7zFU0oHpAnctl//pP3hEAeobfeHMyygHB8MnjP6sX5OR8KHT1G3jmLsV3U9RnIYo+Yn+peJYWu+D5tUS8qQ==", + "dev": true, + "dependencies": { + "airbnb-prop-types": "^2.15.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "document.contains": "^1.0.1", + "object.values": "^1.1.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.14 || >=15", + "react-dom": "^0.14 || >=15" + } + }, + "node_modules/react-portal": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-4.2.1.tgz", + "integrity": "sha512-fE9kOBagwmTXZ3YGRYb4gcMy+kSA+yLO0xnPankjRlfBv4uCpFXqKPfkpsGQQR15wkZ9EssnvTOl1yMzbkxhPQ==", + "dev": true, + "dependencies": { + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": "^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0" + } + }, + "node_modules/react-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-1.0.1.tgz", + "integrity": "sha512-1tKOwxFn3dXVomH6pM9IkLkq2Y8oh+fh/lYW3MJ/B03URswUTqttgckOlbxY2XHF3vPG6uanSc4dVsLW/wk3wQ==" + }, + "node_modules/react-quill": { + "version": "2.0.0-beta.4", + "resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0-beta.4.tgz", + "integrity": "sha512-KyAHvAlPjP4xLElKZJefMth91Z6FbbXRvq9OSu6xN3KBaoasLP9p+3dcxg4Ywr4tBlpMGXcPszYSAgd5CpJ45Q==", + "dependencies": { + "@types/quill": "^1.3.10", + "lodash": "^4.17.4", + "quill": "^1.3.7" + }, + "peerDependencies": { + "react": "^16 || ^17", + "react-dom": "^16 || ^17" + } + }, + "node_modules/react-refresh": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", + "integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-resize-aware": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-resize-aware/-/react-resize-aware-3.1.0.tgz", + "integrity": "sha512-bIhHlxVTX7xKUz14ksXMEHjzCZPTpQZKZISY3nbTD273pDKPABGFNFBP6Tr42KECxzC5YQiKpMchjTVJCqaxpA==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0" + } + }, + "node_modules/react-select": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", + "integrity": "sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.1.1", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^3.0.0", + "react-transition-group": "^4.3.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/react-select/node_modules/@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "dependencies": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "node_modules/react-select/node_modules/@emotion/sheet": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.1.tgz", + "integrity": "sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==" + }, + "node_modules/react-select/node_modules/@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "node_modules/react-spring": { + "version": "8.0.27", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz", + "integrity": "sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.3.1", + "prop-types": "^15.5.8" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/react-test-renderer": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", + "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/react-textarea-autosize": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-use-gesture": { + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-7.0.16.tgz", + "integrity": "sha512-gwgX+E+WQG0T1uFVl3z8j3ZwH3QQGIgVl7VtQEC2m0IscSs668sSps4Ss3CFp3Vns8xx0j9TVK4aBXH6+YrpEg==", + "dev": true, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/react-with-direction": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.1.tgz", + "integrity": "sha512-aGcM21ZzhqeXFvDCfPj0rVNYuaVXfTz5D3Rbn0QMz/unZe+CCiLHthrjQWO7s6qdfXORgYFtmS7OVsRgSk5LXQ==", + "dev": true, + "dependencies": { + "airbnb-prop-types": "^2.10.0", + "brcast": "^2.0.2", + "deepmerge": "^1.5.2", + "direction": "^1.0.2", + "hoist-non-react-statics": "^3.3.0", + "object.assign": "^4.1.0", + "object.values": "^1.0.4", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "^0.14 || ^15 || ^16", + "react-dom": "^0.14 || ^15 || ^16" + } + }, + "node_modules/react-with-direction/node_modules/deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-with-styles": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/react-with-styles/-/react-with-styles-3.2.3.tgz", + "integrity": "sha512-MTI1UOvMHABRLj5M4WpODfwnveHaip6X7QUMI2x6zovinJiBXxzhA9AJP7MZNaKqg1JRFtHPXZdroUC8KcXwlQ==", + "dev": true, + "dependencies": { + "hoist-non-react-statics": "^3.2.1", + "object.assign": "^4.1.0", + "prop-types": "^15.6.2", + "react-with-direction": "^1.3.0" + }, + "peerDependencies": { + "react": ">=0.14", + "react-with-direction": "^1.1.0" + } + }, + "node_modules/react-with-styles-interface-css": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/react-with-styles-interface-css/-/react-with-styles-interface-css-4.0.3.tgz", + "integrity": "sha512-wE43PIyjal2dexxyyx4Lhbcb+E42amoYPnkunRZkb9WTA+Z+9LagbyxwsI352NqMdFmghR0opg29dzDO4/YXbw==", + "dev": true, + "dependencies": { + "array.prototype.flat": "^1.2.1", + "global-cache": "^1.2.1" + }, + "peerDependencies": { + "react-with-styles": "^3.0.0" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/readdirp/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "optional": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "optional": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "optional": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "optional": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "optional": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "optional": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reakit": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/reakit/-/reakit-1.3.8.tgz", + "integrity": "sha512-8SVejx6FUaFi2+Q9eXoDAd4wWi/xAn6v8JgXH8x2xnzye8pb6v5bYvegACVpYVZnrS5w/JUgMTGh1Xy8MkkPww==", + "dev": true, + "dependencies": { + "@popperjs/core": "^2.5.4", + "body-scroll-lock": "^3.1.5", + "reakit-system": "^0.15.1", + "reakit-utils": "^0.15.1", + "reakit-warning": "^0.6.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/reakit" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/reakit-system": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/reakit-system/-/reakit-system-0.15.1.tgz", + "integrity": "sha512-PkqfAyEohtcEu/gUvKriCv42NywDtUgvocEN3147BI45dOFAB89nrT7wRIbIcKJiUT598F+JlPXAZZVLWhc1Kg==", + "dev": true, + "dependencies": { + "reakit-utils": "^0.15.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/reakit-utils": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/reakit-utils/-/reakit-utils-0.15.1.tgz", + "integrity": "sha512-6cZgKGvOkAMQgkwU9jdYbHfkuIN1Pr+vwcB19plLvcTfVN0Or10JhIuj9X+JaPZyI7ydqTDFaKNdUcDP69o/+Q==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/reakit-warning": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/reakit-warning/-/reakit-warning-0.6.1.tgz", + "integrity": "sha512-poFUV0EyxB+CcV9uTNBAFmcgsnR2DzAbOTkld4Ul+QOKSeEHZB3b3+MoZQgcYHmbvG19Na1uWaM7ES+/Eyr8tQ==", + "dev": true, + "dependencies": { + "reakit-utils": "^0.15.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/recast": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.4.tgz", + "integrity": "sha512-6qLIBGGRcwjrTZGIiBpJVC/NeuXpogXNyRQpqU1zWPUigCphvApoCs9KIwDYh1eDuJ6dAFlQoi/QUyE5KQ6RBQ==", + "dev": true, + "peer": true, + "dependencies": { + "ast-types": "0.14.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/recast/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", + "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/redux": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz", + "integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-multi": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/redux-multi/-/redux-multi-0.1.12.tgz", + "integrity": "sha1-KOH+XklnLLxb2KB/Cyrq8O+DVcI=", + "dev": true + }, + "node_modules/redux-optimist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redux-optimist/-/redux-optimist-1.0.0.tgz", + "integrity": "sha512-AG1v8o6UZcGXTEH2jVcWG6KD+gEix+Cj9JXAAzln9MPkauSVd98H7N7EOOyT/v4c9N1mJB4sm1zfspGlLDkUEw==", + "dev": true + }, + "node_modules/redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, + "node_modules/reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=", + "dev": true + }, + "node_modules/refx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/refx/-/refx-3.1.1.tgz", + "integrity": "sha512-lwN27W5iYyagpCxxYDYDl0IIiKh0Vgi3wvafqfthbzTfBgLOYAstcftp+G2X612xVaB8rhn5wDxd4er4KEeb8A==", + "dev": true + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "node_modules/regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "dev": true, + "engines": { + "node": ">=0.1.14" + } + }, + "node_modules/regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "dev": true, + "dependencies": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, + "dependencies": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/remark-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "dev": true, + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark/node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/remark/node_modules/remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dev": true, + "dependencies": { + "mdast-util-from-markdown": "^0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark/node_modules/unified": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.1.tgz", + "integrity": "sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==", + "dev": true, + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark/node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark/node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rememo": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rememo/-/rememo-3.0.0.tgz", + "integrity": "sha512-eWtut/7pqMRnSccbexb647iPjN7ir6Tmf4RG92ZVlykFEkHqGYy9tWnpHH3I+FS+WQ6lQ1i1iDgarYzGKgTcRQ==", + "dev": true + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/reselect": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-bin": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/resolve-bin/-/resolve-bin-0.4.0.tgz", + "integrity": "sha1-RxMiSYkRAa+xmZH+k3ywpfBy5dk=", + "dev": true, + "dependencies": { + "find-parent-dir": "~0.3.0" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true, + "dependencies": { + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-dir/node_modules/expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "dev": true + }, + "node_modules/resolve-pkg": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz", + "integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=", + "dev": true, + "dependencies": { + "resolve-from": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg/node_modules/resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "peer": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "peer": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rst-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", + "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=", + "dev": true, + "dependencies": { + "lodash.flattendeep": "^4.4.0", + "nearley": "^2.7.10" + } + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "node_modules/rtlcss": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-2.6.2.tgz", + "integrity": "sha512-06LFAr+GAPo+BvaynsXRfoYTJvSaWRyOhURCQ7aeI1MKph9meM222F+Zkt3bDamyHHJuGi3VPtiRkpyswmQbGA==", + "dev": true, + "dependencies": { + "@choojs/findup": "^0.2.1", + "chalk": "^2.4.2", + "mkdirp": "^0.5.1", + "postcss": "^6.0.23", + "strip-json-comments": "^2.0.0" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + } + }, + "node_modules/rtlcss/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/rtlcss/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/rtlcss/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rtlcss/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/rungen": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/rungen/-/rungen-0.3.2.tgz", + "integrity": "sha1-QAwJ6+kU57F+C27zJjQA/Cq8fLM=", + "dev": true + }, + "node_modules/rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dev": true, + "dependencies": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sane/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/sane/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sane/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sane/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sane/node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sane/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sane/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/sanitize-html": { + "version": "1.27.5", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.27.5.tgz", + "integrity": "sha512-M4M5iXDAUEcZKLXkmk90zSYWEtk5NH3JmojQxKxV371fnMh+x9t1rqdmXaGoyEHw3z/X/8vnFhKjGL5xFGOJ3A==", + "dependencies": { + "htmlparser2": "^4.1.0", + "lodash": "^4.17.15", + "parse-srcset": "^1.0.2", + "postcss": "^7.0.27" + } + }, + "node_modules/sanitize-html/node_modules/domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "node_modules/sass": { + "version": "1.35.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.35.1.tgz", + "integrity": "sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + }, + "bin": { + "sassgraph": "bin/sassgraph" + } + }, + "node_modules/sass-graph/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/sass-graph/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/sass-graph/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sass-graph/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/sass-loader": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz", + "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.0.1", + "neo-async": "^2.5.0", + "pify": "^4.0.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/sass-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/sass-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "dependencies": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + } + }, + "node_modules/scss-tokenizer/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "dev": true + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "peer": true, + "dependencies": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "node_modules/shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "peer": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "node_modules/showdown": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", + "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==", + "dev": true, + "dependencies": { + "yargs": "^14.2" + }, + "bin": { + "showdown": "bin/showdown.js" + } + }, + "node_modules/showdown/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/showdown/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/showdown/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/showdown/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/showdown/node_modules/yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "node_modules/showdown/node_modules/yargs-parser": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz", + "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/simple-html-tokenizer": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", + "dev": true + }, + "node_modules/simple-plist": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.1.1.tgz", + "integrity": "sha512-pKMCVKvZbZTsqYR6RKgLfBHkh2cV89GXcA/0CVPje3sOiNOnXA8+rp/ciAMZ7JRaUdLzlEM6JFfUn+fS6Nt3hg==", + "dev": true, + "peer": true, + "dependencies": { + "bplist-creator": "0.0.8", + "bplist-parser": "0.2.0", + "plist": "^3.0.1" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", + "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", + "dev": true, + "dependencies": { + "async": "^2.5.0", + "loader-utils": "^1.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/source-map-loader/node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/source-map-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/source-map-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "node_modules/spawnd": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-4.4.0.tgz", + "integrity": "sha512-jLPOfB6QOEgMOQY15Z6+lwZEhH3F5ncXxIaZ7WHPIapwNNLyjrs61okj3VJ3K6tmP5TZ6cO0VAu9rEY4MD4YQg==", + "dev": true, + "dependencies": { + "exit": "^0.1.2", + "signal-exit": "^3.0.2", + "tree-kill": "^1.2.2", + "wait-port": "^0.2.7" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "node_modules/specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true, + "bin": { + "specificity": "bin/specificity" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "dev": true, + "peer": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", + "dev": true, + "peer": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=", + "dev": true + }, + "node_modules/string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "dependencies": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.4.tgz", + "integrity": "sha512-hWCk/iqf7lp0/AgTF7/ddO1IWtSNPASjlzCicV5irAVdE1grjsneK26YG6xACMBEdCvO8fUST0UzDMh/2Qy+9Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent/node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/style-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/style-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/style-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "node_modules/style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/style-value-types": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-4.1.4.tgz", + "integrity": "sha512-LCJL6tB+vPSUoxgUBt9juXIlNJHtBMy8jkXzUJSBzeHWdBu6lhzHqCvLVkXFGsFIlNa2ln1sQHya/gzaFmB2Lg==", + "dev": true, + "dependencies": { + "hey-listen": "^1.0.8", + "tslib": "^2.1.0" + } + }, + "node_modules/styled-griddie": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/styled-griddie/-/styled-griddie-0.1.3.tgz", + "integrity": "sha512-RjsiiADJrRpdPTF8NR26nlZutnvkrX78tiM5/za/E+ftVdpjD8ZBb2iOzrIzfix80uDcHYQbg3iIR0lOGaYmEQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint": { + "version": "13.13.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.13.1.tgz", + "integrity": "sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==", + "dev": true, + "dependencies": { + "@stylelint/postcss-css-in-js": "^0.37.2", + "@stylelint/postcss-markdown": "^0.36.2", + "autoprefixer": "^9.8.6", + "balanced-match": "^2.0.0", + "chalk": "^4.1.1", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "execall": "^2.0.0", + "fast-glob": "^3.2.5", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.0.3", + "globjoin": "^0.1.4", + "html-tags": "^3.1.0", + "ignore": "^5.1.8", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.21.0", + "lodash": "^4.17.21", + "log-symbols": "^4.1.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.4", + "normalize-selector": "^0.2.0", + "postcss": "^7.0.35", + "postcss-html": "^0.36.0", + "postcss-less": "^3.1.4", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.2", + "postcss-sass": "^0.4.4", + "postcss-scss": "^2.1.1", + "postcss-selector-parser": "^6.0.5", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^4.1.0", + "resolve-from": "^5.0.0", + "slash": "^3.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.2", + "strip-ansi": "^6.0.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^6.6.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^3.0.3" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz", + "integrity": "sha512-F6yTRuc06xr1h5Qw/ykb2LuFynJ2IxkKfCMf+1xqPffkxh0S09Zc902XCffcsw/XMFq/OzQ1w54fLIDtmRNHnQ==", + "dev": true, + "peerDependencies": { + "stylelint": ">=10.1.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-4.2.0.tgz", + "integrity": "sha512-4bI5BYbabo/GCQ6LbRZx/ZlVkK65a1jivNNsD+ix/Lw0U3iAch+jQcvliGnnAX8SUPaZ0UqzNVNNAF3urswa7g==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^3.0.0" + }, + "peerDependencies": { + "stylelint": "^10.1.0 || ^11.0.0 || ^12.0.0 || ^13.0.0", + "stylelint-scss": "^3.0.0" + } + }, + "node_modules/stylelint-config-wordpress": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wordpress/-/stylelint-config-wordpress-17.0.0.tgz", + "integrity": "sha512-qUU2kVMd2ezIV9AzRdgietIfnavRRENt4180A1OMoVXIowRjjhohZgBiyVPV5EtNKo3GTO63l8g/QGNG27/h9g==", + "deprecated": "This package has been deprecated, please use @wordpress/stylelint-config or @wordpress/scripts", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^3.0.0", + "stylelint-config-recommended-scss": "^4.2.0", + "stylelint-scss": "^3.17.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "stylelint": "^10.1.0 || ^11.0.0 || ^12.0.0 || ^13.0.0" + } + }, + "node_modules/stylelint-scss": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.19.0.tgz", + "integrity": "sha512-Ic5bsmpS4wVucOw44doC1Yi9f5qbeVL4wPFiEOaUElgsOuLEN6Ofn/krKI8BeNL2gAn53Zu+IcVV4E345r6rBw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "stylelint": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0" + } + }, + "node_modules/stylelint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/stylelint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/stylelint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/stylelint/node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint/node_modules/map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/stylelint/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylelint/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylelint/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/stylelint/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/stylis": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", + "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + }, + "node_modules/sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "dev": true, + "peer": true + }, + "node_modules/sugarss": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", + "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/svgo/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tannin": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tannin/-/tannin-1.2.0.tgz", + "integrity": "sha512-U7GgX/RcSeUETbV7gYgoz8PD7Ni4y95pgIP/Z6ayI3CfhSujwKEBlGFTCRN+Aqnuyf4AN2yHL+L8x+TCGjb9uA==", + "dev": true, + "dependencies": { + "@tannin/plural-forms": "^1.1.0" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "dev": true, + "dependencies": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/temp": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", + "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", + "dev": true, + "peer": true, + "dependencies": { + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/thread-loader": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz", + "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==", + "dev": true, + "dependencies": { + "loader-runner": "^2.3.1", + "loader-utils": "^1.1.0", + "neo-async": "^2.6.0" + }, + "engines": { + "node": ">= 6.9.0 <7.0.0 || >= 8.9.0" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/thread-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/thread-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true + }, + "node_modules/tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==", + "dev": true + }, + "node_modules/tiny-lr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", + "dev": true, + "dependencies": { + "body": "^5.1.0", + "debug": "^3.1.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + } + }, + "node_modules/tiny-lr/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "dev": true + }, + "node_modules/tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/tippy.js": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.1.tgz", + "integrity": "sha512-JnFncCq+rF1dTURupoJ4yPie5Cof978inW6/4S6kmWV7LL9YOSEVMifED3KdrVPEG+Z/TFH2CDNJcQEfaeuQww==", + "dependencies": { + "@popperjs/core": "^2.8.3" + } + }, + "node_modules/tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=", + "dev": true + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "dev": true, + "dependencies": { + "glob": "^7.1.2" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "node_modules/ts-essentials": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz", + "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==", + "dev": true + }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/turbo-combine-reducers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/turbo-combine-reducers/-/turbo-combine-reducers-1.0.2.tgz", + "integrity": "sha512-gHbdMZlA6Ym6Ur5pSH/UWrNQMIM9IqTH6SoL1DbHpqEdQ8i+cFunSmSlFykPt0eGQwZ4d/XTHOl74H0/kFBVWw==", + "dev": true + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "node_modules/uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "deprecated": "support for ECMAScript is superseded by `uglify-js` as of v3.13.0", + "dev": true, + "peer": true, + "dependencies": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-es/node_modules/commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "dev": true, + "peer": true + }, + "node_modules/uglify-es/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true, + "peer": true + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "node_modules/underscore.string": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "dev": true, + "dependencies": { + "sprintf-js": "^1.0.3", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "dev": true, + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + } + }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/unist-util-find-all-after": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", + "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==", + "dev": true, + "dependencies": { + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "node_modules/unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "node_modules/unist-util-visit-parents/node_modules/unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-3.0.0.tgz", + "integrity": "sha512-a84JJbIA5xTFTWyjjcPdnsu+41o/SNE8SpXMdUvXs6Q+LuhCD9E2+0VCiuDWqgo3GGXVlFHzArDmBpj9PgWn4A==", + "dev": true, + "dependencies": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/url-loader/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use-composed-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", + "dev": true, + "dependencies": { + "ts-essentials": "^2.0.3" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/use-enhanced-state": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/use-enhanced-state/-/use-enhanced-state-0.0.13.tgz", + "integrity": "sha512-RCtUQdhfUXu/0GAQqLnKPetUt3BheYFpOTogppHe9x1XGwluiu6DQLKVNnc3yMfj0HM3IOVBgw5nVJJuZS5TWQ==", + "dev": true, + "dependencies": { + "@itsjonq/is": "0.0.2", + "tiny-warning": "^1.0.3" + }, + "peerDependencies": { + "react": "^16.8.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", + "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", + "dev": true, + "dependencies": { + "use-isomorphic-layout-effect": "^1.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-memo-one": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.2.tgz", + "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/use-subscription": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", + "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", + "dev": true, + "peer": true, + "dependencies": { + "object-assign": "^4.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": "8.x.x || >=10.10.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "node_modules/vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "dependencies": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "node_modules/vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", + "dev": true, + "peer": true + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wait-on": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.3.0.tgz", + "integrity": "sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ==", + "dev": true, + "dependencies": { + "@hapi/joi": "^15.0.3", + "core-js": "^2.6.5", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/wait-port": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-0.2.9.tgz", + "integrity": "sha512-hQ/cVKsNqGZ/UbZB/oakOGFqic00YAMM5/PEj3Bt4vKarv2jWIWzDbqlwT94qMs/exAQAsvMOq99sZblV92zxQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "commander": "^3.0.2", + "debug": "^4.1.1" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wait-port/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "dependencies": { + "makeerror": "1.0.x" + } + }, + "node_modules/watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "optionalDependencies": { + "chokidar": "^3.4.1", + "watchpack-chokidar2": "^2.0.1" + } + }, + "node_modules/watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "dependencies": { + "chokidar": "^2.1.8" + } + }, + "node_modules/watchpack-chokidar2/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "optional": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "peer": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + }, + "webpack-command": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz", + "integrity": "sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.19", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 6.14.4" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/webpack-bundle-analyzer/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "peerDependencies": { + "webpack": "4.x.x" + } + }, + "node_modules/webpack-cli/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/webpack-cli/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/webpack-cli/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/webpack-cli/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/webpack-cli/node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/webpack-cli/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-cli/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/webpack-cli/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-cli/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-cli/node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-cli/node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/resolve-dir/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/resolve-dir/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-cli/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-cli/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/webpack-cli/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/webpack-livereload-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-livereload-plugin/-/webpack-livereload-plugin-2.3.0.tgz", + "integrity": "sha512-vVBLQLlNpElt2sfsBG+XLDeVbQFS4RrniVU8Hi1/hX5ycSfx6mtW8MEEITr2g0Cvo36kuPWShFFDuy+DS7KFMA==", + "dev": true, + "dependencies": { + "anymatch": "^3.1.1", + "portfinder": "^1.0.17", + "tiny-lr": "^1.1.1" + } + }, + "node_modules/webpack-livereload-plugin/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack-sources/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/webpack/node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", + "dev": true, + "peer": true + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "dev": true, + "dependencies": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url-without-unicode/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz", + "integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "node_modules/xcode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz", + "integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==", + "dev": true, + "peer": true, + "dependencies": { + "simple-plist": "^1.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/xcode/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "peer": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/xmldoc": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", + "integrity": "sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ==", + "dev": true, + "peer": true, + "dependencies": { + "sax": "^1.2.1" + } + }, + "node_modules/xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "dependencies": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/yargs-unparser/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/yargs-unparser/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs-unparser/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + }, + "dependencies": { + "@babel/cli": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.5.tgz", + "integrity": "sha512-poegjhRvXHWO0EAsnYajwYZuqcz7gyfxwfaecUESxDujrqOivf3zrjFbub8IJkrqEaz3fvJWh001EzxBub54fg==", + "dev": true, + "requires": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.2", + "chokidar": "^3.4.0", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + } + }, + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "devOptional": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/compat-data": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "devOptional": true + }, + "@babel/core": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "devOptional": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz", + "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "devOptional": true, + "requires": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", + "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", + "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz", + "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz", + "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "devOptional": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "devOptional": true, + "requires": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz", + "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-wrap-function": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-replace-supers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "devOptional": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", + "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "devOptional": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "devOptional": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "devOptional": true + }, + "@babel/helper-wrap-function": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz", + "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helpers": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "devOptional": true, + "requires": { + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "devOptional": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "devOptional": true + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5" + } + }, + "@babel/plugin-external-helpers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.14.5.tgz", + "integrity": "sha512-q/B/hLX+nDGk73Xn529d7Ar4ih17J8pNBbsXafq8oXij0XfFEA/bks+u+6q5q04zO5o/qivjzui6BqzPfYShEg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz", + "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz", + "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-default-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", + "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-default-from": "^7.14.5" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", + "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz", + "integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.7", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.14.5" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", + "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", + "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-default-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", + "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", + "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz", + "integrity": "sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", + "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", + "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-remap-async-to-generator": "^7.14.5" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", + "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz", + "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz", + "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", + "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", + "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", + "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", + "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", + "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", + "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-flow": "^7.14.5" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", + "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", + "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", + "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", + "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", + "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz", + "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz", + "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", + "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz", + "integrity": "sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", + "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-object-assign": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz", + "integrity": "sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", + "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", + "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", + "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-constant-elements": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.14.5.tgz", + "integrity": "sha512-NBqLEx1GxllIOXJInJAQbrnwwYJsV3WaMHIcOwD8rhYS0AabTWn7kHdHgPgu5RmHLU0q4DMxhAMu8ue/KampgQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.5.tgz", + "integrity": "sha512-07aqY1ChoPgIxsuDviptRpVkWCSbXWmzQqcgy65C6YSFOfPFvb/DX3bBRHh7pCd/PMEEYHYWUTSVkCbkVainYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.5.tgz", + "integrity": "sha512-7RylxNeDnxc1OleDm0F5Q/BSL+whYRbOAR+bwgCxIr0L32v7UFh/pz1DLMZideAUxKT6eMoS2zQH6fyODLEi8Q==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.14.5.tgz", + "integrity": "sha512-rdwG/9jC6QybWxVe2UVOa7q6cnTpw8JRRHOxntG/h6g/guAOe6AhtQHJuJh5FwmnXIT1bdm5vC2/5huV8ZOorQ==", + "dev": true, + "requires": { + "@babel/plugin-transform-react-jsx": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.14.5.tgz", + "integrity": "sha512-M/fmDX6n0cfHK/NLTcPmrfVAORKDhK8tyjDhyxlUjYyPYYO8FRWwuxBA3WBx8kWN/uBUuwGa3s/0+hQ9JIN3Tg==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.5.tgz", + "integrity": "sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.14.5.tgz", + "integrity": "sha512-3X4HpBJimNxW4rhUy/SONPyNQHp5YRr0HhJdT2OH1BRp0of7u3Dkirc7x9FRJMKMqTBI079VZ1hzv7Ouuz///g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", + "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", + "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz", + "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "semver": "^6.3.0" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", + "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", + "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", + "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-strict-mode": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-strict-mode/-/plugin-transform-strict-mode-7.14.5.tgz", + "integrity": "sha512-1oLnWpVtGIwDDxOcd2EuS79kj3f+xhYHoyGy8F7XS26v7ueFyTlglKlnXs5DQ6kyrodXp6eEXbLBISuauuSj/A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", + "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", + "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz", + "integrity": "sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.6", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz", + "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", + "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/polyfill": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", + "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/preset-env": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz", + "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.7", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-async-generator-functions": "^7.14.7", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-class-static-block": "^7.14.5", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-json-strings": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-object-rest-spread": "^7.14.7", + "@babel/plugin-proposal-optional-catch-binding": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.14.5", + "@babel/plugin-proposal-unicode-property-regex": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.14.5", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/plugin-transform-block-scoped-functions": "^7.14.5", + "@babel/plugin-transform-block-scoping": "^7.14.5", + "@babel/plugin-transform-classes": "^7.14.5", + "@babel/plugin-transform-computed-properties": "^7.14.5", + "@babel/plugin-transform-destructuring": "^7.14.7", + "@babel/plugin-transform-dotall-regex": "^7.14.5", + "@babel/plugin-transform-duplicate-keys": "^7.14.5", + "@babel/plugin-transform-exponentiation-operator": "^7.14.5", + "@babel/plugin-transform-for-of": "^7.14.5", + "@babel/plugin-transform-function-name": "^7.14.5", + "@babel/plugin-transform-literals": "^7.14.5", + "@babel/plugin-transform-member-expression-literals": "^7.14.5", + "@babel/plugin-transform-modules-amd": "^7.14.5", + "@babel/plugin-transform-modules-commonjs": "^7.14.5", + "@babel/plugin-transform-modules-systemjs": "^7.14.5", + "@babel/plugin-transform-modules-umd": "^7.14.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7", + "@babel/plugin-transform-new-target": "^7.14.5", + "@babel/plugin-transform-object-super": "^7.14.5", + "@babel/plugin-transform-parameters": "^7.14.5", + "@babel/plugin-transform-property-literals": "^7.14.5", + "@babel/plugin-transform-regenerator": "^7.14.5", + "@babel/plugin-transform-reserved-words": "^7.14.5", + "@babel/plugin-transform-shorthand-properties": "^7.14.5", + "@babel/plugin-transform-spread": "^7.14.6", + "@babel/plugin-transform-sticky-regex": "^7.14.5", + "@babel/plugin-transform-template-literals": "^7.14.5", + "@babel/plugin-transform-typeof-symbol": "^7.14.5", + "@babel/plugin-transform-unicode-escapes": "^7.14.5", + "@babel/plugin-transform-unicode-regex": "^7.14.5", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.14.5", + "babel-plugin-polyfill-corejs2": "^0.2.2", + "babel-plugin-polyfill-corejs3": "^0.2.2", + "babel-plugin-polyfill-regenerator": "^0.2.2", + "core-js-compat": "^3.15.0", + "semver": "^6.3.0" + } + }, + "@babel/preset-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", + "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-flow-strip-types": "^7.14.5" + } + }, + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.14.5.tgz", + "integrity": "sha512-XFxBkjyObLvBaAvkx1Ie95Iaq4S/GUEIrejyrntQ/VCMKUYvKLoyKxOBzJ2kjA3b6rC9/KL6KXfDC2GqvLiNqQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-react-display-name": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.5", + "@babel/plugin-transform-react-jsx-development": "^7.14.5", + "@babel/plugin-transform-react-pure-annotations": "^7.14.5" + } + }, + "@babel/preset-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz", + "integrity": "sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==", + "dev": true, + "peer": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.14.5" + } + }, + "@babel/register": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.14.5.tgz", + "integrity": "sha512-TjJpGz/aDjFGWsItRBQMOFTrmTI9tr79CHOK+KIvLeCkbxuOAk2M5QHjvruIMGoo9OuccMh5euplPzc5FjAKGg==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + } + }, + "@babel/runtime": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", + "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz", + "integrity": "sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==", + "dev": true, + "requires": { + "core-js-pure": "^3.15.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "devOptional": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "devOptional": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "devOptional": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@choojs/findup": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@choojs/findup/-/findup-0.2.1.tgz", + "integrity": "sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==", + "dev": true, + "requires": { + "commander": "^2.15.1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@dnd-kit/accessibility": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz", + "integrity": "sha512-QwaQ1IJHQHMMuAGOOYHQSx7h7vMZPfO97aDts8t5N/MY7n2QTDSnW+kF7uRQ1tVBkr6vJ+BqHWG5dlgGvwVjow==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@dnd-kit/core": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-3.1.1.tgz", + "integrity": "sha512-18YY5+1lTqJbGSg6JBSa/fjAOTUYAysFrQ5Ti8oppEPHFacQbC+owM51y2z2KN0LkDHBfGZKw2sFT7++ttwfpA==", + "requires": { + "@dnd-kit/accessibility": "^3.0.0", + "@dnd-kit/utilities": "^2.0.0", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/modifiers": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-3.0.0.tgz", + "integrity": "sha512-CmskqOcW4Bw61JP1Lqkx7cRzv9xQS/5seI+Q5eKhx+mS/MA5IrX2jgtMxvQ6PKYDnx2v/uHxqLNVhlvumtBTSQ==", + "requires": { + "@dnd-kit/utilities": "^2.0.0", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/sortable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-4.0.0.tgz", + "integrity": "sha512-teYVFy6mQG/u6F6CaGxAkzPfiNJvguFzWfJ/zonYQRxfANHX6QJ6GziMG9KON/Ae9Q2ODJP8vib+guWJrDXeGg==", + "requires": { + "@dnd-kit/utilities": "^2.0.0", + "tslib": "^2.0.0" + } + }, + "@dnd-kit/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-bjs49yMNzMM+BYRsBUhTqhTk6HEvhuY3leFt6Em6NaYGgygaMbtGbbXof/UXBv7rqyyi0OkmBBnrCCcxqS2t/g==", + "requires": { + "tslib": "^2.0.0" + } + }, + "@emotion/cache": { + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", + "dev": true, + "requires": { + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + } + }, + "@emotion/core": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz", + "integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/css": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz", + "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==", + "dev": true, + "requires": { + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3", + "babel-plugin-emotion": "^10.0.27" + } + }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "dev": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/primitives-core": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/primitives-core/-/primitives-core-10.0.27.tgz", + "integrity": "sha512-fRBEDNPSFFOrBJ0OcheuElayrNTNdLF9DzMxtL0sFgsCFvvadlzwJHhJMSwEJuxwARm9GhVLr1p8G8JGkK98lQ==", + "dev": true, + "requires": { + "css-to-react-native": "^2.2.1" + } + }, + "@emotion/react": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.4.0.tgz", + "integrity": "sha512-4XklWsl9BdtatLoJpSjusXhpKv9YVteYKh9hPKP1Sxl+mswEFoUe0WtmtWjxEjkA51DQ2QRMCNOvKcSlCQ7ivg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^11.4.0", + "@emotion/serialize": "^1.0.2", + "@emotion/sheet": "^1.0.1", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + }, + "dependencies": { + "@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "requires": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "requires": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.1.tgz", + "integrity": "sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==" + }, + "@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + } + } + }, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "dev": true, + "requires": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + } + }, + "@emotion/sheet": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==", + "dev": true + }, + "@emotion/styled": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-10.0.27.tgz", + "integrity": "sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==", + "dev": true, + "requires": { + "@emotion/styled-base": "^10.0.27", + "babel-plugin-emotion": "^10.0.27" + } + }, + "@emotion/styled-base": { + "version": "10.0.31", + "resolved": "https://registry.npmjs.org/@emotion/styled-base/-/styled-base-10.0.31.tgz", + "integrity": "sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/is-prop-valid": "0.8.8", + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==", + "dev": true + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==", + "dev": true + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "dev": true + }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "dev": true + }, + "@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", + "dev": true + }, + "@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "dev": true, + "requires": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "dev": true, + "requires": { + "@hapi/hoek": "^8.3.0" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@itsjonq/is": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@itsjonq/is/-/is-0.0.2.tgz", + "integrity": "sha512-P0Ug+chfjCV1JV8MUxAGPz0BM76yDlR76AIfPwRZ6mAJW56k6b9j0s2cIcEsEAu0gNj/RJD1STw777AQyBN3CQ==", + "dev": true + }, + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/create-cache-key-function": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-26.6.2.tgz", + "integrity": "sha512-LgEuqU1f/7WEIPYqwLPIvvHuc1sB6gMVbT6zWhin3txYUNYK/kGQrC1F2WR4gR34YlI9bBtViTm5z98RqVZAaw==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "dev": true, + "requires": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.2", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz", + "integrity": "sha512-Fb8WxUFOBQVl+CX4MWet5o7eCc6Pj04rXIwVKZ6h1NnqTo45eOQW6aWyhG25NIODvWFwTDMwBsYxrQ3imxpetg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^5.1.2", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", + "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "@popperjs/core": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz", + "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==" + }, + "@react-native-community/cli-debugger-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-5.0.1.tgz", + "integrity": "sha512-5gGKaaXYOVE423BUqxIfvfAVSj5Cg1cU/TpGbeg/iqpy2CfqyWqJB3tTuVUbOOiOvR5wbU8tti6pIi1pchJ+oA==", + "dev": true, + "peer": true, + "requires": { + "serve-static": "^1.13.1" + } + }, + "@react-native-community/cli-hermes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-5.0.1.tgz", + "integrity": "sha512-nD+ZOFvu5MfjLB18eDJ01MNiFrzj8SDtENjGpf0ZRFndOWASDAmU54/UlU/wj8OzTToK1+S1KY7j2P2M1gleww==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-platform-android": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "chalk": "^3.0.0", + "hermes-profile-transformer": "^0.0.6", + "ip": "^1.1.5" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@react-native-community/cli-platform-android": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-5.0.1.tgz", + "integrity": "sha512-qv9GJX6BJ+Y4qvV34vgxKwwN1cnveXUdP6y2YmTW7XoAYs5YUzKqHajpY58EyucAL2y++6+573t5y4U/9IIoww==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-tools": "^5.0.1", + "chalk": "^3.0.0", + "execa": "^1.0.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "jetifier": "^1.6.2", + "lodash": "^4.17.15", + "logkitty": "^0.7.1", + "slash": "^3.0.0", + "xmldoc": "^1.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@react-native-community/cli-platform-ios": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-5.0.1.tgz", + "integrity": "sha512-Nr/edBEYJfElgBNvjDevs2BuDicsvQaM8nYkTGgp33pyuCZRBxsYxQqfsNmnLalTzcYaebjWj6AnjUSxzQBWqg==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-tools": "^5.0.1", + "chalk": "^3.0.0", + "glob": "^7.1.3", + "js-yaml": "^3.13.1", + "lodash": "^4.17.15", + "plist": "^3.0.1", + "xcode": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@react-native-community/cli-server-api": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-5.0.1.tgz", + "integrity": "sha512-OOxL+y9AOZayQzmSW+h5T54wQe+QBc/f67Y9QlWzzJhkKJdYx+S4VOooHoD5PFJzGbYaxhu2YF17p517pcEIIA==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "compression": "^1.7.1", + "connect": "^3.6.5", + "errorhandler": "^1.5.0", + "nocache": "^2.1.0", + "pretty-format": "^26.6.2", + "serve-static": "^1.13.1", + "ws": "^1.1.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "peer": true, + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + } + } + }, + "@react-native-community/cli-tools": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-5.0.1.tgz", + "integrity": "sha512-XOX5w98oSE8+KnkMZZPMRT7I5TaP8fLbDl0tCu40S7Epz+Zz924n80fmdu6nUDIfPT1nV6yH1hmHmWAWTDOR+Q==", + "dev": true, + "peer": true, + "requires": { + "chalk": "^3.0.0", + "lodash": "^4.17.15", + "mime": "^2.4.1", + "node-fetch": "^2.6.0", + "open": "^6.2.0", + "shell-quote": "1.6.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@react-native-community/cli-types": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-5.0.1.tgz", + "integrity": "sha512-BesXnuFFlU/d1F3+sHhvKt8fUxbQlAbZ3hhMEImp9A6sopl8TEtryUGJ1dbazGjRXcADutxvjwT/i3LJVTIQug==", + "dev": true, + "peer": true, + "requires": { + "ora": "^3.4.0" + } + }, + "@react-native/assets": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", + "integrity": "sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ==", + "dev": true, + "peer": true + }, + "@react-native/normalize-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-1.0.0.tgz", + "integrity": "sha512-xUNRvNmCl3UGCPbbHvfyFMnpvLPoOjDCcp5bT9m2k+TF/ZBklEQwhPZlkrxRx2NhgFh1X3a5uL7mJ7ZR+8G7Qg==", + "dev": true, + "peer": true + }, + "@react-native/polyfills": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-1.0.0.tgz", + "integrity": "sha512-0jbp4RxjYopTsIdLl+/Fy2TiwVYHy4mgeu07DG4b/LyM0OS/+lPP5c9sbnt/AMlnF6qz2JRZpPpGw1eMNS6A4w==", + "dev": true, + "peer": true + }, + "@reduxjs/toolkit": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.0.tgz", + "integrity": "sha512-eGL50G+Vj5AG5uD0lineb6rRtbs96M8+hxbcwkHpZ8LQcmt0Bm33WyBSnj5AweLkjQ7ZP+KFRDHiLMznljRQ3A==", + "requires": { + "immer": "^9.0.1", + "redux": "^4.1.0", + "redux-thunk": "^2.3.0", + "reselect": "^4.0.0" + } + }, + "@sideway/address": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", + "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "dev": true, + "peer": true, + "requires": { + "@hapi/hoek": "^9.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "dev": true, + "peer": true + } + } + }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "dev": true, + "peer": true + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true, + "peer": true + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@stylelint/postcss-css-in-js": { + "version": "0.37.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz", + "integrity": "sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==", + "dev": true, + "requires": { + "@babel/core": ">=7.9.0" + } + }, + "@stylelint/postcss-markdown": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz", + "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==", + "dev": true, + "requires": { + "remark": "^13.0.0", + "unist-util-find-all-after": "^3.0.2" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "dev": true + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "dev": true + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "dev": true + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "dev": true + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "dev": true + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "dev": true + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "dev": true + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "dev": true + }, + "@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dev": true, + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + } + }, + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dev": true, + "requires": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.6" + } + }, + "@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + } + }, + "@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + } + }, + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + } + }, + "@tannin/compile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.1.0.tgz", + "integrity": "sha512-n8m9eNDfoNZoxdvWiTfW/hSPhehzLJ3zW7f8E7oT6mCROoMNWCB4TYtv041+2FMAxweiE0j7i1jubQU4MEC/Gg==", + "dev": true, + "requires": { + "@tannin/evaluate": "^1.2.0", + "@tannin/postfix": "^1.1.0" + } + }, + "@tannin/evaluate": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@tannin/evaluate/-/evaluate-1.2.0.tgz", + "integrity": "sha512-3ioXvNowbO/wSrxsDG5DKIMxC81P0QrQTYai8zFNY+umuoHWRPbQ/TuuDEOju9E+jQDXmj6yI5GyejNuh8I+eg==", + "dev": true + }, + "@tannin/plural-forms": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/plural-forms/-/plural-forms-1.1.0.tgz", + "integrity": "sha512-xl9R2mDZO/qiHam1AgMnAES6IKIg7OBhcXqy6eDsRCdXuxAFPcjrej9HMjyCLE0DJ/8cHf0i5OQTstuBRhpbHw==", + "dev": true, + "requires": { + "@tannin/compile": "^1.1.0" + } + }, + "@tannin/postfix": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", + "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==", + "dev": true + }, + "@tippyjs/react": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.5.tgz", + "integrity": "sha512-YBLgy+1zznBNbx4JOoOdFXWMLXjBh9hLPwRtq3s8RRdrez2l3tPBRt2m2909wZd9S1KUeKjOOYYsnitccI9I3A==", + "requires": { + "tippy.js": "^6.3.1" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.14", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", + "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.0.tgz", + "integrity": "sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/cheerio": { + "version": "0.22.29", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.29.tgz", + "integrity": "sha512-rNX1PsrDPxiNiyLnRKiW2NXHJFHqx0Fl3J2WsZq0MTBspa/FgwlqhXJE2crIcc+/2IglLHtSWw7g053oUR8fOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha512-cfBw6q6tT5sa1gSPFSRKzF/xxYrrmeiut7E0TxNBObiLSBTuFEHibcfEe3waQPEDbqBsq+ql/TOniw65EyDFMA==" + }, + "@types/domutils": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@types/domutils/-/domutils-1.7.3.tgz", + "integrity": "sha512-EucnS75OnnEdypNt+UpARisSF8eJBq4no+aVOis3Bs5kyABDXm1hEDv6jJxcMJPjR+a2YCrEANaW+BMT2QVG2Q==", + "requires": { + "domhandler": "^2.4.0" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + } + } + }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@types/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-fCxmHS4ryCUCfV9+CJZY1UjkbR+6Al/EQdX5Jh03qBj9gdlPG5q+7uNoDgE/ZNXb3XNWSAQgqKIWnbRCbOyyWA==", + "requires": { + "@types/domhandler": "*", + "@types/domutils": "*", + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "@types/mdast": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", + "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, + "@types/mime-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz", + "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "@types/node": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.0.0.tgz", + "integrity": "sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/quill": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/quill/-/quill-1.3.10.tgz", + "integrity": "sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw==", + "requires": { + "parchment": "^1.1.2" + } + }, + "@types/react": { + "version": "16.14.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.10.tgz", + "integrity": "sha512-QadBsMyF6ldjEAXEhsmEW/L0uBDJT8yw7Qoe5sRnEKVrzMkiYoJwqoL5TKJOlArsn/wvIJM/XdVzkdL6+AS64Q==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + } + } + }, + "@types/react-dom": { + "version": "16.9.13", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.13.tgz", + "integrity": "sha512-34Hr3XnmUSJbUVDxIw/e7dhQn2BJZhJmlAaPyPwfTQyuVS9mV/CeyghFcXyvkJXxI7notQJz8mF8FeCVvloJrA==", + "dev": true, + "requires": { + "@types/react": "^16" + } + }, + "@types/scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==", + "dev": true + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/tapable": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", + "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==", + "dev": true + }, + "@types/uglify-js": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", + "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/unist": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==", + "dev": true + }, + "@types/webpack": { + "version": "4.41.30", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.30.tgz", + "integrity": "sha512-GUHyY+pfuQ6haAfzu4S14F+R5iGRwN6b2FRNJY7U0NilmFAqbsOfK6j1HwuLBAqwRIT+pVdNDJGJ6e8rpp0KHA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "anymatch": "^3.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/webpack-sources": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz", + "integrity": "sha512-MjM1R6iuw8XaVbtkCBz0N349cyqBjJHCbQiOeppe3VBeFvxqs74RKHAVt9LkxTnUWc7YLZOEsUfPUnmK6SBPKQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@wordpress/a11y": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-2.15.3.tgz", + "integrity": "sha512-uoCznHY3/TaNWeXutLI6juC198ykaBwZ34P51PNHHQqi3WzVoBhFx6AnAR/9Uupl3tZcekefpkVHy7AJHMAPIA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/dom-ready": "^2.13.2", + "@wordpress/i18n": "^3.20.0" + } + }, + "@wordpress/api-fetch": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-3.18.0.tgz", + "integrity": "sha512-sNT/9yOC9G/G/6QOd4b1d4tckwWS1IrLVulxRFcyhBSorB0XCu07j40nQxhrPKANgi8dLawke4hlfJdlQ9CSZQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/i18n": "^3.14.0", + "@wordpress/url": "^2.17.0" + } + }, + "@wordpress/autop": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-2.12.2.tgz", + "integrity": "sha512-c3taxJCmf1Bib33GPm7ihrgFvuzKHycdyE+XWnpa9G3JgZUJTpssFSC5rC3VZ3u+QD8agStBtlOBOyxj6pjQSA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/babel-plugin-import-jsx-pragma": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-plugin-import-jsx-pragma/-/babel-plugin-import-jsx-pragma-2.7.0.tgz", + "integrity": "sha512-yR+rSyfHKfevW84vKBOERpjEslD/o00CaYMftywVYOjsOQ8GLS6xv/VgDcpQ8JomJ9eRRInLRpeGKTM3lOa4xQ==", + "dev": true, + "requires": {} + }, + "@wordpress/babel-preset-default": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-4.20.0.tgz", + "integrity": "sha512-VKPoC5We2GNxon5umOeZ7NIP4CfP7X5gqslSnNrLW4kD1XgmbVaCs2ISFF8+mObVVb6KAzbaUjI6OWljcUb5UA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.9", + "@babel/plugin-transform-react-jsx": "^7.12.7", + "@babel/plugin-transform-runtime": "^7.12.1", + "@babel/preset-env": "^7.12.7", + "@babel/runtime": "^7.12.5", + "@wordpress/babel-plugin-import-jsx-pragma": "^2.7.0", + "@wordpress/browserslist-config": "^2.7.0", + "@wordpress/element": "^2.19.0", + "@wordpress/warning": "^1.3.0", + "core-js": "^3.6.4" + }, + "dependencies": { + "core-js": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", + "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", + "dev": true + } + } + }, + "@wordpress/base-styles": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/@wordpress/base-styles/-/base-styles-3.5.4.tgz", + "integrity": "sha512-5JfLnkQMqaefuoMkqUJMBC8m9RpXJqaaOykxuy9y3uk+s2ENbMGXSUjbzw+anO3SIRORKnHmRkgofcSoqvWV5w==", + "dev": true + }, + "@wordpress/blob": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-2.13.2.tgz", + "integrity": "sha512-Us71BMrvjiMjW9WTV1UzZbEBd+Q7W05P0WW+Tfo6qHJLBMYXPDN9dP9s6JhK6fzzL+U/PzotMJwA6P85BqL30w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/block-directory": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-directory/-/block-directory-1.19.3.tgz", + "integrity": "sha512-bqoyYqbbJUtES6pv63xaSXlX+JE3fb9ADtPtN/7XrVJzDROJmbXTnNC8Ct7YBdjuCnolgjrykF0mXSytVMGoBg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/edit-post": "^3.27.3", + "@wordpress/editor": "^9.26.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/plugins": "^2.25.3", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "requires": { + "@emotion/primitives-core": "10.0.27" + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "requires": {} + } + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "@wordpress/editor": { + "version": "9.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.26.3.tgz", + "integrity": "sha512-W3F/UnpjdEISkKqGv4NdwTgdzre3Ak3O6JGxaB4xWyFi6o4uz8ldlKpfacU9GJaX1wV1ajM8RkHGNDgyejPPdA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "rememo": "^3.0.0" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/server-side-render": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.21.3.tgz", + "integrity": "sha512-pS2+LmTQX8S61TvaC+UyXqmFnQSXcJ3wcr3RPX1EwmpvlMuXlqdW8N5Y1TWuOT1G/ZDAwvTilLAlxeAMqrYSXA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "dependencies": { + "@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "requires": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + } + } + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "requires": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/block-editor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-4.2.0.tgz", + "integrity": "sha512-qBIgbjG683Y1PK9aw5UPdiwrpRDIqePL7PHw6KsD45peTCpPJouZXcC6aQq0UV1qOuxE0Zykp33vkjsDDCjTXA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/a11y": "^2.11.0", + "@wordpress/blob": "^2.9.0", + "@wordpress/blocks": "^6.19.0", + "@wordpress/components": "^9.9.0", + "@wordpress/compose": "^3.18.0", + "@wordpress/data": "^4.21.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/dom": "^2.12.0", + "@wordpress/element": "^2.15.0", + "@wordpress/hooks": "^2.9.0", + "@wordpress/html-entities": "^2.8.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/icons": "^2.3.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/keyboard-shortcuts": "^1.8.0", + "@wordpress/keycodes": "^2.14.0", + "@wordpress/rich-text": "^3.19.0", + "@wordpress/shortcode": "^2.9.0", + "@wordpress/token-list": "^1.11.0", + "@wordpress/url": "^2.17.0", + "@wordpress/viewport": "^2.20.0", + "@wordpress/wordcount": "^2.10.0", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "react-autosize-textarea": "^3.0.2", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "refx": "^3.0.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "traverse": "^0.6.6" + } + }, + "@wordpress/block-library": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-2.29.3.tgz", + "integrity": "sha512-bOhiBmvOMmlOYuO8z+TZzhfLDGcpz1BnupW7nqkWvlJhaJ9sCbRu8Hrar+dti1tYHn+anmC3aJ0f+w0kvWPysg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/editor": "^9.26.3", + "@wordpress/element": "^2.20.3", + "@wordpress/escape-html": "^1.12.2", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/viewport": "^2.26.3", + "classnames": "^2.2.5", + "fast-average-color": "4.3.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "react-easy-crop": "^3.0.0", + "tinycolor2": "^1.4.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + } + }, + "@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "requires": { + "@emotion/primitives-core": "10.0.27" + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "requires": {} + } + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "@wordpress/editor": { + "version": "9.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.26.3.tgz", + "integrity": "sha512-W3F/UnpjdEISkKqGv4NdwTgdzre3Ak3O6JGxaB4xWyFi6o4uz8ldlKpfacU9GJaX1wV1ajM8RkHGNDgyejPPdA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "rememo": "^3.0.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/server-side-render": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.21.3.tgz", + "integrity": "sha512-pS2+LmTQX8S61TvaC+UyXqmFnQSXcJ3wcr3RPX1EwmpvlMuXlqdW8N5Y1TWuOT1G/ZDAwvTilLAlxeAMqrYSXA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "dependencies": { + "@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "requires": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + } + } + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "requires": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/block-serialization-default-parser": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-3.10.2.tgz", + "integrity": "sha512-0vyHHTcEw3ijY+stJqCf0iVR4bHpb84dbTZVaT2VSzISGzeVuAJpcYhIJMHvDTMcX1E2pgAfanIL8xloS6W7gQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/blocks": { + "version": "6.25.2", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-6.25.2.tgz", + "integrity": "sha512-dYleqt8o030Bw2dV6HKrafhcTQf/AqOAVagA9rBKRVfl6ABrm26Gb8YsgwTMMrxIIGRy9uqqqNWH1o8ae3JE2A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@wordpress/autop": "^2.11.0", + "@wordpress/blob": "^2.12.0", + "@wordpress/block-serialization-default-parser": "^3.9.0", + "@wordpress/compose": "^3.24.0", + "@wordpress/data": "^4.26.2", + "@wordpress/deprecated": "^2.11.0", + "@wordpress/dom": "^2.16.1", + "@wordpress/element": "^2.19.0", + "@wordpress/hooks": "^2.11.0", + "@wordpress/html-entities": "^2.10.0", + "@wordpress/i18n": "^3.17.0", + "@wordpress/icons": "^2.9.0", + "@wordpress/is-shallow-equal": "^3.0.0", + "@wordpress/shortcode": "^2.12.0", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/browserslist-config": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-2.7.0.tgz", + "integrity": "sha512-pB45JlfmHuEigNFZ1X+CTgIsOT3/TTb9iZxw1DHXge/7ytY8FNhtcNwTfF9IgnS6/xaFRZBqzw4DyH4sP1Lyxg==", + "dev": true + }, + "@wordpress/components": { + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-9.9.0.tgz", + "integrity": "sha512-EtDQ7sf7GuEMo+oWW7CDob0YrVynxR+t0FXGDZw3IP8msKAvVmsCD0DoSEOfX/DTWNaaHstaw6xE4+Tgk1XUWQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@emotion/core": "^10.0.22", + "@emotion/css": "^10.0.22", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.11.0", + "@wordpress/compose": "^3.18.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/dom": "^2.12.0", + "@wordpress/element": "^2.15.0", + "@wordpress/hooks": "^2.9.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/icons": "^2.3.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/keycodes": "^2.14.0", + "@wordpress/primitives": "^1.6.0", + "@wordpress/rich-text": "^3.19.0", + "@wordpress/warning": "^1.2.0", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^4.0.5", + "gradient-parser": "^0.1.5", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-spring": "^8.0.20", + "react-use-gesture": "^7.0.15", + "reakit": "^1.1.0", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.1", + "uuid": "^7.0.2" + }, + "dependencies": { + "@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "requires": { + "@emotion/primitives-core": "10.0.27" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/compose": { + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.25.3.tgz", + "integrity": "sha512-tCO2EnJCkCH548OqA0uU8V1k/1skz2QwBlHs8ZQSpimqUS4OWWsAlndCEFe4U4vDTqFt2ow7tzAir+05Cw8MAg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/priority-queue": "^1.11.2", + "clipboard": "^2.0.1", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.1.0", + "use-memo-one": "^1.1.1" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/core-data": { + "version": "2.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-2.26.3.tgz", + "integrity": "sha512-cbwOXB5AM37kBiZUUiXdSkbyJFNJ6CtkhkHkUvKoWkvvwLfGDre+BITr60NPJgw9o+MgsM/RfcBAsdRnz8/uJA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/element": "^2.20.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/url": "^2.22.2", + "equivalent-key-map": "^0.2.2", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "uuid": "^8.3.0" + }, + "dependencies": { + "@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/data": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.21.0.tgz", + "integrity": "sha512-+KU4+XKtVUqnPRBUlqD5yJXQNVoAPBZsp6KWNojd9Zhm4Sg/+8DGNo+fSpt5RQ+VJmUoRAqAk8UifQ6LZSuzQg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/compose": "^3.18.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/element": "^2.15.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/priority-queue": "^1.7.0", + "@wordpress/redux-routine": "^3.10.0", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/data-controls": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/data-controls/-/data-controls-1.21.3.tgz", + "integrity": "sha512-aLpx/HvKaxCQfWSLGIz699SB9Guyq8Yoq5XLlH8eNWnf/8HkQg8hQ6yagDY8BinV/t8HScc5A7a6n6pvZNGtjg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3" + }, + "dependencies": { + "@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/date": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.10.0.tgz", + "integrity": "sha512-MEwPn1jzYfWGD2qmQkN0dvtzyARmYHC6zh2l/wAgN7tDdqSWXnS/n0RY9RmJVTxLYyHed+MNMTJiuI35aQsXPg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "moment": "^2.22.1", + "moment-timezone": "^0.5.16" + } + }, + "@wordpress/dependency-extraction-webpack-plugin": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-2.8.0.tgz", + "integrity": "sha512-fEOsSl1kYY8gkiAe7OM9IopmSOtaAug37OQwKVeda5fK6xLsnpqprP5iwHHOApNWMEzgmVGS6/iW5IZoi7qv/A==", + "dev": true, + "requires": { + "json2php": "^0.0.4", + "webpack": "^4.8.3", + "webpack-sources": "^1.3.0" + } + }, + "@wordpress/deprecated": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.12.3.tgz", + "integrity": "sha512-qr+yDfTQfI3M4h6oY6IeHWwoHr4jxbILjSlV+Ht6Jjto9Owap6OuzSqR13Ev4xqIoG4C7b5B3gZXVfwVDae1zg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^2.12.3" + } + }, + "@wordpress/dom": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.18.0.tgz", + "integrity": "sha512-tM2WeQuSObl3nzWjUTF0/dyLnA7sdl/MXaSe32D64OF89bjSyJvjUipI7gjKzI3kJ7ddGhwcTggGvSB06MOoCQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19" + } + }, + "@wordpress/dom-ready": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-2.13.2.tgz", + "integrity": "sha512-COH7n2uZfBq4FtluSbl37N3nCEcdMXzV42ETCWKUcumiP1Zd3qnkfQKcsxTaHWY8aVt/358RvJ7ghWe3xAd+fg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/edit-post": { + "version": "3.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-3.27.3.tgz", + "integrity": "sha512-rxnW8zJrM+lK8oFyRCGykjcYUF3NcNm2+sm7po/kDT5pRB84Rbq8OxZBcIqvTbpbtjzkkBP+pwtiaTxRpQ1BPw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/block-library": "^2.29.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/editor": "^9.26.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/interface": "^2.0.2", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/plugins": "^2.25.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/url": "^2.22.2", + "@wordpress/viewport": "^2.26.3", + "@wordpress/warning": "^1.4.2", + "classnames": "^2.2.5", + "framer-motion": "^4.1.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "rememo": "^3.0.0", + "uuid": "8.3.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + }, + "@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "requires": { + "@emotion/primitives-core": "10.0.27" + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "requires": {} + } + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "@wordpress/editor": { + "version": "9.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.26.3.tgz", + "integrity": "sha512-W3F/UnpjdEISkKqGv4NdwTgdzre3Ak3O6JGxaB4xWyFi6o4uz8ldlKpfacU9GJaX1wV1ajM8RkHGNDgyejPPdA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/media-utils": "^1.20.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/reusable-blocks": "^1.2.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/server-side-render": "^1.21.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "rememo": "^3.0.0" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/server-side-render": { + "version": "1.21.3", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.21.3.tgz", + "integrity": "sha512-pS2+LmTQX8S61TvaC+UyXqmFnQSXcJ3wcr3RPX1EwmpvlMuXlqdW8N5Y1TWuOT1G/ZDAwvTilLAlxeAMqrYSXA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "dependencies": { + "@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "requires": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + } + } + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "requires": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "dev": true + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/editor": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-9.19.0.tgz", + "integrity": "sha512-rQp94jf0SPyqJVX1D8j8eCaanhsUEilctx0t3DLR3C+T2/wO0Tdk/b0Ws+F+PttNb4TUxFiN1S4QdTyB298EJQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/api-fetch": "^3.18.0", + "@wordpress/autop": "^2.9.0", + "@wordpress/blob": "^2.9.0", + "@wordpress/block-directory": "^1.12.0", + "@wordpress/block-editor": "^4.2.0", + "@wordpress/blocks": "^6.19.0", + "@wordpress/components": "^9.9.0", + "@wordpress/compose": "^3.18.0", + "@wordpress/core-data": "^2.19.0", + "@wordpress/data": "^4.21.0", + "@wordpress/data-controls": "^1.15.0", + "@wordpress/date": "^3.10.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/element": "^2.15.0", + "@wordpress/hooks": "^2.9.0", + "@wordpress/html-entities": "^2.8.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/icons": "^2.3.0", + "@wordpress/is-shallow-equal": "^2.1.0", + "@wordpress/keyboard-shortcuts": "^1.8.0", + "@wordpress/keycodes": "^2.14.0", + "@wordpress/media-utils": "^1.14.0", + "@wordpress/notices": "^2.7.0", + "@wordpress/rich-text": "^3.19.0", + "@wordpress/server-side-render": "^1.15.0", + "@wordpress/url": "^2.17.0", + "@wordpress/viewport": "^2.20.0", + "@wordpress/wordcount": "^2.10.0", + "classnames": "^2.2.5", + "lodash": "^4.17.15", + "memize": "^1.1.0", + "react-autosize-textarea": "^3.0.2", + "redux-optimist": "^1.0.0", + "refx": "^3.0.0", + "rememo": "^3.0.0" + } + }, + "@wordpress/element": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.20.3.tgz", + "integrity": "sha512-f4ZPTDf9CxiiOXiMxc4v1K7jcBMT4dsiehVOpkKzCDKboNXp4qVf8oe5PE23VGZNEjcOj5Mkg9hB57R0nqvMTw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^1.12.2", + "lodash": "^4.17.19", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "@wordpress/escape-html": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-1.12.2.tgz", + "integrity": "sha512-FabgSwznhdaUwe6hr1CsGpgxQbzqEoGevv73WIL1B9GvlZ6csRWodgHfWh4P6fYqpzxFL4WYB8wPJ1PdO32XFA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/eslint-plugin": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.1.0.tgz", + "integrity": "sha512-FTrKkpEa8vZg7/7M6GBhd1YW24hnh5rFGzKgKX4MGyB0Jw8GGSwld9J23eRbQ5JQWGFP/tmOMeiu6W1/arxy7Q==", + "dev": true, + "requires": { + "@wordpress/prettier-config": "^0.3.0", + "babel-eslint": "^10.1.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^26.0.0", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.0.5", + "requireindex": "^1.2.0" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "@wordpress/hooks": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.12.3.tgz", + "integrity": "sha512-LmKiwKldZt6UYqOxV/a6+eUFXdvALFnB/pQx3RmrMvO64sgFhfR6dhrlv+uVbuuezSuv8dce1jx8lUWAT0krMA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/html-entities": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.11.2.tgz", + "integrity": "sha512-WIdEGO9/o7tuTV3jpLHhFC/NBBnNdJeG9nRZbEyb37CL1fvqJA85hTugyDOhGzOVIAtpFTc6kr/gMJK1oTdopw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/i18n": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.20.0.tgz", + "integrity": "sha512-SIoOJFB4UrrYAScS4H91CYCLW9dX3Ghv8pBKc/yHGculb1AdGr6gRMlmJxZV62Cn3CZ4Ga86c+FfR+GiBu0JPg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^2.12.3", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + } + }, + "@wordpress/icons": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-2.10.3.tgz", + "integrity": "sha512-hVXArGOHLE5pL1G3rHNzsUEuTR4/G6lB+enKYwhYSSIqWuSbyXbZq3nvibxpepPrLy9B3d5t6aR6QUmjMVzIcQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/element": "^2.20.3", + "@wordpress/primitives": "^1.12.3" + } + }, + "@wordpress/interface": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@wordpress/interface/-/interface-2.0.2.tgz", + "integrity": "sha512-yuuVRpcCAgKVPRj/C/c7vEjj64GdVxYOL5c9H+yvjPcMEazb36lquL2Xz846dtcCBO0/8sxz3wk5NI6sSwG/tw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/plugins": "^2.25.3", + "@wordpress/viewport": "^2.26.3", + "classnames": "^2.2.5", + "lodash": "^4.17.19" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "requires": { + "@emotion/primitives-core": "10.0.27" + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "requires": {} + } + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "dependencies": { + "@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "requires": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + } + } + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/is-shallow-equal": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-2.3.0.tgz", + "integrity": "sha512-BUVCYZNDoT5fRJGoam/nI2Sn8QELu5z/pFe7UL+szFqQqNnMibdWqN/KoW/YO7WLJqqqTRhAs/Fa51g4oXRyHQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2" + } + }, + "@wordpress/jest-console": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-3.10.0.tgz", + "integrity": "sha512-iS1GSO+o7+p2PhvScOquD+IK7WqmVxa2s9uTUQyNEo06f9EUv6KNw0B1iZ00DpbgLqDCiczfdCNapC816UXIIA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "jest-matcher-utils": "^25.3.0", + "lodash": "^4.17.19" + } + }, + "@wordpress/jest-preset-default": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-6.6.0.tgz", + "integrity": "sha512-9HbKUNRMUCooXAKt+6jj5SZjDMtWoR9yMb9bJ5eCd9wUfrfQ/x2nUJK/RXiv1aI85HHmzl5KfQquZF76lYEkcw==", + "dev": true, + "requires": { + "@jest/reporters": "^25.3.0", + "@wordpress/jest-console": "^3.10.0", + "babel-jest": "^25.3.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.2", + "enzyme-to-json": "^3.4.4" + } + }, + "@wordpress/keyboard-shortcuts": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-1.14.3.tgz", + "integrity": "sha512-p7dvsaAckYRwFp5FeaeYm1IrA2KoXFq3D9mFALftdDQuLkx3XRk6f0IjgxYTePcWM5hS2Bc07UCAcNKyouFIGw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/element": "^2.20.3", + "@wordpress/keycodes": "^2.19.3", + "lodash": "^4.17.19", + "rememo": "^3.0.0" + }, + "dependencies": { + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/keycodes": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.19.3.tgz", + "integrity": "sha512-8rNdmP5M1ifTgLIL0dt/N1uTGsq/Rx1ydCXy+gg24WdxBRhyu5sudNVCtascVXo26aIfOH9OJRdqRZZTEORhog==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "lodash": "^4.17.19" + } + }, + "@wordpress/media-utils": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-1.20.3.tgz", + "integrity": "sha512-938LnUQPMhC6mKMJ4/fILC0+jseSg3b6ABdhSDkdOQdrSVKy+zabfd/w1BQ9I5MnsuviLsAyeaq5alpTmdHTwg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/api-fetch": "^4.0.0", + "@wordpress/blob": "^2.13.2", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "@wordpress/api-fetch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-4.0.0.tgz", + "integrity": "sha512-4nWH/gEpG7/VnEJbjbOWS0AWBnX5snPc3ZaKcXNZsLQlv9YgsS8idL/BNkUl9/ylZeez/UX4lJLVkOR5clvg8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^3.20.0", + "@wordpress/url": "^2.22.2" + } + } + } + }, + "@wordpress/notices": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-2.13.3.tgz", + "integrity": "sha512-lutDWWlw5r+EYSHZvJ/l4fHNharjPvF92EexoHjk+B9pVzxMtbtJv2dHeffu8BjcuYvke8OJbydlUYaa0SoeLQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/data": "^4.27.3", + "lodash": "^4.17.19" + }, + "dependencies": { + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/npm-package-json-lint-config": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-3.1.0.tgz", + "integrity": "sha512-SYRWpzpQaSsBUiRO+ssqg6AHjgCF4j2npstGTGaKdVs/B720fLFzeyONuMmo1ZtMb9v6MyEWxVz5ON6dDgmVYg==", + "dev": true, + "requires": {} + }, + "@wordpress/plugins": { + "version": "2.25.3", + "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-2.25.3.tgz", + "integrity": "sha512-I61O0cWT2nSXEuOP/C2bmgRU7Hhj6e/SXaUKJyfZd7hs16Ihp1a2NJh23jDhFS3wZ/4SY7bZgRnVNGRaBZAacw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/icons": "^2.10.3", + "lodash": "^4.17.19", + "memize": "^1.1.0" + } + }, + "@wordpress/postcss-plugins-preset": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-plugins-preset/-/postcss-plugins-preset-1.6.0.tgz", + "integrity": "sha512-WPToVlX99PiUSSxSbwAR2wJtIpbcnnRkB48sIIkDvw7rCpSWkh6OLuzfj0o5g+JCYuNL1OnQXFA8EtydNEZ9Sw==", + "dev": true, + "requires": { + "@wordpress/base-styles": "^3.3.0", + "@wordpress/postcss-themes": "^2.6.0", + "autoprefixer": "^9.8.6", + "postcss-custom-properties": "^10.0.0" + } + }, + "@wordpress/postcss-themes": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-themes/-/postcss-themes-2.6.0.tgz", + "integrity": "sha512-Q22s1KSVdtoK0Z0ND06V2QwTx/U4KvJhWFmoI8IzYW/LGlk8BkQJhHH157Y9vFliwpMlQpqfXW6/zOg2XtvHzQ==", + "dev": true, + "requires": { + "postcss": "^7.0.32" + } + }, + "@wordpress/prettier-config": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.3.0.tgz", + "integrity": "sha512-wL1ztV+so5Ttwz23lDmb8ZmREmND96sf+Dh/kbP2nyAw/DWt3K8uj31qbczVmjwfoetTiRoH9Z1CasgPs4bccg==", + "dev": true + }, + "@wordpress/primitives": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-1.12.3.tgz", + "integrity": "sha512-LIF44bVlJS7CJEVmk6TLuV6HZMdj5iwkyM8do4ukGY6qnZIzrXpBablgJeDBcyjzWrWRLn+w+tiZ/8l+2egoVA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/element": "^2.20.3", + "classnames": "^2.2.5" + } + }, + "@wordpress/priority-queue": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-1.11.2.tgz", + "integrity": "sha512-ulwmUOklY3orn1xXpcPnTyGWV5B/oycxI+cHZ6EevBVgM5sq+BW3xo0PKLR/MMm6UNBtFTu/71QAJrNZcD6V1g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/redux-routine": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-3.14.2.tgz", + "integrity": "sha512-aqi4UtvMP/+NhULxyCR8ktG0v4BJVTRcMpByAqDg7Oabq2sz2LPuShxd5UY8vxQYQY9t1uUJbslhom4ytcohWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "rungen": "^0.3.2" + } + }, + "@wordpress/reusable-blocks": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-1.2.3.tgz", + "integrity": "sha512-Q6jXwbTYg2Uu/kAdqkwosp2IYjOE9qgvkE+m4UpMtRyQDpjMunN3i3gGb/J7UexybtyjfH75VibZbYrjoUP+OQ==", + "dev": true, + "requires": { + "@wordpress/block-editor": "^5.3.3", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/core-data": "^2.26.3", + "@wordpress/data": "^4.27.3", + "@wordpress/element": "^2.20.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/url": "^2.22.2", + "lodash": "^4.17.19" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@wordpress/block-editor": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-5.3.3.tgz", + "integrity": "sha512-DRkoz9WLWNHI01+iNRowMLLPqweeVsMyFH3r6UTXvnf++X0hUAZj6KRsbmGjyg8q4HBqJR4Nf8G8h7Gnjlulvw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/a11y": "^2.15.3", + "@wordpress/blob": "^2.13.2", + "@wordpress/blocks": "^8.0.3", + "@wordpress/components": "^13.0.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/data-controls": "^1.21.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keyboard-shortcuts": "^1.14.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/notices": "^2.13.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/shortcode": "^2.13.2", + "@wordpress/token-list": "^1.15.3", + "@wordpress/url": "^2.22.2", + "@wordpress/wordcount": "^2.15.2", + "classnames": "^2.2.5", + "css-mediaquery": "^0.1.2", + "diff": "^4.0.2", + "dom-scroll-into-view": "^1.2.1", + "inherits": "^2.0.3", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-autosize-textarea": "^7.1.0", + "react-spring": "^8.0.19", + "redux-multi": "^0.1.12", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "traverse": "^0.6.6" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/blocks": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-8.0.3.tgz", + "integrity": "sha512-/zXk5gEI/TCzsVSUIht5cmO+pFC6u3mpNV8ye0Cy4CEQVtauW969GvgEM+LVf8Mk8R5NcLdLPE88n8xxsFaRoQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/autop": "^2.12.2", + "@wordpress/blob": "^2.13.2", + "@wordpress/block-serialization-default-parser": "^3.10.2", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/html-entities": "^2.11.2", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/shortcode": "^2.13.2", + "hpq": "^1.3.0", + "lodash": "^4.17.19", + "rememo": "^3.0.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/components": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-13.0.3.tgz", + "integrity": "sha512-L5cCeZvhFsLlGVxuAIFwqZotLqrwrisFjikd6a0Aj8jlTZrb9vNQ4mDXU1Zz2toHCH3NegIUAHMHOs3Jf46tWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^10.0.27", + "@emotion/core": "^10.1.1", + "@emotion/css": "^10.0.22", + "@emotion/hash": "^0.8.0", + "@emotion/native": "^10.0.22", + "@emotion/styled": "^10.0.23", + "@wordpress/a11y": "^2.15.3", + "@wordpress/compose": "^3.25.3", + "@wordpress/date": "^3.15.1", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/hooks": "^2.12.3", + "@wordpress/i18n": "^3.20.0", + "@wordpress/icons": "^2.10.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "@wordpress/primitives": "^1.12.3", + "@wordpress/rich-text": "^3.25.3", + "@wordpress/warning": "^1.4.2", + "@wp-g2/components": "^0.0.160", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "classnames": "^2.2.5", + "dom-scroll-into-view": "^1.2.1", + "downshift": "^6.0.15", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "moment": "^2.22.1", + "re-resizable": "^6.4.0", + "react-dates": "^17.1.1", + "react-resize-aware": "^3.1.0", + "react-spring": "^8.0.20", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.5", + "rememo": "^3.0.0", + "tinycolor2": "^1.4.2", + "uuid": "^8.3.0" + }, + "dependencies": { + "@emotion/native": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/native/-/native-10.0.27.tgz", + "integrity": "sha512-3qxR2XFizGfABKKbX9kAYc0PHhKuCEuyxshoq3TaMEbi9asWHdQVChg32ULpblm4XAf9oxaitAU7J9SfdwFxtw==", + "dev": true, + "requires": { + "@emotion/primitives-core": "10.0.27" + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "requires": {} + } + } + }, + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + }, + "dependencies": { + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/date": { + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.15.1.tgz", + "integrity": "sha512-SuHiObvjbegL8RpaSQ6JqFnG+QyGP+oUhx1FZDMdt1nOQA9HE7D5ssVlZFlMEAdo6iS8xMuW+4SgJN3Eo1fb4w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "moment": "^2.22.1", + "moment-timezone": "^0.5.31" + } + }, + "@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.154.tgz", + "integrity": "sha512-JSZIMxQxWjs9qJXT3q7LoD1cr8ob6dlItrYwg4i9bxLNSkKYe/DeDX4x3Nindh0Mt9mu623szIDcK3B/UBWU3Q==", + "dev": true, + "peer": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.154", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + }, + "dependencies": { + "@wp-g2/utils": { + "version": "0.0.154", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.154.tgz", + "integrity": "sha512-XedrucCzs0eA6AKGEwWiMIhJy8/xVC73jMFfZjDksdNU0bqldr6SlPxc8nDN30yqbvyYl6tBq2k5N0TiLekq1Q==", + "dev": true, + "peer": true, + "requires": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + } + } + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-autosize-textarea": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-7.1.0.tgz", + "integrity": "sha512-BHpjCDkuOlllZn3nLazY2F8oYO1tS2jHnWhcjTWQdcKiiMU6gHLNt/fzmqMSyerR0eTdKtfSIqtSeTtghNwS+g==", + "dev": true, + "requires": { + "autosize": "^4.0.2", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/rich-text": { + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.25.3.tgz", + "integrity": "sha512-FdqL1/rHTsRxZ1gW1UEWuy0URmUEqMzj5hcAbOhHFPO5m0ENrkzC9bBa195KqZBSNSmBmXnDZdHu4UJUolzcZg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "@wordpress/dom": "^2.18.0", + "@wordpress/element": "^2.20.3", + "@wordpress/escape-html": "^1.12.2", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/keycodes": "^2.19.3", + "classnames": "^2.2.5", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "rememo": "^3.0.0" + }, + "dependencies": { + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/scripts": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-12.6.1.tgz", + "integrity": "sha512-pDLtACFrP5gUA414qrE49dUrR7yMy40+//1e/5Nx821lnmDb7GAGWGo1gX4lJ2gbfSjePwmRoZe6Mph87vSnLQ==", + "dev": true, + "requires": { + "@svgr/webpack": "^5.2.0", + "@wordpress/babel-preset-default": "^4.20.0", + "@wordpress/dependency-extraction-webpack-plugin": "^2.9.0", + "@wordpress/eslint-plugin": "^7.4.0", + "@wordpress/jest-preset-default": "^6.6.0", + "@wordpress/npm-package-json-lint-config": "^3.1.0", + "@wordpress/postcss-plugins-preset": "^1.6.0", + "@wordpress/prettier-config": "^0.4.0", + "babel-jest": "^25.3.0", + "babel-loader": "^8.1.0", + "chalk": "^4.0.0", + "check-node-version": "^3.1.1", + "clean-webpack-plugin": "^3.0.0", + "cross-spawn": "^5.1.0", + "css-loader": "^3.5.2", + "dir-glob": "^3.0.1", + "eslint": "^7.1.0", + "eslint-plugin-markdown": "^1.0.2", + "ignore-emit-webpack-plugin": "^2.0.6", + "jest": "^25.3.0", + "jest-puppeteer": "^4.4.0", + "markdownlint": "^0.18.0", + "markdownlint-cli": "^0.21.0", + "mini-css-extract-plugin": "^0.9.0", + "minimist": "^1.2.0", + "npm-package-json-lint": "^5.0.0", + "postcss-loader": "^3.0.0", + "prettier": "npm:wp-prettier@2.2.1-beta-1", + "puppeteer": "npm:puppeteer-core@3.0.0", + "read-pkg-up": "^1.0.1", + "resolve-bin": "^0.4.0", + "sass": "^1.26.11", + "sass-loader": "^8.0.2", + "source-map-loader": "^0.2.4", + "stylelint": "^13.6.0", + "stylelint-config-wordpress": "^17.0.0", + "terser-webpack-plugin": "^3.0.3", + "thread-loader": "^2.1.3", + "url-loader": "^3.0.0", + "webpack": "^4.42.0", + "webpack-bundle-analyzer": "^3.6.1", + "webpack-cli": "^3.3.11", + "webpack-livereload-plugin": "^2.3.0" + }, + "dependencies": { + "@wordpress/dependency-extraction-webpack-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-2.9.0.tgz", + "integrity": "sha512-Eo8ByPd3iZ6az4UmdLD2xYLp1/7os/H80l28Y5OlS4DozkD3vcWCBReynWoBax74u3oJ9wWN5b/8oSxGwIKXYQ==", + "dev": true, + "requires": { + "json2php": "^0.0.4", + "webpack-sources": "^1.3.0" + } + }, + "@wordpress/eslint-plugin": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-7.4.0.tgz", + "integrity": "sha512-HJpDYz2drtC9rY8MiYtYJ3cimioEIweGyb3P2DQTjUZ3sC4AGg+97PhXLHUdKfsFQ31JRxyLS9kKuGdDVBwWww==", + "dev": true, + "requires": { + "@wordpress/prettier-config": "^0.4.0", + "babel-eslint": "^10.1.0", + "cosmiconfig": "^7.0.0", + "eslint-config-prettier": "^6.10.1", + "eslint-plugin-jest": "^23.8.2", + "eslint-plugin-jsdoc": "^30.2.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-react": "^7.20.0", + "eslint-plugin-react-hooks": "^4.0.4", + "globals": "^12.0.0", + "prettier": "npm:wp-prettier@2.2.1-beta-1", + "requireindex": "^1.2.0" + } + }, + "@wordpress/prettier-config": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-0.4.0.tgz", + "integrity": "sha512-7c4VeugkCwDkaHSD7ffxoP0VC5c///gCTEAT032OhI5Rik2dPxE3EkNAB2NhotGE8M4dMAg4g5Wj2OWZIn8TFw==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "cacache": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", + "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==", + "dev": true, + "requires": { + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + } + }, + "eslint-plugin-jsdoc": { + "version": "30.7.13", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.7.13.tgz", + "integrity": "sha512-YM4WIsmurrp0rHX6XiXQppqKB8Ne5ATiZLJe2+/fkp9l9ExXFr43BbAbjZaVrpCT+tuPYOZ8k1MICARHnURUNQ==", + "dev": true, + "requires": { + "comment-parser": "^0.7.6", + "debug": "^4.3.1", + "jsdoctypeparser": "^9.0.0", + "lodash": "^4.17.20", + "regextras": "^0.7.1", + "semver": "^7.3.4", + "spdx-expression-parse": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jsdoctypeparser": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz", + "integrity": "sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "requires": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "prettier": { + "version": "npm:wp-prettier@2.2.1-beta-1", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.2.1-beta-1.tgz", + "integrity": "sha512-+JHkqs9LC/JPp51yy1hzs3lQ7qeuWCwOcSzpQNeeY/G7oSpnF61vxt7hRh87zNRTr6ob2ndy0W8rVzhgrcA+Gw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tar": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + } + }, + "terser-webpack-plugin": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz", + "integrity": "sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA==", + "dev": true, + "requires": { + "cacache": "^15.0.5", + "find-cache-dir": "^3.3.1", + "jest-worker": "^26.2.1", + "p-limit": "^3.0.2", + "schema-utils": "^2.6.6", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.8.0", + "webpack-sources": "^1.4.3" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "@wordpress/server-side-render": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-1.15.0.tgz", + "integrity": "sha512-umRhtIVtWd2vqHPdDOk7qF3crld1OnOyyKrjAzTZAdlosqHsExgvcRvEri1YPs7R181wcbyNWoJdNp6ITIVsKg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@wordpress/api-fetch": "^3.18.0", + "@wordpress/components": "^9.9.0", + "@wordpress/data": "^4.21.0", + "@wordpress/deprecated": "^2.9.0", + "@wordpress/element": "^2.15.0", + "@wordpress/i18n": "^3.14.0", + "@wordpress/url": "^2.17.0", + "lodash": "^4.17.15" + } + }, + "@wordpress/shortcode": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-2.13.2.tgz", + "integrity": "sha512-n4O5O66ARGY+h1SCvt0uOIQAJ6B4hd6EjULAWRNYgQuuF9mdhcczpGvSH76BssuvLN6bJU1RjsVy7m56kqO5xw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19", + "memize": "^1.1.0" + } + }, + "@wordpress/token-list": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-1.15.3.tgz", + "integrity": "sha512-UrAnXgn05wmlS0GLPoxHZBtjjzB7TA4wX/1MV57LcLngifUKKPuNl0kMur/bQcPU+AAczbHKy/0vSvKHiZdoNg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19" + } + }, + "@wordpress/url": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.22.2.tgz", + "integrity": "sha512-aqpYKQXzyzkCOm+GzZRYlLb+wh58g0cwR1PaKAl0UXaBS4mdS+X6biMriylb4P8CVC/RR7CSw5XI20JC24KDwQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19", + "react-native-url-polyfill": "^1.1.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@react-native-community/cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-5.0.1.tgz", + "integrity": "sha512-9VzSYUYSEqxEH5Ib2UNSdn2eyPiYZ4T7Y79o9DKtRBuSaUIwbCUdZtIm+UUjBpLS1XYBkW26FqL8/UdZDmQvXw==", + "dev": true, + "peer": true, + "requires": { + "@react-native-community/cli-debugger-ui": "^5.0.1", + "@react-native-community/cli-hermes": "^5.0.1", + "@react-native-community/cli-server-api": "^5.0.1", + "@react-native-community/cli-tools": "^5.0.1", + "@react-native-community/cli-types": "^5.0.1", + "appdirsjs": "^1.2.4", + "chalk": "^3.0.0", + "command-exists": "^1.2.8", + "commander": "^2.19.0", + "cosmiconfig": "^5.1.0", + "deepmerge": "^3.2.0", + "envinfo": "^7.7.2", + "execa": "^1.0.0", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0", + "glob": "^7.1.3", + "graceful-fs": "^4.1.3", + "joi": "^17.2.1", + "leven": "^3.1.0", + "lodash": "^4.17.15", + "metro": "^0.64.0", + "metro-config": "^0.64.0", + "metro-core": "^0.64.0", + "metro-react-native-babel-transformer": "^0.64.0", + "metro-resolver": "^0.64.0", + "metro-runtime": "^0.64.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "node-stream-zip": "^1.9.1", + "ora": "^3.4.0", + "pretty-format": "^26.6.2", + "prompts": "^2.4.0", + "semver": "^6.3.0", + "serve-static": "^1.13.1", + "strip-ansi": "^5.2.0", + "sudo-prompt": "^9.0.0", + "wcwidth": "^1.0.1" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "peer": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "peer": true + } + } + }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "dev": true, + "peer": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "peer": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "peer": true, + "requires": { + "pump": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "peer": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "peer": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "peer": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "peer": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "react-native": { + "version": "0.64.2", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.64.2.tgz", + "integrity": "sha512-Ty/fFHld9DcYsFZujXYdeVjEhvSeQcwuTGXezyoOkxfiGEGrpL/uwUZvMzwShnU4zbbTKDu2PAm/uwuOittRGA==", + "dev": true, + "peer": true, + "requires": { + "@jest/create-cache-key-function": "^26.5.0", + "@react-native-community/cli": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-android": "^5.0.1-alpha.1", + "@react-native-community/cli-platform-ios": "^5.0.1-alpha.1", + "@react-native/assets": "1.0.0", + "@react-native/normalize-color": "1.0.0", + "@react-native/polyfills": "1.0.0", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "base64-js": "^1.1.2", + "event-target-shim": "^5.0.1", + "hermes-engine": "~0.7.0", + "invariant": "^2.2.4", + "jsc-android": "^245459.0.0", + "metro-babel-register": "0.64.0", + "metro-react-native-babel-transformer": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "pretty-format": "^26.5.2", + "promise": "^8.0.3", + "prop-types": "^15.7.2", + "react-devtools-core": "^4.6.0", + "react-native-codegen": "^0.0.6", + "react-refresh": "^0.4.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "^0.20.1", + "shelljs": "^0.8.4", + "stacktrace-parser": "^0.1.3", + "use-subscription": "^1.0.0", + "whatwg-fetch": "^3.0.0", + "ws": "^6.1.4" + } + }, + "react-native-url-polyfill": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-1.3.0.tgz", + "integrity": "sha512-w9JfSkvpqqlix9UjDvJjm1EjSt652zVQ6iwCIj1cVVkwXf4jQhQgTNXY6EVTwuAmUjg6BC6k9RHCBynoLFo3IQ==", + "dev": true, + "requires": { + "whatwg-url-without-unicode": "8.0.0-3" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + } + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "peer": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@wordpress/viewport": { + "version": "2.26.3", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-2.26.3.tgz", + "integrity": "sha512-CjTMPgWDmcBIa3sEd3wcIhULFsJgStiHJWEtRVHfM2fp/ZApaXrvldHJJxkoHhT5OuLet9JlNnNoD1ZvcUoE1g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/data": "^4.27.3", + "lodash": "^4.17.19" + }, + "dependencies": { + "@wordpress/data": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.27.3.tgz", + "integrity": "sha512-5763NgNV9IIa1CC3Q80dAvrH6108tJtj3IrHfUCZmUk1atSNsOMBCkLdQ7tGTTi2JFejeGEMg1LJI22JD5zM6Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^3.25.3", + "@wordpress/deprecated": "^2.12.3", + "@wordpress/element": "^2.20.3", + "@wordpress/is-shallow-equal": "^3.1.3", + "@wordpress/priority-queue": "^1.11.2", + "@wordpress/redux-routine": "^3.14.2", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "redux": "^4.0.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/is-shallow-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-3.1.3.tgz", + "integrity": "sha512-eDLhfC4aaSgklzqwc6F/F4zmJVpTVTAvhqX+q0SP/8LPcP2HuKErPHVrEc75PMWqIutja2wJg98YSNPdewrj1w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + } + } + }, + "@wordpress/warning": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-1.4.2.tgz", + "integrity": "sha512-MjrkSp6Jyfx+92AE32A83P503noUtGb6//BYUH4GiWzzzSNhDHgbQ0UcOJwJaEYK166DxSNpMk/JXc4YENi1Cw==", + "dev": true + }, + "@wordpress/wordcount": { + "version": "2.15.2", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-2.15.2.tgz", + "integrity": "sha512-y7dltZQrdtUatzpDVpZxNfXeDva4xRw30lO57MkxmeqlWOpZCrgCK7czNbebTC1CUXZ9xbKiOrNdnFgE6CnoOw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.19" + } + }, + "@wp-g2/components": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/components/-/components-0.0.160.tgz", + "integrity": "sha512-44qUtiF5Nl/srD7Vzbpcd0im/EIej04fOdDfa0lfDxXJDNK3RRtSSEwCRhok/M5SKCmvYbZKRUx2K0ugXNqK0Q==", + "dev": true, + "requires": { + "@popperjs/core": "^2.5.4", + "@wp-g2/context": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "csstype": "^3.0.3", + "downshift": "^6.0.15", + "framer-motion": "^2.1.0", + "highlight-words-core": "^1.2.2", + "history": "^4.9.0", + "lodash": "^4.17.19", + "path-to-regexp": "^1.7.0", + "react-colorful": "4.4.4", + "react-textarea-autosize": "^8.2.0", + "react-use-gesture": "^9.0.0", + "reakit": "^1.3.4" + }, + "dependencies": { + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, + "downshift": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", + "integrity": "sha512-RA1MuaNcTbt0j+sVLhSs8R2oZbBXYAtdQP/V+uHhT3DoDteZzJPjlC+LQVm9T07Wpvo84QXaZtUCePLDTDwGXg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.13.10", + "compute-scroll-into-view": "^1.0.17", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "framer-motion": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-2.9.5.tgz", + "integrity": "sha512-epSX4Co1YbDv0mjfHouuY0q361TpHE7WQzCp/xMTilxy4kXd+Z23uJzPVorfzbm1a/9q1Yu8T5bndaw65NI4Tg==", + "dev": true, + "requires": { + "@emotion/is-prop-valid": "^0.8.2", + "framesync": "^4.1.0", + "hey-listen": "^1.0.8", + "popmotion": "9.0.0-rc.20", + "style-value-types": "^3.1.9", + "tslib": "^1.10.0" + } + }, + "framesync": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-4.1.0.tgz", + "integrity": "sha512-MmgZ4wCoeVxNbx2xp5hN/zPDCbLSKiDt4BbbslK7j/pM2lg5S0vhTNv1v8BCVb99JPIo6hXBFdwzU7Q4qcAaoQ==", + "dev": true, + "requires": { + "hey-listen": "^1.0.5" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "popmotion": { + "version": "9.0.0-rc.20", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-9.0.0-rc.20.tgz", + "integrity": "sha512-f98sny03WuA+c8ckBjNNXotJD4G2utG/I3Q23NU69OEafrXtxxSukAaJBxzbtxwDvz3vtZK69pu9ojdkMoBNTg==", + "dev": true, + "requires": { + "framesync": "^4.1.0", + "hey-listen": "^1.0.8", + "style-value-types": "^3.1.9", + "tslib": "^1.10.0" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "react-use-gesture": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-9.1.3.tgz", + "integrity": "sha512-CdqA2SmS/fj3kkS2W8ZU8wjTbVBAIwDWaRprX7OKaj7HlGwBasGEFggmk5qNklknqk9zK/h8D355bEJFTpqEMg==", + "dev": true, + "requires": {} + }, + "style-value-types": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-3.2.0.tgz", + "integrity": "sha512-ih0mGsrYYmVvdDi++/66O6BaQPRPRMQHoZevNNdMMcPlP/cH28Rnfsqf1UEba/Bwfuw9T8BmIMwbGdzsPwQKrQ==", + "dev": true, + "requires": { + "hey-listen": "^1.0.8", + "tslib": "^1.10.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "@wp-g2/context": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/context/-/context-0.0.160.tgz", + "integrity": "sha512-50wSQCZkdZEexP88Ljutskn7/klT2Id1ks4GpzKDSBM8kadrfNdr2iabjgJdFLIH33S+r4dzEnzLs9SFtqUgwg==", + "dev": true, + "requires": { + "@wp-g2/create-styles": "^0.0.160", + "@wp-g2/styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160", + "lodash": "^4.17.19" + }, + "dependencies": { + "@wordpress/compose": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-4.1.2.tgz", + "integrity": "sha512-9QdldUzcsmBPB9hj3tzPMdjHktM8FNvRqXIW2Ese0MFLV8gvrRP1JQ6tstxW59AtuRgVw0nWz2fSt0nmsjnN8Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/dom": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/keycodes": "^3.1.1", + "@wordpress/priority-queue": "^2.1.1", + "clipboard": "^2.0.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.1.0", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/data": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-5.1.2.tgz", + "integrity": "sha512-QtDlGaa6SvQmll24DDvQ0CvbtD70u0XEFPfSC7gWGFO0/mpBkrmZLUCth17cC3kfdjn+5BgefKGV3/uvHjJFqA==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^4.1.2", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/priority-queue": "^2.1.1", + "@wordpress/redux-routine": "^4.1.1", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "redux": "^4.1.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/deprecated": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-3.1.1.tgz", + "integrity": "sha512-0hILlCNhf0DukFo3hMWybf9q507cxnIHhC1GQ1crZtTqzKS2QY2C1/77V4YGPdBShUj5j1dPriYCzfB5jFFgqQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1" + } + }, + "@wordpress/dom": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-3.1.1.tgz", + "integrity": "sha512-NkNkgczdQweWXXiP7uaXmuu58JsRU/WN9OTWT0pVTZumTQKsvm0Fcs55jt3NBG+X/F80DC+DPVW6+sTKv0Lqxg==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.21" + } + }, + "@wordpress/element": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-3.1.1.tgz", + "integrity": "sha512-OaqKQVEV3CCTdrx/G7fMbmxhrxjApobHUAGAVYCCR1MIqScfluYJRLWFLx8tlkl/Qm/UbF9IfdXS1lphufvYog==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^2.1.1", + "lodash": "^4.17.21", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "@wordpress/escape-html": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.1.1.tgz", + "integrity": "sha512-ZIkLxGLBhXkZu3t0yF82/brPV5aCOGCXGiH0EMV8GCohhXCNIfQwwFrZ5gd5NyNX5Q8alTLsiA84azJd+n0XiQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/hooks": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.1.1.tgz", + "integrity": "sha512-9f6H9WBwu6x/MM4ZCVLGGBuMiBcyaLapmAku5IwcWaeB2PtPduwjmk2NfGx35TuhBQD554DUg8WtTjIS019UAg==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/i18n": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.1.1.tgz", + "integrity": "sha512-Ra/hxR8WCLqDp2P49Ibr9ANhZZZ8WHnsO+4WG3XDarJ3lmzux0TcRThDKRCcYHsW3pzieARmrEa/BOlYD7ZEjQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/keycodes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-3.1.1.tgz", + "integrity": "sha512-lLJTl/PJv0F5c02YfFdzS/sspmMM3kWYcix8sXsAQgjzLkOMizSQySBa3bpT2t5auN0YQ34YVyeupVfoY+evOQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^4.1.1", + "lodash": "^4.17.21" + } + }, + "@wordpress/priority-queue": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-2.1.1.tgz", + "integrity": "sha512-e4x4B+1F2wXejqjNr6L3LTf5aO7gzy/9MWy5pUgg1rlo8z+B73OyOUmK39WOnzFtzmwTbFqgzzCwY5JqIaZe2g==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/redux-routine": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-4.1.1.tgz", + "integrity": "sha512-wjHASkmDPiOhnTZGn43kBj5RDVnSTRpj3EHL8boUGmOMiEFm/bUAfefhyvlo9ksBF4ZQm2pJjJTWtp5zE1drgg==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "rungen": "^0.3.2" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.160.tgz", + "integrity": "sha512-2/q8jcB9wIyfxkoCfNhz+9otRmAbDwfgk3nSEFhyz9ExR+OCqNUWqmITE3TZ4hYaSsV8E/gUUO4JjnPPy989bA==", + "dev": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/hash": "^0.8.0", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.160", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + } + } + } + }, + "@wp-g2/styles": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/styles/-/styles-0.0.160.tgz", + "integrity": "sha512-o91jxb0ZwEDRJrtVVjnqn3qTAXjnxZ1fX5KF3Q7oz776lMZPHsyfC0hvqnOz0w7zqaZZpdWtVQRShgrYXN6JHw==", + "dev": true, + "requires": { + "@wp-g2/create-styles": "^0.0.160", + "@wp-g2/utils": "^0.0.160" + }, + "dependencies": { + "@wordpress/compose": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-4.1.2.tgz", + "integrity": "sha512-9QdldUzcsmBPB9hj3tzPMdjHktM8FNvRqXIW2Ese0MFLV8gvrRP1JQ6tstxW59AtuRgVw0nWz2fSt0nmsjnN8Q==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/dom": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/keycodes": "^3.1.1", + "@wordpress/priority-queue": "^2.1.1", + "clipboard": "^2.0.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "mousetrap": "^1.6.5", + "react-resize-aware": "^3.1.0", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/data": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-5.1.2.tgz", + "integrity": "sha512-QtDlGaa6SvQmll24DDvQ0CvbtD70u0XEFPfSC7gWGFO0/mpBkrmZLUCth17cC3kfdjn+5BgefKGV3/uvHjJFqA==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/compose": "^4.1.2", + "@wordpress/deprecated": "^3.1.1", + "@wordpress/element": "^3.1.1", + "@wordpress/is-shallow-equal": "^4.1.1", + "@wordpress/priority-queue": "^2.1.1", + "@wordpress/redux-routine": "^4.1.1", + "equivalent-key-map": "^0.2.2", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "redux": "^4.1.0", + "turbo-combine-reducers": "^1.0.2", + "use-memo-one": "^1.1.1" + } + }, + "@wordpress/deprecated": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-3.1.1.tgz", + "integrity": "sha512-0hILlCNhf0DukFo3hMWybf9q507cxnIHhC1GQ1crZtTqzKS2QY2C1/77V4YGPdBShUj5j1dPriYCzfB5jFFgqQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1" + } + }, + "@wordpress/dom": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-3.1.1.tgz", + "integrity": "sha512-NkNkgczdQweWXXiP7uaXmuu58JsRU/WN9OTWT0pVTZumTQKsvm0Fcs55jt3NBG+X/F80DC+DPVW6+sTKv0Lqxg==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "lodash": "^4.17.21" + } + }, + "@wordpress/element": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-3.1.1.tgz", + "integrity": "sha512-OaqKQVEV3CCTdrx/G7fMbmxhrxjApobHUAGAVYCCR1MIqScfluYJRLWFLx8tlkl/Qm/UbF9IfdXS1lphufvYog==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@types/react": "^16.9.0", + "@types/react-dom": "^16.9.0", + "@wordpress/escape-html": "^2.1.1", + "lodash": "^4.17.21", + "react": "^16.13.1", + "react-dom": "^16.13.1" + } + }, + "@wordpress/escape-html": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.1.1.tgz", + "integrity": "sha512-ZIkLxGLBhXkZu3t0yF82/brPV5aCOGCXGiH0EMV8GCohhXCNIfQwwFrZ5gd5NyNX5Q8alTLsiA84azJd+n0XiQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/hooks": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.1.1.tgz", + "integrity": "sha512-9f6H9WBwu6x/MM4ZCVLGGBuMiBcyaLapmAku5IwcWaeB2PtPduwjmk2NfGx35TuhBQD554DUg8WtTjIS019UAg==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/i18n": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.1.1.tgz", + "integrity": "sha512-Ra/hxR8WCLqDp2P49Ibr9ANhZZZ8WHnsO+4WG3XDarJ3lmzux0TcRThDKRCcYHsW3pzieARmrEa/BOlYD7ZEjQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/hooks": "^3.1.1", + "gettext-parser": "^1.3.1", + "lodash": "^4.17.21", + "memize": "^1.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + } + }, + "@wordpress/is-shallow-equal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-4.1.1.tgz", + "integrity": "sha512-Bc782s4Kte98RKLtuDXOaUBpyJWUgN4XZJevEoFasKQTpABZUDF+Y2C0/dhnlJeYF5TDEd8TQgFfpF5csxEUNw==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/keycodes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-3.1.1.tgz", + "integrity": "sha512-lLJTl/PJv0F5c02YfFdzS/sspmMM3kWYcix8sXsAQgjzLkOMizSQySBa3bpT2t5auN0YQ34YVyeupVfoY+evOQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "@wordpress/i18n": "^4.1.1", + "lodash": "^4.17.21" + } + }, + "@wordpress/priority-queue": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-2.1.1.tgz", + "integrity": "sha512-e4x4B+1F2wXejqjNr6L3LTf5aO7gzy/9MWy5pUgg1rlo8z+B73OyOUmK39WOnzFtzmwTbFqgzzCwY5JqIaZe2g==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@wordpress/redux-routine": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-4.1.1.tgz", + "integrity": "sha512-wjHASkmDPiOhnTZGn43kBj5RDVnSTRpj3EHL8boUGmOMiEFm/bUAfefhyvlo9ksBF4ZQm2pJjJTWtp5zE1drgg==", + "dev": true, + "peer": true, + "requires": { + "@babel/runtime": "^7.13.10", + "is-promise": "^4.0.0", + "lodash": "^4.17.21", + "rungen": "^0.3.2" + } + }, + "@wp-g2/create-styles": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/create-styles/-/create-styles-0.0.160.tgz", + "integrity": "sha512-2/q8jcB9wIyfxkoCfNhz+9otRmAbDwfgk3nSEFhyz9ExR+OCqNUWqmITE3TZ4hYaSsV8E/gUUO4JjnPPy989bA==", + "dev": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/hash": "^0.8.0", + "@emotion/is-prop-valid": "^0.8.8", + "@wp-g2/utils": "^0.0.160", + "create-emotion": "^10.0.27", + "emotion": "^10.0.27", + "emotion-theming": "^10.0.27", + "lodash": "^4.17.19", + "mitt": "^2.1.0", + "rtlcss": "^2.6.2", + "styled-griddie": "^0.1.3" + } + } + } + }, + "@wp-g2/utils": { + "version": "0.0.160", + "resolved": "https://registry.npmjs.org/@wp-g2/utils/-/utils-0.0.160.tgz", + "integrity": "sha512-4FhezjKyeYVb+3PZahW1kmqXpCvVvuJM97EcGqkKf+u4Qf66J3n1niHgfnRbn8aNydYK6EFze+6/UL48U35z1w==", + "dev": true, + "requires": { + "copy-to-clipboard": "^3.3.1", + "create-emotion": "^10.0.27", + "deepmerge": "^4.2.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2", + "json2mq": "^0.2.0", + "lodash": "^4.17.19", + "memize": "^1.1.0", + "react-merge-refs": "^1.1.0", + "react-resize-aware": "^3.1.0", + "tinycolor2": "^1.4.2", + "use-enhanced-state": "^0.0.13", + "use-isomorphic-layout-effect": "^1.0.0" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "peer": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "absolute-path": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", + "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=", + "dev": true, + "peer": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + } + } + }, + "airbnb-prop-types": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz", + "integrity": "sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg==", + "dev": true, + "requires": { + "array.prototype.find": "^2.1.1", + "function.prototype.name": "^1.1.2", + "is-regex": "^1.1.0", + "object-is": "^1.1.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2", + "prop-types": "^15.7.2", + "prop-types-exact": "^1.2.0", + "react-is": "^16.13.1" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "requires": {} + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", + "dev": true, + "peer": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-fragments": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", + "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", + "dev": true, + "peer": true, + "requires": { + "colorette": "^1.0.7", + "slice-ansi": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "peer": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "appdirsjs": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.5.tgz", + "integrity": "sha512-UyaAyzj+7XLoKhbXJi4zoAw8IDXCiLNCKfQEiuCsCCTkDmiG1vpCliQn/MoUvO3DZqCN1i6gOahokcFtNSIrVA==", + "dev": true, + "peer": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true, + "peer": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true, + "peer": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true, + "peer": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "array.prototype.filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.0.tgz", + "integrity": "sha512-TfO1gz+tLm+Bswq0FBOXPqAchtCr2Rn48T8dLJoRFl8NoEosjZmzptmuo1X8aZBzZcqsR1W8U761tjACJtngTQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.5" + } + }, + "array.prototype.find": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.1.1.tgz", + "integrity": "sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.4" + } + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "peer": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", + "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", + "dev": true, + "peer": true, + "requires": { + "tslib": "^2.0.1" + } + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true, + "optional": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + } + }, + "autosize": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", + "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "axe-core": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz", + "integrity": "sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ==", + "dev": true + }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, + "babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", + "dev": true, + "peer": true, + "requires": {} + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "babel-loader": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", + "dev": true, + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^1.4.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-emotion": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz", + "integrity": "sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + } + } + }, + "babel-plugin-module-resolver": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", + "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", + "dev": true, + "requires": { + "find-babel-config": "^1.1.0", + "glob": "^7.1.2", + "pkg-up": "^2.0.0", + "reselect": "^3.0.1", + "resolve": "^1.4.0" + }, + "dependencies": { + "reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=", + "dev": true + } + } + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz", + "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.11", + "@babel/helper-define-polyfill-provider": "^0.2.2", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz", + "integrity": "sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2", + "core-js-compat": "^3.14.0" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz", + "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.2.2" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", + "dev": true, + "peer": true + }, + "babel-plugin-transform-html-import-to-string": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-html-import-to-string/-/babel-plugin-transform-html-import-to-string-0.0.1.tgz", + "integrity": "sha1-lJFSUV2q12TPVcUasXh9IG3s+J0=", + "dev": true + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", + "dev": true + }, + "babel-preset-current-node-syntax": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", + "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-fbjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz", + "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==", + "dev": true, + "peer": true, + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "backbone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.3.3.tgz", + "integrity": "sha1-TMgOp8sWMaxHSInOQPL4vGg7KZk=", + "dev": true, + "requires": { + "underscore": ">=1.8.3" + } + }, + "backbone.marionette": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/backbone.marionette/-/backbone.marionette-3.5.1.tgz", + "integrity": "sha1-yyLKaM+YbLzan9tUT7eF3Wb48kg=", + "dev": true, + "requires": { + "backbone.radio": "^2.0.0" + } + }, + "backbone.radio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/backbone.radio/-/backbone.radio-2.0.0.tgz", + "integrity": "sha1-u+hnKzc+MT+Z820vvPWD/nfQT0I=", + "dev": true, + "requires": {} + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true, + "peer": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "dev": true, + "requires": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + }, + "dependencies": { + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", + "dev": true + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "dev": true, + "requires": { + "bytes": "1", + "string_decoder": "0.10" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "body-scroll-lock": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz", + "integrity": "sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==", + "dev": true + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "bplist-creator": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", + "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", + "dev": true, + "peer": true, + "requires": { + "stream-buffers": "~2.2.0" + } + }, + "bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "peer": true, + "requires": { + "big-integer": "^1.6.44" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "brcast": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brcast/-/brcast-2.0.2.tgz", + "integrity": "sha512-Tfn5JSE7hrUlFcOoaLzVvkbgIemIorMIyoMr3TgvszWW7jFt2C9PdeMLtysYD9RU0MmU17b69+XJG1eRY2OBRg==", + "dev": true + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "devOptional": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001242", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz", + "integrity": "sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug==", + "devOptional": true + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true + }, + "check-node-version": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/check-node-version/-/check-node-version-3.3.0.tgz", + "integrity": "sha512-OAtp7prQf+8YYKn2UB/fK1Ppb9OT+apW56atoKYUvucYLPq69VozOY0B295okBwCKymk2cictrS3qsdcZwyfzw==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "map-values": "^1.0.1", + "minimist": "^1.2.0", + "object-filter": "^1.0.2", + "object.assign": "^4.0.4", + "run-parallel": "^1.1.4", + "semver": "^5.0.3" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, + "cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "requires": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + } + }, + "cheerio-select": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", + "integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "css-what": "^5.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0", + "domutils": "^2.7.0" + } + }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json-es6": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/circular-json-es6/-/circular-json-es6-2.0.2.tgz", + "integrity": "sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + } + }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "clean-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", + "dev": true, + "requires": { + "@types/webpack": "^4.4.31", + "del": "^4.1.1" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "peer": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "dev": true, + "peer": true + }, + "clipboard": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", + "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", + "dev": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "requires": { + "is-regexp": "^2.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "codemirror": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.0.tgz", + "integrity": "sha512-Xnl3304iCc8nyVZuRkzDVVwc794uc9QNX0UcPGeNic1fbzkSrO4l4GVXho9tRNKBgPYZXgocUqXyfIv3BILhCQ==" + }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "devOptional": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true, + "peer": true + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "comment-parser": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-0.7.6.tgz", + "integrity": "sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "peer": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "peer": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "peer": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + } + } + }, + "compute-scroll-into-view": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz", + "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==", + "dev": true + }, + "computed-style": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz", + "integrity": "sha1-fzRP2FhLLkJb7cpKGvwOMAuwXXQ=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "peer": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + } + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "consolidated-events": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/consolidated-events/-/consolidated-events-2.0.2.tgz", + "integrity": "sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "devOptional": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "dev": true, + "requires": { + "toggle-selection": "^1.0.6" + } + }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "dev": true + }, + "core-js-compat": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz", + "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-js-pure": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.2.tgz", + "integrity": "sha512-D42L7RYh1J2grW8ttxoY1+17Y4wXZeKe7uyplAI3FkNQyI5OgBIAjUfFiTPfL1rs0qLpxaabITNbjKl1Sp82tA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "create-emotion": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.27.tgz", + "integrity": "sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==", + "dev": true, + "requires": { + "@emotion/cache": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "dev": true + }, + "css-loader": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz", + "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==", + "dev": true, + "requires": { + "camelcase": "^5.2.0", + "icss-utils": "^4.1.0", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.14", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.6", + "postcss-modules-scope": "^2.1.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "css-mediaquery": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", + "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=", + "dev": true + }, + "css-select": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz", + "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^5.0.0", + "domhandler": "^4.2.0", + "domutils": "^2.6.0", + "nth-check": "^2.0.0" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "dev": true, + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-what": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz", + "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + }, + "dependencies": { + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "csstype": { + "version": "2.6.17", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", + "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cwd": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", + "integrity": "sha1-FyQAaUBXwioTsM8WFix+S3p/5Wc=", + "dev": true, + "requires": { + "find-pkg": "^0.1.2", + "fs-exists-sync": "^0.1.0" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "damerau-levenshtein": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", + "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "dayjs": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.5.tgz", + "integrity": "sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g==", + "dev": true, + "peer": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "devOptional": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + } + }, + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-equal-ident": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz", + "integrity": "sha1-BvS4nlNxDNbOpKd4HHqVZkLejck=", + "dev": true, + "requires": { + "lodash.isequal": "^3.0" + }, + "dependencies": { + "lodash.isequal": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz", + "integrity": "sha1-HDXrO27wzR/1F0Pj6jz3/f/ay2Q=", + "dev": true, + "requires": { + "lodash._baseisequal": "^3.0.0", + "lodash._bindcallback": "^3.0.0" + } + } + } + }, + "deep-extend": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "dev": true + }, + "deep-freeze": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", + "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "peer": true, + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "peer": true + } + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", + "dev": true, + "peer": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "direction": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/direction/-/direction-1.0.4.tgz", + "integrity": "sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==", + "dev": true + }, + "discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "document.contains": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/document.contains/-/document.contains-1.0.2.tgz", + "integrity": "sha512-YcvYFs15mX8m3AO1QNQy3BlIpSMfNRj3Ujk2BEJxsZG+HZf7/hZ6jr7mDpXrF8q+ff95Vef5yjhiZxm8CGJr6Q==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + } + } + }, + "dom-scroll-into-view": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", + "integrity": "sha1-6PNnMt0ImwIBqI14Fdw/iObWbH4=", + "dev": true + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, + "domhandler": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", + "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.7.0.tgz", + "integrity": "sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "downshift": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-4.1.0.tgz", + "integrity": "sha512-GODZOZC65a8n8YD/S/87hR2t5PJfqZ7+lwEBJsNi/AJnhImfle+CFD/ZPde4l+nB8QNHfn0GbE1W9djEFOj1yQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "compute-scroll-into-view": "^1.0.9", + "prop-types": "^15.7.2", + "react-is": "^16.9.0" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.766", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.766.tgz", + "integrity": "sha512-u2quJ862q9reRKh/je3GXis3w38+RoXH1J9N3XjtsS6NzmUAosNsyZgUVFZPN/ZlJ3v6T0rTyZR3q/J5c6Sy5w==", + "devOptional": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "emotion": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.27.tgz", + "integrity": "sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==", + "dev": true, + "requires": { + "babel-plugin-emotion": "^10.0.27", + "create-emotion": "^10.0.27" + } + }, + "emotion-theming": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/emotion-theming/-/emotion-theming-10.0.27.tgz", + "integrity": "sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/weak-memoize": "0.2.5", + "hoist-non-react-statics": "^3.3.0" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "peer": true + }, + "enzyme": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", + "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==", + "dev": true, + "requires": { + "array.prototype.flat": "^1.2.3", + "cheerio": "^1.0.0-rc.3", + "enzyme-shallow-equal": "^1.0.1", + "function.prototype.name": "^1.1.2", + "has": "^1.0.3", + "html-element-map": "^1.2.0", + "is-boolean-object": "^1.0.1", + "is-callable": "^1.1.5", + "is-number-object": "^1.0.4", + "is-regex": "^1.0.5", + "is-string": "^1.0.5", + "is-subset": "^0.1.1", + "lodash.escape": "^4.0.1", + "lodash.isequal": "^4.5.0", + "object-inspect": "^1.7.0", + "object-is": "^1.0.2", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1", + "object.values": "^1.1.1", + "raf": "^3.4.1", + "rst-selector-parser": "^2.2.3", + "string.prototype.trim": "^1.2.1" + } + }, + "enzyme-adapter-react-16": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz", + "integrity": "sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==", + "dev": true, + "requires": { + "enzyme-adapter-utils": "^1.14.0", + "enzyme-shallow-equal": "^1.0.4", + "has": "^1.0.3", + "object.assign": "^4.1.2", + "object.values": "^1.1.2", + "prop-types": "^15.7.2", + "react-is": "^16.13.1", + "react-test-renderer": "^16.0.0-0", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "enzyme-adapter-utils": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz", + "integrity": "sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==", + "dev": true, + "requires": { + "airbnb-prop-types": "^2.16.0", + "function.prototype.name": "^1.1.3", + "has": "^1.0.3", + "object.assign": "^4.1.2", + "object.fromentries": "^2.0.3", + "prop-types": "^15.7.2", + "semver": "^5.7.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "enzyme-matchers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz", + "integrity": "sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==", + "dev": true, + "requires": { + "circular-json-es6": "^2.0.1", + "deep-equal-ident": "^1.1.1" + } + }, + "enzyme-shallow-equal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", + "integrity": "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==", + "dev": true, + "requires": { + "has": "^1.0.3", + "object-is": "^1.1.2" + } + }, + "enzyme-to-json": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.6.2.tgz", + "integrity": "sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg==", + "dev": true, + "requires": { + "@types/cheerio": "^0.22.22", + "lodash": "^4.17.21", + "react-is": "^16.12.0" + } + }, + "equivalent-key-map": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/equivalent-key-map/-/equivalent-key-map-0.2.2.tgz", + "integrity": "sha512-xvHeyCDbZzkpN4VHQj/n+j2lOwL0VWszG30X4cOrc9Y7Tuo2qCdZK/0AMod23Z5dCtNUbaju6p0rwOhHUk05ew==", + "dev": true + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dev": true, + "requires": { + "string-template": "~0.2.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "dev": true, + "peer": true, + "requires": { + "stackframe": "^1.1.1" + } + }, + "errorhandler": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", + "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", + "dev": true, + "peer": true, + "requires": { + "accepts": "~1.3.7", + "escape-html": "~1.0.3" + } + }, + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "devOptional": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-plugin-jest": { + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^2.5.0" + } + }, + "eslint-plugin-jsdoc": { + "version": "26.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz", + "integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==", + "dev": true, + "requires": { + "comment-parser": "^0.7.4", + "debug": "^4.1.1", + "jsdoctypeparser": "^6.1.0", + "lodash": "^4.17.15", + "regextras": "^0.7.1", + "semver": "^6.3.0", + "spdx-expression-parse": "^3.0.1" + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", + "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.0.2", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^3.1.0", + "language-tags": "^1.0.5" + } + }, + "eslint-plugin-markdown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-1.0.2.tgz", + "integrity": "sha512-BfvXKsO0K+zvdarNc801jsE/NTLmig4oKhZ1U3aSUgTf2dB/US5+CrfGxMsCK2Ki1vS1R3HPok+uYpufFndhzw==", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "remark-parse": "^5.0.0", + "unified": "^6.1.2" + } + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz", + "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==", + "dev": true, + "requires": { + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.0.4", + "object.entries": "^1.1.4", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.4", + "prop-types": "^15.7.2", + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.5" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "peer": true + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", + "dev": true + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "requires": { + "clone-regexp": "^2.1.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "expect-puppeteer": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-4.4.0.tgz", + "integrity": "sha512-6Ey4Xy2xvmuQu7z7YQtMsaMV0EHJRpVxIDOd5GRrm04/I3nkTKIutELfECsLp6le+b3SSa3cXhPiw6PgqzxYWA==", + "dev": true + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "faker": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz", + "integrity": "sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=" + }, + "fast-average-color": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-4.3.0.tgz", + "integrity": "sha512-k8FXd6+JeXoItmdNqB3hMwFgArryjdYBLuzEM8fRY/oztd/051yhSHU6GUrMOfIQU9dDHyFDcIAkGrQKlYtpDA==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.6.tgz", + "integrity": "sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fast-memoize": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "dev": true, + "requires": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-file-up": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz", + "integrity": "sha1-z2gJG8+fMApA2kEbN9pczlovvqA=", + "dev": true, + "requires": { + "fs-exists-sync": "^0.1.0", + "resolve-dir": "^0.1.0" + } + }, + "find-parent-dir": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.1.tgz", + "integrity": "sha512-o4UcykWV/XN9wm+jMEtWLPlV8RXCZnMhQI6F6OdHeSez7iiJWePw8ijOlskJZMsaQoGR/b7dH6lO02HhaTN7+A==", + "dev": true + }, + "find-pkg": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-0.1.2.tgz", + "integrity": "sha1-G9wiwG42NlUy4qJIBGhUuXiNpVc=", + "dev": true, + "requires": { + "find-file-up": "^0.1.2" + } + }, + "find-process": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.4.tgz", + "integrity": "sha512-rRSuT1LE4b+BFK588D2V8/VG9liW0Ark1XJgroxZXI0LtwmQJOb490DvDYvbm+Hek9ETFzTutGfJ90gumITPhQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "debug": "^4.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "dependencies": { + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + } + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.0.tgz", + "integrity": "sha512-XprP7lDrVT+kE2c2YlfiV+IfS9zxukiIOvNamPNsImNhXadSsQEbosItdL9bUQlCZXR13SvPk20BjWSWLA7m4A==", + "dev": true + }, + "flow-parser": { + "version": "0.121.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", + "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==", + "dev": true, + "peer": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "framer-motion": { + "version": "4.1.17", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-4.1.17.tgz", + "integrity": "sha512-thx1wvKzblzbs0XaK2X0G1JuwIdARcoNOW7VVwjO8BUltzXPyONGAElLu6CiCScsOQRI7FIk/45YTFtJw5Yozw==", + "dev": true, + "requires": { + "@emotion/is-prop-valid": "^0.8.2", + "framesync": "5.3.0", + "hey-listen": "^1.0.8", + "popmotion": "9.3.6", + "style-value-types": "4.1.4", + "tslib": "^2.1.0" + } + }, + "framesync": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz", + "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.4.tgz", + "integrity": "sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "functions-have-names": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz", + "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "devOptional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getobject": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.1.tgz", + "integrity": "sha512-tj18lLe+917AACr6BdVoUuHnBPTVd9BEJp1vxnMZ58ztNvuxz9Ufa+wf3g37tlGITH35jggwZ2d9lcgHJJgXfQ==", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "gettext-parser": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz", + "integrity": "sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA==", + "dev": true, + "requires": { + "encoding": "^0.1.12", + "safe-buffer": "^5.1.1" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-cache": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/global-cache/-/global-cache-1.2.1.tgz", + "integrity": "sha512-EOeUaup5DgWKlCMhA9YFqNRIlZwoxt731jCh47WBV9fQqHgXhr3Fa55hfgIUqilIcPsfdNKN7LHjrNY+Km40KA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "is-symbol": "^1.0.1" + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true, + "requires": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "dependencies": { + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + } + } + }, + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "dependencies": { + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "devOptional": true + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "dev": true, + "requires": { + "delegate": "^3.1.2" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "gradient-parser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/gradient-parser/-/gradient-parser-0.1.5.tgz", + "integrity": "sha1-DH4heVWeXOfY1x9EI6+TcQCyJIw=", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "grunt": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.4.1.tgz", + "integrity": "sha512-ZXIYXTsAVrA7sM+jZxjQdrBOAg7DyMUplOMhTaspMRExei+fD0BTwdWXnn0W5SXqhb/Q/nlkzXclSi3IH55PIA==", + "dev": true, + "requires": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.2", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "requires": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, + "grunt-exec": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-3.0.0.tgz", + "integrity": "sha512-cgAlreXf3muSYS5LzW0Cc4xHK03BjFOYk0MqCQ/MZ3k1Xz2GU7D+IAJg4UKicxpO+XdONJdx/NJ6kpy2wI+uHg==", + "dev": true, + "requires": {} + }, + "grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true + }, + "grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "requires": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "requires": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "grunt-text-replace": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/grunt-text-replace/-/grunt-text-replace-0.4.0.tgz", + "integrity": "sha1-252c5Z4v5J2id+nbwZXD4Rz7FsI=", + "dev": true + }, + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hermes-engine": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.7.2.tgz", + "integrity": "sha512-E2DkRaO97gwL98LPhgfkMqhHiNsrAjIfEk3wWYn2Y31xdkdWn0572H7RnVcGujMJVqZNJvtknxlpsUb8Wzc3KA==", + "dev": true, + "peer": true + }, + "hermes-profile-transformer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz", + "integrity": "sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==", + "dev": true, + "peer": true, + "requires": { + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "peer": true + } + } + }, + "hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "dev": true + }, + "highlight-words-core": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words-core/-/highlight-words-core-1.2.2.tgz", + "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg==", + "dev": true + }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dev": true, + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "hpq": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/hpq/-/hpq-1.3.0.tgz", + "integrity": "sha512-fvYTvdCFOWQupGxqkahrkA+ERBuMdzkxwtUdKrxR6rmMd4Pfl+iZ1QiQYoaZ0B/v0y59MOMnz3XFUWbT50/NWA==", + "dev": true + }, + "html-dom-parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-0.3.0.tgz", + "integrity": "sha512-WDEYpO5gHGKuJbf0rwndGq7yUHJ4xboNj9l9mRGw5RsKFc3jfRozCsGAMu69zXxt4Ol8UkbqubKxu8ys0BLKtA==", + "requires": { + "@types/domhandler": "2.4.1", + "domhandler": "2.4.2", + "htmlparser2": "3.10.1" + }, + "dependencies": { + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "html-element-map": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz", + "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==", + "dev": true, + "requires": { + "array.prototype.filter": "^1.0.0", + "call-bind": "^1.0.2" + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "html-react-parser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-0.13.0.tgz", + "integrity": "sha512-hU94hE2p9xhMM61EOoiY3Kr+DfzH/uY7hGeVXQpGFRjgbYRUeyuSKORDNMIaY8IAcuHQ6Ov9pJ3x94Wvso/OmQ==", + "requires": { + "@types/htmlparser2": "3.10.1", + "html-dom-parser": "0.3.0", + "react-property": "1.0.1", + "style-to-object": "0.3.0" + } + }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "dev": true + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "dev": true + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-emit-webpack-plugin": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/ignore-emit-webpack-plugin/-/ignore-emit-webpack-plugin-2.0.6.tgz", + "integrity": "sha512-/zC18RWCC2wz4ZwnS4UoujGWzvSKy28DLjtE+jrGBOXej6YdmityhBDzE8E0NlktEqi4tgdNbydX8B6G4haHSQ==", + "dev": true + }, + "image-size": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", + "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", + "dev": true, + "peer": true + }, + "immer": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.5.tgz", + "integrity": "sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ==" + }, + "immutability-helper": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-3.1.1.tgz", + "integrity": "sha512-Q0QaXjPjwIju/28TsugCHNEASwoCcJSyJV3uO1sOIQGI0jKgm9f41Lvz0DZj3n46cNCyAZTsEYoY4C2bVRUzyQ==" + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz", + "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "install": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/install/-/install-0.10.4.tgz", + "integrity": "sha512-+IRyOastuPmLVx9zlVXJoKErSqz1Ma5at9A7S8yfsj3W+Kg95faPoh3bPDtMrZ/grz4PRmXzrswmlzfLlYyLOw==", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true, + "peer": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "irregular-plurals": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", + "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-touch-device": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-touch-device/-/is-touch-device-1.0.1.tgz", + "integrity": "sha512-LAYzo9kMT1b2p19L/1ATGt2XcSilnzNlyvq6c0pbPRVisLbAPpLqr53tIJS00kvrTkj0HtR8U7+u8X0yR8lPSw==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz", + "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==", + "dev": true, + "requires": { + "@jest/core": "^25.5.4", + "import-local": "^3.0.2", + "jest-cli": "^25.5.4" + } + }, + "jest-changed-files": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + } + }, + "jest-cli": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", + "dev": true, + "requires": { + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "prompts": "^2.0.1", + "realpath-native": "^2.0.0", + "yargs": "^15.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-dev-server": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-4.4.0.tgz", + "integrity": "sha512-STEHJ3iPSC8HbrQ3TME0ozGX2KT28lbT4XopPxUm2WimsX3fcB3YOptRh12YphQisMhfqNSNTZUmWyT3HEXS2A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "cwd": "^0.10.0", + "find-process": "^1.4.3", + "prompts": "^2.3.0", + "spawnd": "^4.4.0", + "tree-kill": "^1.2.2", + "wait-on": "^3.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + }, + "dependencies": { + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-environment-puppeteer": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-puppeteer/-/jest-environment-puppeteer-4.4.0.tgz", + "integrity": "sha512-iV8S8+6qkdTM6OBR/M9gKywEk8GDSOe05hspCs5D8qKSwtmlUfdtHfB4cakdc68lC6YfK3AUsLirpfgodCHjzQ==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "cwd": "^0.10.0", + "jest-dev-server": "^4.4.0", + "merge-deep": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "dev": true, + "requires": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} + }, + "jest-puppeteer": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/jest-puppeteer/-/jest-puppeteer-4.4.0.tgz", + "integrity": "sha512-ZaiCTlPZ07B9HW0erAWNX6cyzBqbXMM7d2ugai4epBDKpKvRDpItlRQC6XjERoJELKZsPziFGS0OhhUvTvQAXA==", + "dev": true, + "requires": { + "expect-puppeteer": "^4.4.0", + "jest-environment-puppeteer": "^4.4.0" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "jest-resolve-dependencies": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-snapshot": "^25.5.1" + } + }, + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watcher": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", + "dev": true, + "requires": { + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "string-length": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jetifier": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.8.tgz", + "integrity": "sha512-3Zi16h6L5tXDRQJTb221cnRoVG9/9OvreLdLU2/ZjRv/GILL+2Cemt0IKvkowwkDpvouAU1DQPOJ7qaiHeIdrw==", + "dev": true, + "peer": true + }, + "joi": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.0.tgz", + "integrity": "sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==", + "dev": true, + "peer": true, + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + }, + "dependencies": { + "@hapi/hoek": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", + "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==", + "dev": true, + "peer": true + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, + "peer": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + } + } + }, + "jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", + "dev": true + }, + "js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsc-android": { + "version": "245459.0.0", + "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-245459.0.0.tgz", + "integrity": "sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==", + "dev": true, + "peer": true + }, + "jscodeshift": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.11.0.tgz", + "integrity": "sha512-SdRK2C7jjs4k/kT2mwtO07KJN9RnjxtKn03d9JVj6c3j9WwaLcFYsICYDnLAzY0hp+wG2nxl+Cm2jWLiNVYb8g==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.1.6", + "@babel/parser": "^7.1.6", + "@babel/plugin-proposal-class-properties": "^7.1.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.1.0", + "@babel/plugin-proposal-optional-chaining": "^7.1.0", + "@babel/plugin-transform-modules-commonjs": "^7.1.0", + "@babel/preset-flow": "^7.0.0", + "@babel/preset-typescript": "^7.1.0", + "@babel/register": "^7.0.0", + "babel-core": "^7.0.0-bridge.0", + "colors": "^1.1.2", + "flow-parser": "0.*", + "graceful-fs": "^4.2.4", + "micromatch": "^3.1.10", + "neo-async": "^2.5.0", + "node-dir": "^0.1.17", + "recast": "^0.20.3", + "temp": "^0.8.1", + "write-file-atomic": "^2.3.0" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "peer": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "peer": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "peer": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "peer": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "peer": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "peer": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "peer": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "jsdoctypeparser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz", + "integrity": "sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA==", + "dev": true + }, + "jsdom": { + "version": "16.6.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", + "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.5", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true + } + } + }, + "jsdom-global": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsdom-global/-/jsdom-global-3.0.2.tgz", + "integrity": "sha1-a9KZwTsMRiay2iwDk81DhdYGrLk=", + "dev": true, + "requires": {} + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "devOptional": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "dev": true, + "requires": { + "string-convert": "^0.2.0" + } + }, + "json2php": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/json2php/-/json2php-0.0.4.tgz", + "integrity": "sha1-a9haHdpqXdfpECK7JEA8wbfC7jQ=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "devOptional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonc-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", + "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "peer": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "dev": true, + "requires": { + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "known-css-properties": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz", + "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==", + "dev": true + }, + "language-subtag-registry": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", + "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "requires": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + } + } + }, + "line-height": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz", + "integrity": "sha1-SxIF7d4YKHKl76PI9iCzGHqcVMk=", + "dev": true, + "requires": { + "computed-style": "~0.1.3" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "livereload-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", + "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", + "dev": true + }, + "load-grunt-tasks": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz", + "integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "multimatch": "^2.0.0", + "pkg-up": "^1.0.0", + "resolve-pkg": "^0.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash._baseisequal": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz", + "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=", + "dev": true, + "requires": { + "lodash.isarray": "^3.0.0", + "lodash.istypedarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.differencewith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.differencewith/-/lodash.differencewith-4.5.0.tgz", + "integrity": "sha1-uvr7yRi1UVTheRdqALsK76rIVLc=", + "dev": true + }, + "lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "lodash.istypedarray": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", + "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "dev": true, + "peer": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "logkitty": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.7.1.tgz", + "integrity": "sha512-/3ER20CTTbahrCrpYfPn7Xavv9diBROZpoXGVZDWMw4b/X4uuUwAC0ki85tgsdMRONURyIJbcOvS94QsUBYPbQ==", + "dev": true, + "peer": true, + "requires": { + "ansi-fragments": "^0.2.1", + "dayjs": "^1.8.15", + "yargs": "^15.1.0" + } + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-values/-/map-values-1.0.1.tgz", + "integrity": "sha1-douOecAJvytk/ugG4ip7HEGQyZA=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true + }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + } + } + }, + "markdownlint": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.18.0.tgz", + "integrity": "sha512-nQAfK9Pbq0ZRoMC/abNGterEnV3kL8MZmi0WHhw8WJKoIbsm3cXGufGsxzCRvjW15cxe74KWcxRSKqwplS26Bw==", + "dev": true, + "requires": { + "markdown-it": "10.0.0" + } + }, + "markdownlint-cli": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.21.0.tgz", + "integrity": "sha512-gvnczz3W3Wgex851/cIQ/2y8GNhY+EVK8Ael8kRd8hoSQ0ps9xjhtwPwMyJPoiYbAoPxG6vSBFISiysaAbCEZg==", + "dev": true, + "requires": { + "commander": "~2.9.0", + "deep-extend": "~0.5.1", + "get-stdin": "~5.0.1", + "glob": "~7.1.2", + "ignore": "~5.1.4", + "js-yaml": "~3.13.1", + "jsonc-parser": "~2.2.0", + "lodash.differencewith": "~4.5.0", + "lodash.flatten": "~4.4.0", + "markdownlint": "~0.18.0", + "markdownlint-rule-helpers": "~0.6.0", + "minimatch": "~3.0.4", + "rc": "~1.2.7" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } + }, + "markdownlint-rule-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.6.0.tgz", + "integrity": "sha512-LiZVAbg9/cqkBHtLNNqHV3xuy4Y2L/KuGU6+ZXqCT9NnCdEkIoxeI5/96t+ExquBY0iHy2CVWxPH16nG1RKQVQ==", + "dev": true + }, + "mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "dependencies": { + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } + } + } + }, + "mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "dependencies": { + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + } + } + }, + "mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", + "integrity": "sha512-K4FcPETOMTwe7KL2LK0orMhpOmWD2wRGwWWpbZy0fyArwsyIKR8YJVz8+efBAh3BO4zPqlSICu4vsLTRRqtFAg==", + "dev": true + }, + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "merge-deep": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.3.tgz", + "integrity": "sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "clone-deep": "^0.2.4", + "kind-of": "^3.0.2" + }, + "dependencies": { + "clone-deep": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", + "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", + "dev": true, + "requires": { + "for-own": "^0.1.3", + "is-plain-object": "^2.0.1", + "kind-of": "^3.0.2", + "lazy-cache": "^1.0.3", + "shallow-clone": "^0.1.2" + } + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "shallow-clone": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", + "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", + "dev": true, + "requires": { + "is-extendable": "^0.1.1", + "kind-of": "^2.0.1", + "lazy-cache": "^0.2.3", + "mixin-object": "^2.0.1" + }, + "dependencies": { + "kind-of": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", + "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", + "dev": true, + "requires": { + "is-buffer": "^1.0.2" + } + }, + "lazy-cache": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", + "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", + "dev": true + } + } + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "metro": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.64.0.tgz", + "integrity": "sha512-G2OC08Rzfs0kqnSEuKo2yZxR+/eNUpA93Ru45c60uN0Dw3HPrDi+ZBipgFftC6iLE0l+6hu8roFFIofotWxybw==", + "dev": true, + "peer": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "absolute-path": "^0.0.0", + "accepts": "^1.3.7", + "async": "^2.4.0", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "error-stack-parser": "^2.0.6", + "fs-extra": "^1.0.0", + "graceful-fs": "^4.1.3", + "image-size": "^0.6.0", + "invariant": "^2.2.4", + "jest-haste-map": "^26.5.2", + "jest-worker": "^26.0.0", + "lodash.throttle": "^4.1.1", + "metro-babel-register": "0.64.0", + "metro-babel-transformer": "0.64.0", + "metro-cache": "0.64.0", + "metro-cache-key": "0.64.0", + "metro-config": "0.64.0", + "metro-core": "0.64.0", + "metro-hermes-compiler": "0.64.0", + "metro-inspector-proxy": "0.64.0", + "metro-minify-uglify": "0.64.0", + "metro-react-native-babel-preset": "0.64.0", + "metro-resolver": "0.64.0", + "metro-runtime": "0.64.0", + "metro-source-map": "0.64.0", + "metro-symbolicate": "0.64.0", + "metro-transform-plugins": "0.64.0", + "metro-transform-worker": "0.64.0", + "mime-types": "^2.1.27", + "mkdirp": "^0.5.1", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.1", + "rimraf": "^2.5.4", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "strip-ansi": "^6.0.0", + "temp": "0.8.3", + "throat": "^5.0.0", + "ws": "^1.1.5", + "yargs": "^15.3.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "peer": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "peer": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "peer": true + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "dev": true, + "peer": true, + "requires": { + "os-tmpdir": "^1.0.0", + "rimraf": "~2.2.6" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true, + "peer": true + } + } + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "peer": true, + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + } + } + }, + "metro-babel-register": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.64.0.tgz", + "integrity": "sha512-Kf6YvE3kIRumGnjK0Q9LqGDIdnsX9eFGtNBmBuCVDuB9wGGA/5CgX8We8W7Y44dz1RGTcHJRhfw5iGg+pwC3aQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/register": "^7.0.0", + "escape-string-regexp": "^1.0.5" + } + }, + "metro-babel-transformer": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.64.0.tgz", + "integrity": "sha512-itZaxKTgmKGEZWxNzbSZBc22NngrMZzoUNuU92aHSTGkYi2WH4XlvzEHsstmIKHMsRVKl75cA+mNmgk4gBFJKw==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.0.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1" + } + }, + "metro-cache": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.64.0.tgz", + "integrity": "sha512-QvGfxe/1QQYM9XOlR8W1xqE9eHDw/AgJIgYGn/TxZxBu9Zga+Rgs1omeSZju45D8w5VWgMr83ma5kACgzvOecg==", + "dev": true, + "peer": true, + "requires": { + "metro-core": "0.64.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "metro-cache-key": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.64.0.tgz", + "integrity": "sha512-O9B65G8L/fopck45ZhdRosyVZdMtUQuX5mBWEC1NRj02iWBIUPLmYMjrunqIe8vHipCMp3DtTCm/65IlBmO8jg==", + "dev": true, + "peer": true + }, + "metro-config": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.64.0.tgz", + "integrity": "sha512-QhM4asnX5KhlRWaugwVGNNXhX0Z85u5nK0UQ/A90bBb4xWyXqUe20e788VtdA75rkQiiI6wXTCIHWT0afbnjwQ==", + "dev": true, + "peer": true, + "requires": { + "cosmiconfig": "^5.0.5", + "jest-validate": "^26.5.2", + "metro": "0.64.0", + "metro-cache": "0.64.0", + "metro-core": "0.64.0", + "metro-runtime": "0.64.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "peer": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "peer": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "peer": true + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "peer": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "peer": true + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "peer": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "metro-core": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.64.0.tgz", + "integrity": "sha512-v8ZQ5j72EaUwamQ8pLfHlOHTyp7SbdazvHPzFGDpHnwIQqIT0Bw3Syg8R4regTlVG3ngpeSEAi005UITljmMcQ==", + "dev": true, + "peer": true, + "requires": { + "jest-haste-map": "^26.5.2", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.64.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "peer": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "peer": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "peer": true + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "peer": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "metro-hermes-compiler": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.64.0.tgz", + "integrity": "sha512-CLAjVDWGAoGhbi2ZyPHnH5YDdfrDIx6+tzFWfHGIMTZkYBXsYta9IfYXBV8lFb6BIbrXLjlXZAOoosknetMPOA==", + "dev": true, + "peer": true + }, + "metro-inspector-proxy": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.64.0.tgz", + "integrity": "sha512-KywbH3GNSz9Iqw4UH3smgaV2dBHHYMISeN7ORntDL/G+xfgPc6vt13d+zFb907YpUcXj5N0vdoiAHI5V/0y8IA==", + "dev": true, + "peer": true, + "requires": { + "connect": "^3.6.5", + "debug": "^2.2.0", + "ws": "^1.1.5", + "yargs": "^15.3.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "peer": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true, + "peer": true + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "peer": true, + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + } + } + }, + "metro-minify-uglify": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.64.0.tgz", + "integrity": "sha512-DRwRstqXR5qfte9Nuwoov5dRXxL7fJeVlO5fGyOajWeO3+AgPjvjXh/UcLJqftkMWTPGUFuzAD5/7JC5v5FLWw==", + "dev": true, + "peer": true, + "requires": { + "uglify-es": "^3.1.9" + } + }, + "metro-react-native-babel-preset": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.64.0.tgz", + "integrity": "sha512-HcZ0RWQRuJfpPiaHyFQJzcym+/dDIVUPwUAXWoub/C4GkGu+mPjp8vqK6g0FxokCnnI2TK0gZTza2IDfiNNscQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + } + }, + "metro-react-native-babel-transformer": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.64.0.tgz", + "integrity": "sha512-K1sHO3ODBFCr7uEiCQ4RvVr+cQg0EHQF8ChVPnecGh/WDD8udrTq9ECwB0dRfMjAvlsHtRUlJm6ZSI8UPgum2w==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.0.0", + "babel-preset-fbjs": "^3.3.0", + "metro-babel-transformer": "0.64.0", + "metro-react-native-babel-preset": "0.64.0", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1" + } + }, + "metro-resolver": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.64.0.tgz", + "integrity": "sha512-cJ26Id8Zf+HmS/1vFwu71K3u7ep/+HeXXAJIeVDYf+niE7AWB9FijyMtAlQgbD8elWqv1leJCnQ/xHRFBfGKYA==", + "dev": true, + "peer": true, + "requires": { + "absolute-path": "^0.0.0" + } + }, + "metro-runtime": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.64.0.tgz", + "integrity": "sha512-m7XbWOaIOeFX7YcxUhmnOi6Pg8EaeL89xyZ+quZyZVF1aNoTr4w8FfbKxvijpjsytKHIZtd+43m2Wt5JrqyQmQ==", + "dev": true, + "peer": true + }, + "metro-source-map": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.64.0.tgz", + "integrity": "sha512-OCG2rtcp5cLEGYvAbfkl6mEc0J2FPRP4/UCEly+juBk7hawS9bCBMBfhJm/HIsvY1frk6nT2Vsl1O8YBbwyx2g==", + "dev": true, + "peer": true, + "requires": { + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "invariant": "^2.2.4", + "metro-symbolicate": "0.64.0", + "nullthrows": "^1.1.1", + "ob1": "0.64.0", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + } + }, + "metro-symbolicate": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.64.0.tgz", + "integrity": "sha512-qIi+YRrDWnLVmydj6gwidYLPaBsakZRibGWSspuXgHAxOI3UuLwlo4dpQ73Et0gyHjI7ZvRMRY8JPiOntf9AQQ==", + "dev": true, + "peer": true, + "requires": { + "invariant": "^2.2.4", + "metro-source-map": "0.64.0", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "through2": "^2.0.1", + "vlq": "^1.0.0" + } + }, + "metro-transform-plugins": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.64.0.tgz", + "integrity": "sha512-iTIRBD/wBI98plfxj8jAoNUUXfXLNlyvcjPtshhpGvdwu9pzQilGfnDnOaaK+vbITcOk9w5oQectXyJwAqTr1A==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "nullthrows": "^1.1.1" + } + }, + "metro-transform-worker": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.64.0.tgz", + "integrity": "sha512-wegRtK8GyLF6IPZRBJp+zsORgA4iX0h1DRpknyAMDCtSbJ4VU2xV/AojteOgAsDvY3ucAGsvfuZLNDJHUdUNHQ==", + "dev": true, + "peer": true, + "requires": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/parser": "^7.0.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.3.0", + "metro": "0.64.0", + "metro-babel-transformer": "0.64.0", + "metro-cache": "0.64.0", + "metro-cache-key": "0.64.0", + "metro-hermes-compiler": "0.64.0", + "metro-source-map": "0.64.0", + "metro-transform-plugins": "0.64.0", + "nullthrows": "^1.1.1" + } + }, + "micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "requires": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + }, + "dependencies": { + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + } + } + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dev": true, + "requires": { + "mime-db": "1.48.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "devOptional": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + } + } + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mitt": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", + "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "dev": true, + "requires": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", + "dev": true + } + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + } + } + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "moment-timezone": { + "version": "0.5.33", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz", + "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==", + "dev": true, + "requires": { + "moment": ">= 2.9.0" + } + }, + "moo": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", + "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==", + "dev": true + }, + "mousetrap": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz", + "integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==", + "dev": true + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "devOptional": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + } + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nearley": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", + "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==", + "dev": true, + "peer": true + }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "dev": true, + "peer": true, + "requires": { + "minimatch": "^3.0.2" + } + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true, + "peer": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + } + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "devOptional": true + }, + "node-sass": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", + "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "node-stream-zip": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.13.6.tgz", + "integrity": "sha512-c7tRSVkLNOHvasWgmZ2d86cDgTWEygnkuuHNOY9c0mR3yLZtQTTrGvMaJ/fPs6+LOJn3240y30l5sjLaXFtcvw==", + "dev": true, + "peer": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "normalize-wheel": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz", + "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=", + "dev": true + }, + "npm": { + "version": "6.14.13", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.13.tgz", + "integrity": "sha512-SRl4jJi0EBHY2xKuu98FLRMo3VhYQSA6otyLnjSEiHoSG/9shXCFNJy9tivpUJvtkN9s6VDdItHa5Rn+fNBzag==", + "dev": true, + "requires": { + "abbrev": "~1.1.1", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "aproba": "^2.0.0", + "archy": "~1.0.0", + "bin-links": "^1.1.8", + "bluebird": "^3.5.5", + "byte-size": "^5.0.1", + "cacache": "^12.0.3", + "call-limit": "^1.1.1", + "chownr": "^1.1.4", + "ci-info": "^2.0.0", + "cli-columns": "^3.1.2", + "cli-table3": "^0.5.1", + "cmd-shim": "^3.0.3", + "columnify": "~1.5.4", + "config-chain": "^1.1.12", + "debuglog": "*", + "detect-indent": "~5.0.0", + "detect-newline": "^2.1.0", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "fs-vacuum": "~1.2.10", + "fs-write-stream-atomic": "~1.0.10", + "gentle-fs": "^2.3.1", + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "has-unicode": "~2.0.1", + "hosted-git-info": "^2.8.9", + "iferr": "^1.0.2", + "imurmurhash": "*", + "infer-owner": "^1.0.4", + "inflight": "~1.0.6", + "inherits": "^2.0.4", + "ini": "^1.3.8", + "init-package-json": "^1.10.3", + "is-cidr": "^3.0.0", + "json-parse-better-errors": "^1.0.2", + "JSONStream": "^1.3.5", + "lazy-property": "~1.0.0", + "libcipm": "^4.0.8", + "libnpm": "^3.0.1", + "libnpmaccess": "^3.0.2", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "libnpx": "^10.2.4", + "lock-verify": "^2.1.0", + "lockfile": "^1.0.4", + "lodash._baseindexof": "*", + "lodash._baseuniq": "~4.6.0", + "lodash._bindcallback": "*", + "lodash._cacheindexof": "*", + "lodash._createcache": "*", + "lodash._getnative": "*", + "lodash.clonedeep": "~4.5.0", + "lodash.restparam": "*", + "lodash.union": "~4.6.0", + "lodash.uniq": "~4.5.0", + "lodash.without": "~4.4.0", + "lru-cache": "^5.1.1", + "meant": "^1.0.2", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.5", + "move-concurrently": "^1.0.1", + "node-gyp": "^5.1.0", + "nopt": "^4.0.3", + "normalize-package-data": "^2.5.0", + "npm-audit-report": "^1.3.3", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "^3.0.2", + "npm-lifecycle": "^3.1.5", + "npm-package-arg": "^6.1.1", + "npm-packlist": "^1.4.8", + "npm-pick-manifest": "^3.0.2", + "npm-profile": "^4.0.4", + "npm-registry-fetch": "^4.0.7", + "npm-user-validate": "^1.0.1", + "npmlog": "~4.1.2", + "once": "~1.4.0", + "opener": "^1.5.2", + "osenv": "^0.1.5", + "pacote": "^9.5.12", + "path-is-inside": "~1.0.2", + "promise-inflight": "~1.0.1", + "qrcode-terminal": "^0.12.0", + "query-string": "^6.8.2", + "qw": "~1.0.1", + "read": "~1.0.7", + "read-cmd-shim": "^1.0.5", + "read-installed": "~4.0.3", + "read-package-json": "^2.1.1", + "read-package-tree": "^5.3.1", + "readable-stream": "^3.6.0", + "readdir-scoped-modules": "^1.1.0", + "request": "^2.88.0", + "retry": "^0.12.0", + "rimraf": "^2.7.1", + "safe-buffer": "^5.1.2", + "semver": "^5.7.1", + "sha": "^3.0.0", + "slide": "~1.1.6", + "sorted-object": "~2.0.1", + "sorted-union-stream": "~2.1.3", + "ssri": "^6.0.2", + "stringify-package": "^1.0.1", + "tar": "^4.4.13", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "unique-filename": "^1.1.1", + "unpipe": "~1.0.0", + "update-notifier": "^2.5.0", + "uuid": "^3.3.3", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "~3.0.0", + "which": "^1.3.1", + "worker-farm": "^1.7.0", + "write-file-atomic": "^2.4.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "agent-base": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "agentkeepalive": { + "version": "3.5.2", + "bundled": true, + "dev": true, + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "ansi-align": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "asap": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "asn1": { + "version": "0.2.4", + "bundled": true, + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "bundled": true, + "dev": true + }, + "aws4": { + "version": "1.8.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bin-links": { + "version": "1.1.8", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cmd-shim": "^3.0.0", + "gentle-fs": "^2.3.0", + "graceful-fs": "^4.1.15", + "npm-normalize-package-bin": "^1.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "bluebird": { + "version": "3.5.5", + "bundled": true, + "dev": true + }, + "boxen": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "builtins": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "byline": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "byte-size": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "cacache": { + "version": "12.0.3", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "call-limit": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "chalk": { + "version": "2.4.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "2.0.10", + "bundled": true, + "dev": true, + "requires": { + "ip-regex": "^2.1.0" + } + }, + "cli-boxes": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "cli-columns": { + "version": "3.1.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + } + }, + "cli-table3": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "cliui": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "cmd-shim": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "bundled": true, + "dev": true + }, + "colors": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true + }, + "columnify": { + "version": "1.5.4", + "bundled": true, + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "combined-stream": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "bundled": true, + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "config-chain": { + "version": "1.1.12", + "bundled": true, + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "3.1.5", + "bundled": true, + "dev": true, + "requires": { + "dot-prop": "^4.2.1", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "create-error-class": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + } + } + }, + "crypto-random-string": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "cyclist": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true + }, + "defaults": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "detect-indent": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "dezalgo": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "dot-prop": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "duplexify": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "editor": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "bundled": true, + "dev": true + }, + "encoding": { + "version": "0.1.12", + "bundled": true, + "dev": true, + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "env-paths": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "err-code": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "errno": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "bundled": true, + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "bundled": true, + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "execa": { + "version": "0.7.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "figgy-pudding": { + "version": "3.5.1", + "bundled": true, + "dev": true + }, + "find-npm-prefix": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "flush-write-stream": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true + }, + "form-data": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^2.6.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "fs-vacuum": { + "version": "1.2.10", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "dependencies": { + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "genfun": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "gentle-fs": { + "version": "2.3.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.2", + "chownr": "^1.1.2", + "cmd-shim": "^3.0.3", + "fs-vacuum": "^1.2.10", + "graceful-fs": "^4.1.11", + "iferr": "^0.1.5", + "infer-owner": "^1.0.4", + "mkdirp": "^0.5.1", + "path-is-inside": "^1.0.2", + "read-cmd-shim": "^1.0.1", + "slide": "^1.1.6" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true, + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global-dirs": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "got": { + "version": "6.7.1", + "bundled": true, + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "bundled": true, + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "bundled": true, + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "bundled": true, + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "bundled": true, + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "bundled": true, + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "bundled": true, + "dev": true + }, + "http-cache-semantics": { + "version": "3.8.1", + "bundled": true, + "dev": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + } + }, + "http-signature": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "bundled": true, + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "iferr": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-lazy": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.8", + "bundled": true, + "dev": true + }, + "init-package-json": { + "version": "1.10.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + } + }, + "ip": { + "version": "1.1.5", + "bundled": true, + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "ci-info": "^1.5.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "bundled": true, + "dev": true + } + } + }, + "is-cidr": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "cidr-regex": "^2.0.10" + } + }, + "is-date-object": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-redirect": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "bundled": true, + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "jsprim": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "latest-version": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lazy-property": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "libcipm": { + "version": "4.0.8", + "bundled": true, + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.5.1", + "find-npm-prefix": "^1.0.2", + "graceful-fs": "^4.1.11", + "ini": "^1.3.5", + "lock-verify": "^2.1.0", + "mkdirp": "^0.5.1", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "pacote": "^9.1.0", + "read-package-json": "^2.0.13", + "rimraf": "^2.6.2", + "worker-farm": "^1.6.0" + } + }, + "libnpm": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.3", + "find-npm-prefix": "^1.0.2", + "libnpmaccess": "^3.0.2", + "libnpmconfig": "^1.2.1", + "libnpmhook": "^5.0.3", + "libnpmorg": "^1.0.1", + "libnpmpublish": "^1.1.2", + "libnpmsearch": "^2.0.2", + "libnpmteam": "^1.0.2", + "lock-verify": "^2.0.2", + "npm-lifecycle": "^3.0.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "npm-profile": "^4.0.2", + "npm-registry-fetch": "^4.0.0", + "npmlog": "^4.1.2", + "pacote": "^9.5.3", + "read-package-json": "^2.0.13", + "stringify-package": "^1.0.0" + } + }, + "libnpmaccess": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "get-stream": "^4.0.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmconfig": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + } + } + }, + "libnpmhook": { + "version": "5.0.3", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmorg": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmpublish": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "lodash.clonedeep": "^4.5.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^4.0.0", + "semver": "^5.5.1", + "ssri": "^6.0.1" + } + }, + "libnpmsearch": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpmteam": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^4.0.0" + } + }, + "libnpx": { + "version": "10.2.4", + "bundled": true, + "dev": true, + "requires": { + "dotenv": "^5.0.1", + "npm-package-arg": "^6.0.0", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.0", + "update-notifier": "^2.3.0", + "which": "^1.3.0", + "y18n": "^4.0.0", + "yargs": "^14.2.3" + } + }, + "lock-verify": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "npm-package-arg": "^6.1.0", + "semver": "^5.4.1" + } + }, + "lockfile": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "requires": { + "signal-exit": "^3.0.2" + } + }, + "lodash._baseindexof": { + "version": "3.1.0", + "bundled": true, + "extraneous": true + }, + "lodash._baseuniq": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "requires": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "bundled": true, + "extraneous": true + }, + "lodash._cacheindexof": { + "version": "3.0.2", + "bundled": true, + "extraneous": true + }, + "lodash._createcache": { + "version": "3.1.2", + "bundled": true, + "extraneous": true, + "requires": { + "lodash._getnative": "^3.0.0" + } + }, + "lodash._createset": { + "version": "4.0.3", + "bundled": true, + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "bundled": true, + "extraneous": true + }, + "lodash._root": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "bundled": true, + "dev": true + }, + "lodash.restparam": { + "version": "3.6.1", + "bundled": true, + "extraneous": true + }, + "lodash.union": { + "version": "4.6.0", + "bundled": true, + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "bundled": true, + "dev": true + }, + "lodash.without": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "bundled": true, + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-fetch-happen": { + "version": "5.0.2", + "bundled": true, + "dev": true, + "requires": { + "agentkeepalive": "^3.4.1", + "cacache": "^12.0.0", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + } + }, + "meant": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "mime-db": { + "version": "1.35.0", + "bundled": true, + "dev": true + }, + "mime-types": { + "version": "2.1.19", + "bundled": true, + "dev": true, + "requires": { + "mime-db": "~1.35.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "requires": { + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "mississippi": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "bundled": true, + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "bundled": true, + "dev": true + }, + "node-fetch-npm": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-gyp": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.1.2", + "request": "^2.88.0", + "rimraf": "^2.6.3", + "semver": "^5.7.1", + "tar": "^4.4.12", + "which": "^1.3.1" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "npm-audit-report": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "requires": { + "cli-table3": "^0.5.0", + "console-control-strings": "^1.1.0" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "npm-install-checks": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-lifecycle": { + "version": "3.1.5", + "bundled": true, + "dev": true, + "requires": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.15", + "node-gyp": "^5.0.2", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + } + }, + "npm-logical-tree": { + "version": "1.2.1", + "bundled": true, + "dev": true + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npm-package-arg": { + "version": "6.1.1", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^2.7.1", + "osenv": "^0.1.5", + "semver": "^5.6.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-pick-manifest": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "npm-profile": { + "version": "4.0.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.2 || 2", + "figgy-pudding": "^3.4.1", + "npm-registry-fetch": "^4.0.0" + } + }, + "npm-registry-fetch": { + "version": "4.0.7", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "JSONStream": "^1.3.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "npm-package-arg": "^6.1.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "bundled": true, + "dev": true + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npm-user-validate": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "bundled": true, + "dev": true + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "package-json": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "pacote": { + "version": "9.5.12", + "bundled": true, + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cacache": "^12.0.2", + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^5.0.0", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-normalize-package-bin": "^1.0.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^3.0.0", + "npm-registry-fetch": "^4.0.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.10", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "bundled": true, + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "retry": { + "version": "0.10.1", + "bundled": true, + "dev": true + } + } + }, + "promzard": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "read": "1" + } + }, + "proto-list": { + "version": "1.2.4", + "bundled": true, + "dev": true + }, + "protoduck": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "requires": { + "genfun": "^5.0.0" + } + }, + "prr": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "psl": { + "version": "1.1.29", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "bundled": true, + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true + }, + "qrcode-terminal": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "qs": { + "version": "6.5.2", + "bundled": true, + "dev": true + }, + "query-string": { + "version": "6.8.2", + "bundled": true, + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "qw": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "read-installed": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + } + }, + "read-package-json": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "npm-normalize-package-bin": "^1.0.0" + } + }, + "read-package-tree": { + "version": "5.3.1", + "bundled": true, + "dev": true, + "requires": { + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "util-promisify": "^2.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdir-scoped-modules": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "request": { + "version": "2.88.0", + "bundled": true, + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "retry": { + "version": "0.12.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-queue": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.1.1" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "sha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "smart-buffer": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "socks": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + } + } + }, + "sorted-object": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "sorted-union-stream": { + "version": "2.1.3", + "bundled": true, + "dev": true, + "requires": { + "from2": "^1.3.0", + "stream-iterate": "^1.1.0" + }, + "dependencies": { + "from2": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.10" + } + }, + "isarray": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true, + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "bundled": true, + "dev": true + }, + "split-on-first": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "bundled": true, + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.2", + "bundled": true, + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-iterate": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-shift": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strict-uri-encode": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "bundled": true, + "dev": true + } + } + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "stringify-package": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + } + } + }, + "term-size": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "through": { + "version": "2.3.8", + "bundled": true, + "dev": true + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "timed-out": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "tiny-relative-date": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "bundled": true, + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true + }, + "umask": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "unzip-response": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "bundled": true, + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "uri-js": { + "version": "4.4.0", + "bundled": true, + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "bundled": true, + "dev": true + } + } + }, + "url-parse-lax": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "util-extend": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "util-promisify": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "uuid": { + "version": "3.3.3", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "verror": { + "version": "1.10.0", + "bundled": true, + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.2" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "widest-line": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, + "worker-farm": { + "version": "1.7.0", + "bundled": true, + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "xtend": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "y18n": { + "version": "4.0.1", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "14.2.3", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "15.0.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "bundled": true, + "dev": true + } + } + } + } + }, + "npm-package-json-lint": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-5.1.0.tgz", + "integrity": "sha512-gPGpoFTbt0H4uPlubAKqHORg4+GObXqeYJh5ovkkSv76ua+t29vzRP4Qhm+9N/Q59Z3LT0tCmpoDlbTcNB7Jcg==", + "dev": true, + "requires": { + "ajv": "^6.12.2", + "ajv-errors": "^1.0.1", + "chalk": "^4.0.0", + "cosmiconfig": "^6.0.0", + "debug": "^4.1.1", + "globby": "^11.0.0", + "ignore": "^5.1.4", + "is-plain-obj": "^2.1.0", + "jsonc-parser": "^2.2.1", + "log-symbols": "^4.0.0", + "meow": "^6.1.0", + "plur": "^4.0.0", + "semver": "^7.3.2", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true + }, + "meow": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", + "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", + "integrity": "sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true, + "peer": true + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "ob1": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.64.0.tgz", + "integrity": "sha512-CO1N+5dhvy+MoAwxz8+fymEUcwsT4a+wHhrHFb02LppcJdHxgcBWviwEhUwKOD2kLMQ7ijrrzybOqpGcqEtvpQ==", + "dev": true, + "peer": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-filter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object-filter/-/object-filter-1.0.2.tgz", + "integrity": "sha1-rwt5f/6+r4pSxmN87b6IFs/sG8g=", + "dev": true + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.entries": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + } + }, + "object.fromentries": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "peer": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "peer": true, + "requires": { + "is-wsl": "^1.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "peer": true + } + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true, + "peer": true + }, + "ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "peer": true, + "requires": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "peer": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parchment": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz", + "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha1-8r0iH2zJcKk42IVWq8WJyqqiveE=" + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true, + "optional": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + } + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-MSrkwZBdQ6YapHy87/8hDU8MnIcyxBKjeF+McXnr5A9MtffPewTs7G3hlpodT5TacyfIyFTaJEhh3GGcmasTgQ==", + "dev": true, + "peer": true, + "requires": { + "base64-js": "^1.5.1", + "xmlbuilder": "^9.0.7", + "xmldom": "^0.5.0" + } + }, + "plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "requires": { + "irregular-plurals": "^3.2.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "popmotion": { + "version": "9.3.6", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-9.3.6.tgz", + "integrity": "sha512-ZTbXiu6zIggXzIliMi8LGxXBF5ST+wkpXGEjeTUDUOCdSQ356hij/xjeUdv0F8zCQNeqB1+PR5/BB+gC+QLAPw==", + "dev": true, + "requires": { + "framesync": "5.3.0", + "hey-listen": "^1.0.8", + "style-value-types": "4.1.4", + "tslib": "^2.1.0" + } + }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-properties": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-10.0.0.tgz", + "integrity": "sha512-55BPj5FudpCiPZzBaO+MOeqmwMDa+nV9/0QBJBfhZjYg6D9hE+rW9lpMBLTJoF4OTXnS5Po4yM1nMlgkPbCxFg==", + "dev": true, + "requires": { + "postcss": "^7.0.17", + "postcss-values-parser": "^4.0.0" + } + }, + "postcss-html": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", + "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "dev": true, + "requires": { + "htmlparser2": "^3.10.0" + }, + "dependencies": { + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } + }, + "postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz", + "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0", + "postcss-value-parser": "^3.3.1" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + } + }, + "postcss-modules-values": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz", + "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" + } + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "requires": { + "postcss": "^7.0.26" + } + }, + "postcss-sass": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz", + "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==", + "dev": true, + "requires": { + "gonzales-pe": "^4.3.0", + "postcss": "^7.0.21" + } + }, + "postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "requires": { + "postcss": "^7.0.6" + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "dev": true, + "requires": {} + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "postcss-values-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-4.0.0.tgz", + "integrity": "sha512-R9x2D87FcbhwXUmoCXJR85M1BLII5suXRuXibGYyBJ7lVDEpRIdKZh4+8q5S+/+A4m0IoG1U5tFw39asyhX/Hw==", + "dev": true, + "requires": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "postcss": "^7.0.5" + }, + "dependencies": { + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "prettier": { + "version": "npm:wp-prettier@2.0.5", + "resolved": "https://registry.npmjs.org/wp-prettier/-/wp-prettier-2.0.5.tgz", + "integrity": "sha512-5GCgdeevIXwR3cW4Qj5XWC5MO1iSCz8+IPn0mMw6awAt/PBiey8yyO7MhePRsaMqghJAhg6Q3QLYWSnUHWkG6A==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", + "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "dev": true, + "peer": true, + "requires": { + "asap": "~2.0.6" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "prop-types-exact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", + "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", + "dev": true, + "requires": { + "has": "^1.0.3", + "object.assign": "^4.1.0", + "reflect.ownkeys": "^0.2.0" + } + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "puppeteer": { + "version": "npm:puppeteer-core@3.0.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-3.0.0.tgz", + "integrity": "sha512-oWjZFGMc0q2ak+8OxdmMffS79LIT0UEtmpV4h1/AARvESIqqKljf8mrfP+dQ2kas7XttsAZIxRBuWu7Y5JH8KQ==", + "dev": true, + "requires": { + "@types/mime-types": "^2.1.0", + "debug": "^4.1.0", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "mime": "^2.0.3", + "mime-types": "^2.1.25", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + }, + "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dev": true, + "requires": { + "agent-base": "5", + "debug": "4" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "quill": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz", + "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==", + "requires": { + "clone": "^2.1.1", + "deep-equal": "^1.0.1", + "eventemitter3": "^2.0.3", + "extend": "^3.0.2", + "parchment": "^1.1.4", + "quill-delta": "^3.6.2" + } + }, + "quill-delta": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz", + "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==", + "requires": { + "deep-equal": "^1.0.1", + "extend": "^3.0.2", + "fast-diff": "1.1.2" + }, + "dependencies": { + "fast-diff": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz", + "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==" + } + } + }, + "raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dev": true, + "requires": { + "performance-now": "^2.1.0" + } + }, + "railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=", + "dev": true + }, + "randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "requires": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "re-resizable": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-6.9.0.tgz", + "integrity": "sha512-3cUDG81ylyqI0Pdgle/RHwwRYq0ORZzsUaySOCO8IbEtNyaRtrIHYm/jMQ5pjcNiKCxR3vsSymIQZHwJq4gg2Q==", + "dev": true, + "requires": { + "fast-memoize": "^2.5.1" + } + }, + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-addons-shallow-compare": { + "version": "15.6.3", + "resolved": "https://registry.npmjs.org/react-addons-shallow-compare/-/react-addons-shallow-compare-15.6.3.tgz", + "integrity": "sha512-EDJbgKTtGRLhr3wiGDXK/+AEJ59yqGS+tKE6mue0aNXT6ZMR7VJbbzIiT6akotmHg1BLj46ElJSb+NBMp80XBg==", + "dev": true, + "requires": { + "object-assign": "^4.1.0" + } + }, + "react-autosize-textarea": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-3.0.3.tgz", + "integrity": "sha512-iOSZK7RUuJ+iEwkJ9rqYciqtjQgrG1CCRFL6h8Bk61kODnRyEq4tS74IgXpI1t4S6jBBZVm+6ugaU+tWTlVxXg==", + "dev": true, + "requires": { + "autosize": "^4.0.0", + "line-height": "^0.3.1", + "prop-types": "^15.5.6" + } + }, + "react-codemirror2": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/react-codemirror2/-/react-codemirror2-7.2.1.tgz", + "integrity": "sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==", + "requires": {} + }, + "react-colorful": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-4.4.4.tgz", + "integrity": "sha512-01V2/6rr6sa1vaZntWZJXZxnU7ew02NG2rqq0eoVp4d3gFU5Ug9lDzNMbr+8ns0byXsJbBR8LbwQTlAjz6x7Kg==", + "dev": true, + "requires": {} + }, + "react-dates": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-17.2.0.tgz", + "integrity": "sha512-RDlerU8DdRRrlYS0MQ7Z9igPWABGLDwz6+ykBNff67RM3Sset2TDqeuOr+R5o00Ggn5U47GeLsGcSDxlZd9cHw==", + "dev": true, + "requires": { + "airbnb-prop-types": "^2.10.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "is-touch-device": "^1.0.1", + "lodash": "^4.1.1", + "object.assign": "^4.1.0", + "object.values": "^1.0.4", + "prop-types": "^15.6.1", + "react-addons-shallow-compare": "^15.6.2", + "react-moment-proptypes": "^1.6.0", + "react-outside-click-handler": "^1.2.0", + "react-portal": "^4.1.5", + "react-with-styles": "^3.2.0", + "react-with-styles-interface-css": "^4.0.2" + } + }, + "react-datetime": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/react-datetime/-/react-datetime-3.1.1.tgz", + "integrity": "sha512-gHCTjAniCcMb6jdXpz+MpVe/uCeaHNDOofg+l41nLlJI3uBLBMV40CQbGB2TCTUpCzGT1mCs4vQzKGMjXO/WWQ==", + "requires": { + "prop-types": "^15.5.7" + } + }, + "react-devtools-core": { + "version": "4.13.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.13.5.tgz", + "integrity": "sha512-k+P5VSKM6P22Go9IQ8dJmjj9fbztvKt1iRDI/4wS5oTvd1EnytIJMYB59wZt+D3kgp64jklNX/MRmY42xAQ08g==", + "dev": true, + "peer": true, + "requires": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-easy-crop": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-3.5.2.tgz", + "integrity": "sha512-cwSGO/wk42XDpEyrdAcnQ6OJetVDZZO2ry1i19+kSGZQ750aN06RU9y9z95B5QI6sW3SnaWQRKv5r5GSqVV//g==", + "dev": true, + "requires": { + "normalize-wheel": "^1.0.1", + "tslib": "2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz", + "integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==", + "dev": true + } + } + }, + "react-input-autosize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", + "integrity": "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==", + "requires": { + "prop-types": "^15.5.8" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-merge-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz", + "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==", + "dev": true + }, + "react-moment-proptypes": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/react-moment-proptypes/-/react-moment-proptypes-1.8.1.tgz", + "integrity": "sha512-Er940DxWoObfIqPrZNfwXKugjxMIuk1LAuEzn23gytzV6hKS/sw108wibi9QubfMN4h+nrlje8eUCSbQRJo2fQ==", + "dev": true, + "requires": { + "moment": ">=1.6.0" + } + }, + "react-native-codegen": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.0.6.tgz", + "integrity": "sha512-cMvrUelD81wiPitEPiwE/TCNscIVauXxmt4NTGcy18HrUd0WRWXfYzAQGXm0eI87u3NMudNhqFj2NISJenxQHg==", + "dev": true, + "peer": true, + "requires": { + "flow-parser": "^0.121.0", + "jscodeshift": "^0.11.0", + "nullthrows": "^1.1.1" + } + }, + "react-outside-click-handler": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-outside-click-handler/-/react-outside-click-handler-1.3.0.tgz", + "integrity": "sha512-Te/7zFU0oHpAnctl//pP3hEAeobfeHMyygHB8MnjP6sX5OR8KHT1G3jmLsV3U9RnIYo+Yn+peJYWu+D5tUS8qQ==", + "dev": true, + "requires": { + "airbnb-prop-types": "^2.15.0", + "consolidated-events": "^1.1.1 || ^2.0.0", + "document.contains": "^1.0.1", + "object.values": "^1.1.0", + "prop-types": "^15.7.2" + } + }, + "react-portal": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-portal/-/react-portal-4.2.1.tgz", + "integrity": "sha512-fE9kOBagwmTXZ3YGRYb4gcMy+kSA+yLO0xnPankjRlfBv4uCpFXqKPfkpsGQQR15wkZ9EssnvTOl1yMzbkxhPQ==", + "dev": true, + "requires": { + "prop-types": "^15.5.8" + } + }, + "react-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-1.0.1.tgz", + "integrity": "sha512-1tKOwxFn3dXVomH6pM9IkLkq2Y8oh+fh/lYW3MJ/B03URswUTqttgckOlbxY2XHF3vPG6uanSc4dVsLW/wk3wQ==" + }, + "react-quill": { + "version": "2.0.0-beta.4", + "resolved": "https://registry.npmjs.org/react-quill/-/react-quill-2.0.0-beta.4.tgz", + "integrity": "sha512-KyAHvAlPjP4xLElKZJefMth91Z6FbbXRvq9OSu6xN3KBaoasLP9p+3dcxg4Ywr4tBlpMGXcPszYSAgd5CpJ45Q==", + "requires": { + "@types/quill": "^1.3.10", + "lodash": "^4.17.4", + "quill": "^1.3.7" + } + }, + "react-refresh": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz", + "integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA==", + "dev": true, + "peer": true + }, + "react-resize-aware": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-resize-aware/-/react-resize-aware-3.1.0.tgz", + "integrity": "sha512-bIhHlxVTX7xKUz14ksXMEHjzCZPTpQZKZISY3nbTD273pDKPABGFNFBP6Tr42KECxzC5YQiKpMchjTVJCqaxpA==", + "dev": true, + "requires": {} + }, + "react-select": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", + "integrity": "sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==", + "requires": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.1.1", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^3.0.0", + "react-transition-group": "^4.3.0" + }, + "dependencies": { + "@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "requires": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "@emotion/sheet": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.1.tgz", + "integrity": "sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==" + }, + "@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + } + } + }, + "react-spring": { + "version": "8.0.27", + "resolved": "https://registry.npmjs.org/react-spring/-/react-spring-8.0.27.tgz", + "integrity": "sha512-nDpWBe3ZVezukNRandTeLSPcwwTMjNVu1IDq9qA/AMiUqHuRN4BeSWvKr3eIxxg1vtiYiOLy4FqdfCP5IoP77g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "prop-types": "^15.5.8" + } + }, + "react-test-renderer": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", + "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "react-is": "^16.8.6", + "scheduler": "^0.19.1" + } + }, + "react-textarea-autosize": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" + } + }, + "react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "react-use-gesture": { + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/react-use-gesture/-/react-use-gesture-7.0.16.tgz", + "integrity": "sha512-gwgX+E+WQG0T1uFVl3z8j3ZwH3QQGIgVl7VtQEC2m0IscSs668sSps4Ss3CFp3Vns8xx0j9TVK4aBXH6+YrpEg==", + "dev": true, + "requires": {} + }, + "react-with-direction": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.1.tgz", + "integrity": "sha512-aGcM21ZzhqeXFvDCfPj0rVNYuaVXfTz5D3Rbn0QMz/unZe+CCiLHthrjQWO7s6qdfXORgYFtmS7OVsRgSk5LXQ==", + "dev": true, + "requires": { + "airbnb-prop-types": "^2.10.0", + "brcast": "^2.0.2", + "deepmerge": "^1.5.2", + "direction": "^1.0.2", + "hoist-non-react-statics": "^3.3.0", + "object.assign": "^4.1.0", + "object.values": "^1.0.4", + "prop-types": "^15.6.2" + }, + "dependencies": { + "deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "dev": true + } + } + }, + "react-with-styles": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/react-with-styles/-/react-with-styles-3.2.3.tgz", + "integrity": "sha512-MTI1UOvMHABRLj5M4WpODfwnveHaip6X7QUMI2x6zovinJiBXxzhA9AJP7MZNaKqg1JRFtHPXZdroUC8KcXwlQ==", + "dev": true, + "requires": { + "hoist-non-react-statics": "^3.2.1", + "object.assign": "^4.1.0", + "prop-types": "^15.6.2", + "react-with-direction": "^1.3.0" + } + }, + "react-with-styles-interface-css": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/react-with-styles-interface-css/-/react-with-styles-interface-css-4.0.3.tgz", + "integrity": "sha512-wE43PIyjal2dexxyyx4Lhbcb+E42amoYPnkunRZkb9WTA+Z+9LagbyxwsI352NqMdFmghR0opg29dzDO4/YXbw==", + "dev": true, + "requires": { + "array.prototype.flat": "^1.2.1", + "global-cache": "^1.2.1" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "optional": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "optional": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "reakit": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/reakit/-/reakit-1.3.8.tgz", + "integrity": "sha512-8SVejx6FUaFi2+Q9eXoDAd4wWi/xAn6v8JgXH8x2xnzye8pb6v5bYvegACVpYVZnrS5w/JUgMTGh1Xy8MkkPww==", + "dev": true, + "requires": { + "@popperjs/core": "^2.5.4", + "body-scroll-lock": "^3.1.5", + "reakit-system": "^0.15.1", + "reakit-utils": "^0.15.1", + "reakit-warning": "^0.6.1" + } + }, + "reakit-system": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/reakit-system/-/reakit-system-0.15.1.tgz", + "integrity": "sha512-PkqfAyEohtcEu/gUvKriCv42NywDtUgvocEN3147BI45dOFAB89nrT7wRIbIcKJiUT598F+JlPXAZZVLWhc1Kg==", + "dev": true, + "requires": { + "reakit-utils": "^0.15.1" + } + }, + "reakit-utils": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/reakit-utils/-/reakit-utils-0.15.1.tgz", + "integrity": "sha512-6cZgKGvOkAMQgkwU9jdYbHfkuIN1Pr+vwcB19plLvcTfVN0Or10JhIuj9X+JaPZyI7ydqTDFaKNdUcDP69o/+Q==", + "dev": true, + "requires": {} + }, + "reakit-warning": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/reakit-warning/-/reakit-warning-0.6.1.tgz", + "integrity": "sha512-poFUV0EyxB+CcV9uTNBAFmcgsnR2DzAbOTkld4Ul+QOKSeEHZB3b3+MoZQgcYHmbvG19Na1uWaM7ES+/Eyr8tQ==", + "dev": true, + "requires": { + "reakit-utils": "^0.15.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true + }, + "recast": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.20.4.tgz", + "integrity": "sha512-6qLIBGGRcwjrTZGIiBpJVC/NeuXpogXNyRQpqU1zWPUigCphvApoCs9KIwDYh1eDuJ6dAFlQoi/QUyE5KQ6RBQ==", + "dev": true, + "peer": true, + "requires": { + "ast-types": "0.14.2", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tslib": "^2.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true + } + } + }, + "rechoir": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", + "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "redux": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.0.tgz", + "integrity": "sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-multi": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/redux-multi/-/redux-multi-0.1.12.tgz", + "integrity": "sha1-KOH+XklnLLxb2KB/Cyrq8O+DVcI=", + "dev": true + }, + "redux-optimist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redux-optimist/-/redux-optimist-1.0.0.tgz", + "integrity": "sha512-AG1v8o6UZcGXTEH2jVcWG6KD+gEix+Cj9JXAAzln9MPkauSVd98H7N7EOOyT/v4c9N1mJB4sm1zfspGlLDkUEw==", + "dev": true + }, + "redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, + "reflect.ownkeys": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", + "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=", + "dev": true + }, + "refx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/refx/-/refx-3.1.1.tgz", + "integrity": "sha512-lwN27W5iYyagpCxxYDYDl0IIiKh0Vgi3wvafqfthbzTfBgLOYAstcftp+G2X612xVaB8rhn5wDxd4er4KEeb8A==", + "dev": true + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regextras": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.7.1.tgz", + "integrity": "sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w==", + "dev": true + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remark": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-13.0.0.tgz", + "integrity": "sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==", + "dev": true, + "requires": { + "remark-parse": "^9.0.0", + "remark-stringify": "^9.0.0", + "unified": "^9.1.0" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "remark-parse": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz", + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dev": true, + "requires": { + "mdast-util-from-markdown": "^0.8.0" + } + }, + "unified": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.1.tgz", + "integrity": "sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + } + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } + }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + } + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + } + } + }, + "remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-stringify": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-9.0.1.tgz", + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "dev": true, + "requires": { + "mdast-util-to-markdown": "^0.6.0" + } + }, + "rememo": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rememo/-/rememo-3.0.0.tgz", + "integrity": "sha512-eWtut/7pqMRnSccbexb647iPjN7ir6Tmf4RG92ZVlykFEkHqGYy9tWnpHH3I+FS+WQ6lQ1i1iDgarYzGKgTcRQ==", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, + "reselect": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-bin": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/resolve-bin/-/resolve-bin-0.4.0.tgz", + "integrity": "sha1-RxMiSYkRAa+xmZH+k3ywpfBy5dk=", + "dev": true, + "requires": { + "find-parent-dir": "~0.3.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true, + "requires": { + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" + }, + "dependencies": { + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + } + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "dev": true + }, + "resolve-pkg": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz", + "integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=", + "dev": true, + "requires": { + "resolve-from": "^2.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + } + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "peer": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "peer": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "peer": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rst-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", + "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=", + "dev": true, + "requires": { + "lodash.flattendeep": "^4.4.0", + "nearley": "^2.7.10" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "rtlcss": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-2.6.2.tgz", + "integrity": "sha512-06LFAr+GAPo+BvaynsXRfoYTJvSaWRyOhURCQ7aeI1MKph9meM222F+Zkt3bDamyHHJuGi3VPtiRkpyswmQbGA==", + "dev": true, + "requires": { + "@choojs/findup": "^0.2.1", + "chalk": "^2.4.2", + "mkdirp": "^0.5.1", + "postcss": "^6.0.23", + "strip-json-comments": "^2.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rungen": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/rungen/-/rungen-0.3.2.tgz", + "integrity": "sha1-QAwJ6+kU57F+C27zJjQA/Cq8fLM=", + "dev": true + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "sanitize-html": { + "version": "1.27.5", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.27.5.tgz", + "integrity": "sha512-M4M5iXDAUEcZKLXkmk90zSYWEtk5NH3JmojQxKxV371fnMh+x9t1rqdmXaGoyEHw3z/X/8vnFhKjGL5xFGOJ3A==", + "requires": { + "htmlparser2": "^4.1.0", + "lodash": "^4.17.15", + "parse-srcset": "^1.0.2", + "postcss": "^7.0.27" + }, + "dependencies": { + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + } + } + }, + "sass": { + "version": "1.35.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.35.1.tgz", + "integrity": "sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0" + } + }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + } + } + }, + "sass-loader": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz", + "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.0.1", + "neo-async": "^2.5.0", + "pify": "^4.0.1", + "semver": "^6.3.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "devOptional": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", + "dev": true, + "peer": true + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "peer": true, + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "dev": true, + "peer": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "dependencies": { + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "peer": true, + "requires": { + "resolve": "^1.1.6" + } + } + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "showdown": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", + "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==", + "dev": true, + "requires": { + "yargs": "^14.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz", + "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "simple-html-tokenizer": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", + "dev": true + }, + "simple-plist": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.1.1.tgz", + "integrity": "sha512-pKMCVKvZbZTsqYR6RKgLfBHkh2cV89GXcA/0CVPje3sOiNOnXA8+rp/ciAMZ7JRaUdLzlEM6JFfUn+fS6Nt3hg==", + "dev": true, + "peer": true, + "requires": { + "bplist-creator": "0.0.8", + "bplist-parser": "0.2.0", + "plist": "^3.0.1" + } + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "devOptional": true + }, + "source-map-loader": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", + "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", + "dev": true, + "requires": { + "async": "^2.5.0", + "loader-utils": "^1.1.0" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "spawnd": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-4.4.0.tgz", + "integrity": "sha512-jLPOfB6QOEgMOQY15Z6+lwZEhH3F5ncXxIaZ7WHPIapwNNLyjrs61okj3VJ3K6tmP5TZ6cO0VAu9rEY4MD4YQg==", + "dev": true, + "requires": { + "exit": "^0.1.2", + "signal-exit": "^3.0.2", + "tree-kill": "^1.2.2", + "wait-port": "^0.2.7" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "dev": true, + "peer": true + }, + "stacktrace-parser": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", + "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", + "dev": true, + "peer": true, + "requires": { + "type-fest": "^0.7.1" + }, + "dependencies": { + "type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true, + "peer": true + } + } + }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", + "dev": true, + "peer": true + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=", + "dev": true + }, + "string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trim": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.4.tgz", + "integrity": "sha512-hWCk/iqf7lp0/AgTF7/ddO1IWtSNPASjlzCicV5irAVdE1grjsneK26YG6xACMBEdCvO8fUST0UzDMh/2Qy+9Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + }, + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + } + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, + "style-value-types": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-4.1.4.tgz", + "integrity": "sha512-LCJL6tB+vPSUoxgUBt9juXIlNJHtBMy8jkXzUJSBzeHWdBu6lhzHqCvLVkXFGsFIlNa2ln1sQHya/gzaFmB2Lg==", + "dev": true, + "requires": { + "hey-listen": "^1.0.8", + "tslib": "^2.1.0" + } + }, + "styled-griddie": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/styled-griddie/-/styled-griddie-0.1.3.tgz", + "integrity": "sha512-RjsiiADJrRpdPTF8NR26nlZutnvkrX78tiM5/za/E+ftVdpjD8ZBb2iOzrIzfix80uDcHYQbg3iIR0lOGaYmEQ==", + "dev": true + }, + "stylelint": { + "version": "13.13.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.13.1.tgz", + "integrity": "sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==", + "dev": true, + "requires": { + "@stylelint/postcss-css-in-js": "^0.37.2", + "@stylelint/postcss-markdown": "^0.36.2", + "autoprefixer": "^9.8.6", + "balanced-match": "^2.0.0", + "chalk": "^4.1.1", + "cosmiconfig": "^7.0.0", + "debug": "^4.3.1", + "execall": "^2.0.0", + "fast-glob": "^3.2.5", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "global-modules": "^2.0.0", + "globby": "^11.0.3", + "globjoin": "^0.1.4", + "html-tags": "^3.1.0", + "ignore": "^5.1.8", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.21.0", + "lodash": "^4.17.21", + "log-symbols": "^4.1.0", + "mathml-tag-names": "^2.1.3", + "meow": "^9.0.0", + "micromatch": "^4.0.4", + "normalize-selector": "^0.2.0", + "postcss": "^7.0.35", + "postcss-html": "^0.36.0", + "postcss-less": "^3.1.4", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.2", + "postcss-sass": "^0.4.4", + "postcss-scss": "^2.1.1", + "postcss-selector-parser": "^6.0.5", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^4.1.0", + "resolve-from": "^5.0.0", + "slash": "^3.0.0", + "specificity": "^0.4.1", + "string-width": "^4.2.2", + "strip-ansi": "^6.0.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^6.6.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^3.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true + }, + "meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, + "normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "stylelint-config-recommended": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz", + "integrity": "sha512-F6yTRuc06xr1h5Qw/ykb2LuFynJ2IxkKfCMf+1xqPffkxh0S09Zc902XCffcsw/XMFq/OzQ1w54fLIDtmRNHnQ==", + "dev": true, + "requires": {} + }, + "stylelint-config-recommended-scss": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-4.2.0.tgz", + "integrity": "sha512-4bI5BYbabo/GCQ6LbRZx/ZlVkK65a1jivNNsD+ix/Lw0U3iAch+jQcvliGnnAX8SUPaZ0UqzNVNNAF3urswa7g==", + "dev": true, + "requires": { + "stylelint-config-recommended": "^3.0.0" + } + }, + "stylelint-config-wordpress": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-wordpress/-/stylelint-config-wordpress-17.0.0.tgz", + "integrity": "sha512-qUU2kVMd2ezIV9AzRdgietIfnavRRENt4180A1OMoVXIowRjjhohZgBiyVPV5EtNKo3GTO63l8g/QGNG27/h9g==", + "dev": true, + "requires": { + "stylelint-config-recommended": "^3.0.0", + "stylelint-config-recommended-scss": "^4.2.0", + "stylelint-scss": "^3.17.2" + } + }, + "stylelint-scss": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.19.0.tgz", + "integrity": "sha512-Ic5bsmpS4wVucOw44doC1Yi9f5qbeVL4wPFiEOaUElgsOuLEN6Ofn/krKI8BeNL2gAn53Zu+IcVV4E345r6rBw==", + "dev": true, + "requires": { + "lodash": "^4.17.15", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "stylis": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", + "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + }, + "sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "dev": true, + "peer": true + }, + "sugarss": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", + "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "tannin": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tannin/-/tannin-1.2.0.tgz", + "integrity": "sha512-U7GgX/RcSeUETbV7gYgoz8PD7Ni4y95pgIP/Z6ayI3CfhSujwKEBlGFTCRN+Aqnuyf4AN2yHL+L8x+TCGjb9uA==", + "dev": true, + "requires": { + "@tannin/plural-forms": "^1.1.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "temp": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", + "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==", + "dev": true, + "peer": true, + "requires": { + "rimraf": "~2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "peer": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "thread-loader": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz", + "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==", + "dev": true, + "requires": { + "loader-runner": "^2.3.1", + "loader-utils": "^1.1.0", + "neo-async": "^2.6.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true + }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==", + "dev": true + }, + "tiny-lr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", + "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", + "dev": true, + "requires": { + "body": "^5.1.0", + "debug": "^3.1.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.3.0", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "dev": true + }, + "tinycolor2": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", + "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==", + "dev": true + }, + "tippy.js": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.1.tgz", + "integrity": "sha512-JnFncCq+rF1dTURupoJ4yPie5Cof978inW6/4S6kmWV7LL9YOSEVMifED3KdrVPEG+Z/TFH2CDNJcQEfaeuQww==", + "requires": { + "@popperjs/core": "^2.8.3" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "devOptional": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "dev": true, + "requires": { + "glob": "^7.1.2" + } + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "ts-essentials": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz", + "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==", + "dev": true + }, + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "turbo-combine-reducers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/turbo-combine-reducers/-/turbo-combine-reducers-1.0.2.tgz", + "integrity": "sha512-gHbdMZlA6Ym6Ur5pSH/UWrNQMIM9IqTH6SoL1DbHpqEdQ8i+cFunSmSlFykPt0eGQwZ4d/XTHOl74H0/kFBVWw==", + "dev": true + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "peer": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "dev": true, + "peer": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "dev": true, + "peer": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true + } + } + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true, + "peer": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "underscore.string": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "dev": true, + "requires": { + "sprintf-js": "^1.0.3", + "util-deprecate": "^1.0.2" + } + }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "unified": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + }, + "dependencies": { + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + } + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unist-util-find-all-after": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.2.tgz", + "integrity": "sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==", + "dev": true, + "requires": { + "unist-util-is": "^4.0.0" + } + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true + }, + "unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "optional": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-3.0.0.tgz", + "integrity": "sha512-a84JJbIA5xTFTWyjjcPdnsu+41o/SNE8SpXMdUvXs6Q+LuhCD9E2+0VCiuDWqgo3GGXVlFHzArDmBpj9PgWn4A==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "use-composed-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", + "dev": true, + "requires": { + "ts-essentials": "^2.0.3" + } + }, + "use-enhanced-state": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/use-enhanced-state/-/use-enhanced-state-0.0.13.tgz", + "integrity": "sha512-RCtUQdhfUXu/0GAQqLnKPetUt3BheYFpOTogppHe9x1XGwluiu6DQLKVNnc3yMfj0HM3IOVBgw5nVJJuZS5TWQ==", + "dev": true, + "requires": { + "@itsjonq/is": "0.0.2", + "tiny-warning": "^1.0.3" + } + }, + "use-isomorphic-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", + "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==", + "dev": true, + "requires": {} + }, + "use-latest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", + "dev": true, + "requires": { + "use-isomorphic-layout-effect": "^1.0.0" + } + }, + "use-memo-one": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.2.tgz", + "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==", + "dev": true, + "requires": {} + }, + "use-subscription": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", + "integrity": "sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==", + "dev": true, + "peer": true, + "requires": { + "object-assign": "^4.1.1" + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "dev": true, + "requires": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", + "dev": true, + "peer": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "wait-on": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.3.0.tgz", + "integrity": "sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ==", + "dev": true, + "requires": { + "@hapi/joi": "^15.0.3", + "core-js": "^2.6.5", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + } + }, + "wait-port": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-0.2.9.tgz", + "integrity": "sha512-hQ/cVKsNqGZ/UbZB/oakOGFqic00YAMM5/PEj3Bt4vKarv2jWIWzDbqlwT94qMs/exAQAsvMOq99sZblV92zxQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "commander": "^3.0.2", + "debug": "^4.1.1" + }, + "dependencies": { + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + } + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.1" + } + }, + "watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + } + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "peer": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "webpack-bundle-analyzer": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz", + "integrity": "sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.19", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + } + }, + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + } + } + }, + "webpack-livereload-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/webpack-livereload-plugin/-/webpack-livereload-plugin-2.3.0.tgz", + "integrity": "sha512-vVBLQLlNpElt2sfsBG+XLDeVbQFS4RrniVU8Hi1/hX5ycSfx6mtW8MEEITr2g0Cvo36kuPWShFFDuy+DS7KFMA==", + "dev": true, + "requires": { + "anymatch": "^3.1.1", + "portfinder": "^1.0.17", + "tiny-lr": "^1.1.1" + }, + "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + } + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", + "dev": true, + "peer": true + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "dev": true, + "requires": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.2.tgz", + "integrity": "sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ==", + "dev": true, + "requires": {} + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "xcode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz", + "integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==", + "dev": true, + "peer": true, + "requires": { + "simple-plist": "^1.0.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true, + "peer": true + } + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true, + "peer": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "xmldoc": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", + "integrity": "sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ==", + "dev": true, + "peer": true, + "requires": { + "sax": "^1.2.1" + } + }, + "xmldom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz", + "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==", + "dev": true, + "peer": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + } + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 42e6e9a9c7..ed6a0ecc65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pods", - "version": "2.7.31", + "version": "2.8.0", "description": "Pods is a development framework for creating, extending, managing, and deploying customized content types in WordPress.", "author": "Pods Foundation, Inc", "homepage": "https://pods.io/", @@ -9,64 +9,115 @@ "type": "git", "url": "git://github.com/pods-framework/pods.git" }, + "support": "https://support.pods.io/", + "funding": { + "type": "individual", + "url": "https://friends.pods.io/" + }, "license": "GPL-2.0+", "contributors": "https://github.com/pods-framework/pods/graphs/contributors", + "scripts": { + "build-dev": "npm run webpack-dev && npm run scss", + "build-production": "npm run webpack-production && npm run scss", + "format-js": "./node_modules/.bin/eslint --fix ./ui/js", + "jest": "jest --config jest.config.json --maxWorkers=50%", + "jest:watch": "jest --config jest.config.json --watch --maxWorkers=25%", + "lint-js": "./node_modules/.bin/eslint ./ui/js", + "rebuild": "rm -rf node_modules && composer update && npm install && npm run build", + "scss": "node-sass --output-style compressed ui/styles/src -o ui/styles/dist", + "scss:watch": "node-sass --output-style compressed -w ui/styles/src -o ui/styles/dist", + "version_number": "grunt version_number", + "webpack-dev": "webpack --config webpack.dev.js --progress", + "webpack-dev:watch": "webpack --config webpack.dev.js --progress -w", + "webpack-production": "webpack -p --config webpack.prod.js --progress" + }, + "engines": { + "node": ">=12.6.0", + "npm": ">=6.9.0" + }, + "engineStrict": true, "devDependencies": { - "babel-core": "^6.26.3", - "babel-plugin-external-helpers": "^6.22.0", - "babel-plugin-module-resolver": "^3.1.1", + "@babel/cli": "^7.13.14", + "@babel/core": "^7.13.15", + "@babel/plugin-external-helpers": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-react-jsx": "^7.13.12", + "@babel/plugin-transform-strict-mode": "^7.12.13", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.13.15", + "@babel/preset-react": "^7.13.13", + "@babel/register": "^7.13.14", + "@wordpress/api-fetch": "3.18.0", + "@wordpress/block-editor": "4.2.0", + "@wordpress/components": "9.9.0", + "@wordpress/data": "4.21.0", + "@wordpress/date": "3.10.0", + "@wordpress/dependency-extraction-webpack-plugin": "2.8.0", + "@wordpress/editor": "9.19.0", + "@wordpress/eslint-plugin": "7.1.0", + "@wordpress/jest-preset-default": "6.6.0", + "@wordpress/scripts": "12.6.1", + "@wordpress/server-side-render": "1.15.0", + "babel-eslint": "^10.0.1", + "babel-loader": "^8.2.2", + "babel-plugin-module-resolver": "^3.2.0", "babel-plugin-transform-html-import-to-string": "0.0.1", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-env": "^1.7.0", - "babel-preset-react-app": "^3.1.2", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "backbone": "~1.3.3", "backbone.marionette": "^3.5.1", - "eslint": "^5.4.0", - "eslint-config-wordpress": "^2.0.0", - "eslint-plugin-react": "^7.14.3", - "glob": "^7.1.*", - "grunt": "^1.0.0", - "grunt-cli": "^1.3.0", - "grunt-contrib-clean": "^1.0.0", - "grunt-contrib-connect": "^1.0.0", - "grunt-contrib-copy": "^1.0.0", + "classnames": "^2.3.1", + "css-loader": "^2.1.1", + "deep-freeze": "0.0.1", + "enzyme-matchers": "^7.1.2", + "eslint": "^7.24.0", + "eslint-plugin-react": "^7.23.2", + "glob": "^7.1.6", + "grunt": "^1.3.0", + "grunt-cli": "^1.4.2", "grunt-exec": "^3.0.0", - "grunt-git": "^1.0.9", - "grunt-mkdir": "^1.0.0", - "grunt-newer": "^1.2.0", - "grunt-push-svn": "^0.2.2", - "grunt-remove": "^0.1.0", - "grunt-svn-checkout": "^0.3.0", - "grunt-svn-copy": "^0.1.4", "grunt-text-replace": "^0.4.0", "install": "^0.10.2", - "jquery": "~1.12.4", - "jsdom": "11.12.0", + "jest": "^25.0.0", + "jquery": "^3.6.0", + "jsdom": "^16.5.3", "jsdom-global": "3.0.2", "load-grunt-tasks": "^3.5.0", - "mocha": "^5.2.0", - "node-sass": "^4.9.3", - "npm": "^6.11.3", - "prop-types": "^15.6.2", - "react": "^16.9.0", - "react-dom": "^16.9.0", - "rollup": "^0.64.1", - "rollup-plugin-babel": "^3.0.7", - "rollup-plugin-commonjs": "^9.1.5", - "rollup-plugin-html": "^0.2.1", - "rollup-plugin-includepaths": "^0.2.3", - "rollup-plugin-node-resolve": "^3.3.0", - "rollup-plugin-replace": "^2.0.0", - "rollup-plugin-uglify": "^4.0.0", - "sprintf-js": "^1.1.0", - "underscore": "~1.8.3" - }, - "scripts": { - "test-dfv": "node node_modules/mocha/bin/mocha --compilers js:babel-core/register --reporter dot --recursive tests/js", - "build-podsjs": "node node_modules/rollup/bin/rollup -c", - "scss": "node-sass --output-style compressed ui/styles/src -o ui/styles/dist", - "scss:watch": "node-sass --output-style compressed -w ui/styles/src -o ui/styles/dist", - "version_number": "grunt version_number" + "lodash": "^4.17.21", + "mocha": "^6.1.3", + "node-sass": "^4.14.1", + "npm": "^6.14.12", + "prop-types": "^15.7.2", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "rememo": "^3.0.0", + "sass-loader": "^7.1.0", + "sprintf-js": "^1.1.2", + "style-loader": "^0.23.1", + "terser-webpack-plugin": "^1.4.5", + "underscore": "~1.12.1", + "webpack": "^4.46.0", + "webpack-cli": "^3.3.12", + "webpack-merge": "^4.2.1" }, - "dependencies": {} + "dependencies": { + "@dnd-kit/core": "^3.1.1", + "@dnd-kit/modifiers": "^3.0.0", + "@dnd-kit/sortable": "^4.0.0", + "@dnd-kit/utilities": "2.0.0", + "@reduxjs/toolkit": "^1.5.1", + "@tippyjs/react": "^4.2.5", + "codemirror": "^5.60.0", + "faker": "^4.1.0", + "html-react-parser": "^0.13.0", + "immutability-helper": "^3.1.1", + "memoize-one": "^5.1.1", + "moment": "^2.29.1", + "react-codemirror2": "^7.2.1", + "react-datetime": "^3.1.1", + "react-quill": "^2.0.0-beta.4", + "react-select": "^4.3.1", + "sanitize-html": "^1.27.1", + "uuid": "^8.3.2" + } } diff --git a/phpcs.xml.dist b/phpcs.xml similarity index 100% rename from phpcs.xml.dist rename to phpcs.xml diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index ce3391a409..0000000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,30 +0,0 @@ - - - - tests - tests/phpunit/ - - - - - - . - - - ./includes - init.php - - - - - - - - diff --git a/readme.txt b/readme.txt index 0629988903..f24bc86bf7 100644 --- a/readme.txt +++ b/readme.txt @@ -1,28 +1,31 @@ === Pods - Custom Content Types and Fields === -Contributors: sc0ttkclark, keraweb, jimtrue, pglewis, quasel, jamesgol, ramoonus, nicdford, Shelob9, clubduece, dan.stefan, Desertsnowman, curtismchale, mgibbs189, mikedamage, jchristopher, pcfreak30 -Donate link: https://pods.io/friends-of-pods/ -Tags: pods, custom post types, custom taxonomies, content types, custom fields, cck, database, user fields, comment fields, media fields, relationships, drupal -Requires at least: 4.5 +Contributors: sc0ttkclark, zrothauser, keraweb, jimtrue, quasel, nicdford, jamesgol, ramoonus, pglewis, dan.stefan, Desertsnowman, mgibbs189, Shelob9, clubduece, curtismchale, mikedamage, jchristopher, pcfreak30 +Donate link: https://friends.pods.io/ +Tags: pods, custom post types, custom taxonomies, content types, custom fields, block +Requires at least: 5.5 Tested up to: 5.8 -Requires PHP: 5.3 -Stable tag: 2.7.31 +Requires PHP: 5.6 +Stable tag: 2.8.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html -Pods is a framework for creating, managing, and deploying customized content types and fields. +Pods is a framework for creating, managing, and deploying customized content types and fields for any project. == Description == Manage all your custom content needs in one location with the Pods Framework. -* **Create content types** including custom post types, custom taxonomies and advanced content types using custom tables (separate from WordPress) -* **Extend and customize content types** including posts, pages, categories, tags, users, and media +* **Create content types** including Custom Post Types, Custom Taxonomies, and our special Advanced Content Types (ACTs get their own custom tables) +* **Extend and customize content types** including Posts, Pages, Categories, Tags, Users, and Media with one easy click * **Create custom settings pages** easily within seconds -* **Add custom fields** to *any* content type or settings page -* **Show your fields** anywhere using our [shortcodes](https://docs.pods.io/displaying-pods/pods-shortcode/), [widgets](https://pods.io/2015/05/03/podscast-005-templates-shortcodes-widgets-displaying-data-in-pods-pt-3/), the code-free [Pods Template](https://pods.io/2015/05/03/podscast-005-templates-shortcodes-widgets-displaying-data-in-pods-pt-3/) approach, or our [automatic theme integration](https://docs.pods.io/displaying-pods/wordpress-theme-templates/) -* **Create connections** between any of your content with [relationship fields](https://docs.pods.io/fields/relationship-fields/) to keep your content organized +* **Add custom fields** to *any* content type +* **Group your fields** however you'd like into their own sections and add additional headings to help organize +* **Show your fields** anywhere using our [blocks](https://docs.pods.io/displaying-pods/pods-blocks/), [shortcodes](https://docs.pods.io/displaying-pods/pods-shortcode/), [widgets](https://docs.pods.io/displaying-pods/pods-widgets/), or the non-coder [Pods Template](https://docs.pods.io/displaying-pods/pods-templates/) approach along with our [automatic theme integration](https://docs.pods.io/displaying-pods/pods-templates/auto-templates/) +* **Create connections** between any of your content with [relationship fields](https://docs.pods.io/fields/relationship/) to keep your content organized -Let Pods help you grow your development skills and manage content beyond the standard WordPress Posts & Pages. Check out our [Documentation](https://docs.pods.io/), [Support Forums](https://wordpress.org/support/plugin/pods/), and our [Live Slack Chat](https://pods.io/chat/) to help you build your dream project with Pods. +Let Pods help you grow your development and site building skills so that you can manage content beyond the standard WordPress Posts & Pages. + +Check out our [Documentation](https://docs.pods.io/), [Support Forums](https://wordpress.org/support/plugin/pods/), and our [Live Community Slack Chat](https://support.pods.io/chat/) for assistance building your dream project with Pods. = Introduction = @@ -30,53 +33,21 @@ Let Pods help you grow your development skills and manage content beyond the sta = Content types that evolve with your needs = -Create any type of content that you want -- small or large -- we've got you covered. Every content type created with Pods gets all the love it needs to grow up big and strong. You'll get an easy to use interface that lets you manage custom fields and how your content type will look or function. +Create any type of content that you want -- small or large -- we've got you covered. Every content type created with Pods gets all the love it needs to grow up big and strong. You'll get an easy-to-use interface that lets you manage field groups, custom fields, and how your content type will look or function. = Create new content types = With Pods, you can create entirely new content types and settings pages. -* **Custom Post Types** - Content types that look and function like Posts and Pages, but in their own separate sections of WordPress -* **Custom Taxonomies** - Content types that look and function like Categories and Tags, but in their own separate sections of WordPress -* **Custom Settings Pages** - Create custom settings under Settings menu to help organize your site's custom global settings -* **Advanced Content Types** - These are entirely separate from WordPress and function off their own database tables (much like the [Drupal CCK](https://www.drupal.org/project/cck)) - -= Extend existing content types = - -Need to customize your existing content types in WordPress? We offer the ability to extend existing content types across all of WordPress: += Every Field Type, FREE = -* **Post Types** - Customize and create/manage fields for any existing post type -- Posts, Pages, and even those created by plugins or themes -* **Taxonomies** - Customize and create/manage fields for any existing taxonomy -- Categories, Tags, and even those created by plugins or themes -* **Media** - Create and manage fields for your media uploads to enable you to fill in additional information and context to any image/file you want -* **Users** - Create and manage fields for your user/author profiles -* **Comments** - Create and manage fields for your visitor comments, easily add fields to fit the way you use comments as reviews and more +We have an extensive collection of over [25 different input types to choose from on 20+ different field types for any content structure](https://docs.pods.io/fields/). Each field type comes with their own additional options to help you customize content entry and display. You can also control visibility by role/capability and [other advanced options](https://docs.pods.io/fields/settings-advanced/). -= Field Types = - -We have an extensive collection of fields that you can leverage to build the perfect content structure for your site. You can also build your own custom field types with our extensible field type classes. - -* **Text** - * Plain Text - * Website - * Phone - * E-mail - * Password -* **Paragraph** - * Plain Paragraph Text - * WYSIWYG (Visual Editor) - * Code (Syntax Highlighting) -* **Date / Time** - * Date and Time - * Date - * Time -* **Number** - * Plain Number - * Currency (30+ international currencies) -* **Relationships / Media** - * File / Image / Video - * Avatar (for extended Users) - * oEmbed - * Relationship +* **Text:** Plain Text, Website, Phone, Email, Password +* **Paragraph:** Plain Paragraph Text, WYSIWYG (Visual Editor), Code (Syntax Highlighting) +* **Date / Time:** Date and Time, Date, Time +* **Number:** Plain Number, Currency (30+ international currencies) +* **Relationships / Media:** File / Image / Video (Media library and basic upload options available), Avatar (for extended Users), oEmbed, Relationship (Dropdown, Multi Select, Autocomplete, Checkboxes, Radio Buttons, and List View available) * **Checkbox** (Yes / No) * **Color Picker** @@ -85,60 +56,49 @@ We have an extensive collection of fields that you can leverage to build the per The power is in your hands with our comprehensive support to **relate your content to anything**. * **Custom defined lists** of text options -* Relate to **Post Type** content -* Relate to **Taxonomy** content +* Relate to any **Post Type or Taxonomy** posts / terms * Relate to any **User** profile -* Relate to **User Roles** -* Relate to **User Capabilities** -* Relate to **Media** attachments +* Relate to **User Roles or Capabilities** * Relate to any **Comment** And many other relationships are also available including: * **Image Sizes** * **Navigation Menus** -* **Post Formats** -* **Post Status** * Relate to content within **any Database Table** -* **Themes** -* **Page Templates** -* **Sidebars** -* **Post Type Objects** (choose the post type itself) -* **Taxonomy Objects** (choose the taxonomy itself) * **Countries** (predefined) * **US States** (predefined) * **Canadian Provinces** (predefined) * **Calendar - Days of Week** (predefined) * **Calendar - Months of Year** (predefined) +* And many more! = Optional Components to do even more = You can enable some of our included components to extend your WordPress site even further: -* **Roles and Capabilities** - Create or edit Roles for your site, and customize their corresponding capabilities -* **Templates** - Use our template engine to create templates that can be handed off to clients for care-free management -* **Advanced Relationships** - Add advanced relationship objects for relating to including Database Tables, Multisite Networks, Multisite Sites, Themes, Page Templates, Sidebars, Post Type Objects, and Taxonomy Objects -* **Advanced Content Types** - These types of content were built into Pods prior to 2.3, but are now optionally enabled -* **Table Storage** - Enable table-based storage for custom fields on Post Types, Media, Users, and Comments. Also adds the ability to add custom fields to Taxonomies -* **Markdown Syntax** - Parses Markdown Syntax for Paragraph Text / WYSIWYG fields -* **Pages** - Create custom pages that function off of your site's URL path, with wildcard support, and choose the Page Template to use +* **Pods Templates** - Use our [template engine](https://docs.pods.io/displaying-pods/pods-templates/) to create templates that can be handed off to clients for care-free management +* **Markdown Syntax** - Parses [Markdown Syntax](https://www.markdownguide.org/basic-syntax) for Paragraph Text / WYSIWYG fields +* **Advanced Relationships** - Add even more relationship objects including Database Tables, Multisite Networks, Multisite Sites, Themes, Page Templates (in the theme), Sidebars, Post Type Objects, and Taxonomy Objects +* **Table Storage** - Enable table-based database storage for custom fields on Post Types, Media, Users, and Comments +* **Roles and Capabilities** - Create or edit Roles for your site and customize what they have access to +* **Advanced Content Types** - Create entirely custom content types that have their own database table, and they will exist outside the normal WordPress context avoiding meta database tables +* **Pods Pages** - Create custom pages that function off of your site's URL path with wildcard support and choose the Page Template in the theme to use -- most useful paired with Advanced Content Types = Plays well with others = We also do our best to integrate and play nicely with other projects: * **Plugins we've integrated with** - * [Tabify Edit Screen](http://wordpress.org/plugins/tabify-edit-screen/) - * [Codepress Admin Columns](http://wordpress.org/plugins/codepress-admin-columns/) - * [Polylang](http://wordpress.org/plugins/polylang/) - * [YARPP](http://wordpress.org/plugins/yet-another-related-posts-plugin/) - * [WPML](http://wpml.org/) + * [Beaver Builder](https://www.wpbeaverbuilder.com/) and [Beaver Themer](https://www.wpbeaverbuilder.com/beaver-themer/) using the [Pods Beaver Themer Add-On](https://wordpress.org/plugins/pods-beaver-builder-themer-add-on/) + * [Codepress Admin Columns](https://wordpress.org/plugins/codepress-admin-columns/) using the [Pods Add-On for Admin Columns Pro](https://www.admincolumns.com/pods/) * [Conductor](https://conductorplugin.com/) - * [Timber](http://upstatement.com/timber/) - * [Gravity Forms](http://www.gravityforms.com/) Using the [Pods Gravity Forms Add-on](https://wordpress.org/plugins/pods-gravity-forms/) - * [Beaver Builder](https://www.wpbeaverbuilder.com/) and [Beaver Themer](https://www.wpbeaverbuilder.com/beaver-themer/) Using the [Pods Beaver Themer Add-On](https://wordpress.org/plugins/pods-beaver-builder-themer-add-on/) + * [Gravity Forms](https://www.gravityforms.com/) using the [Pods Gravity Forms Add-on](https://wordpress.org/plugins/pods-gravity-forms/) + * [Polylang](https://wordpress.org/plugins/polylang/) + * [Timber](https://wordpress.org/plugins/timber-library/) + * [WPML](http://wpml.org/) + * [YARPP](http://wordpress.org/plugins/yet-another-related-posts-plugin/) * **Themes we've integrated with** - * [Builder](http://www.ithemes.com/) (iThemes) - * [Genesis](http://www.studiopress.com/) (StudioPress) + * [Genesis](https://www.studiopress.com/themes/genesis/) (StudioPress) == Installation == @@ -151,1044 +111,72 @@ OR you can just install it with WordPress by going to Plugins >> Add New >> and == Frequently Asked Questions == -= Where do we go for Support on your plugin? = += Where do I go for Support on your plugin? = -Our primary Support is handled through our [Support Forums](https://wordpress.org/support/plugin/pods/). For the fastest support, you can contact us on our [Live Slack Chat](https://pods.io/chat/) in the #support channel. We do not staff our Slack channel 24/7, but we do check any questions that come through daily and reply to any unanswered questions. +Our primary Support is handled through our [Support Forums](https://wordpress.org/support/plugin/pods/). For the fastest support, you can contact us on our [Live Community Slack Chat](https://support.pods.io/chat/) in the #support channel. We do not staff our Slack channel 24/7, but we do check any questions that come through daily and reply to any unanswered questions. -We do have a community of Pods users and developers that hang out on Slack so you're sure to get an answer quickly. We answer our Forum questions once a week with follow-up during the week as we're prioritizing resources towards restructuring and improving our documentation. +We do have a community of Pods users and developers that hang out on Slack, so you're sure to get an answer quickly. We answer our Forum questions once a week with follow-up during the week as we're prioritizing resources towards restructuring and improving our documentation. -= I've found a Bug or I have a Feature Request = += Where do I report bugs or request features? = -If youโ€™ve uncovered a Bug or have a Feature Request, we kindly request you to create an Issue on our GitHub Repository at [https://github.com/pods-framework/pods/issues/new](https://github.com/pods-framework/pods/issues/new). Please be very specific about what steps you did to create the issue youโ€™re having and include any screenshots or other configuration parameters to help us recreate or isolate the issue. +If youโ€™ve encountered a bug or have an idea for a new feature, we kindly request you to create an Issue on our GitHub Repository at [https://github.com/pods-framework/pods/issues/new](https://github.com/pods-framework/pods/issues/new). Please be very specific about what steps you did to create the issue youโ€™re having and include any screenshots or other configuration parameters to help us recreate or isolate the issue. = Will Pods work with my Theme? = -Most likely the answer is yes. We don't require any special CSS or display attributes to use Pods with your theme so you should have little to no difficulty showing your content in your theme. If you encounter any issues, contact your theme developer and ask them about their support for the standard WordPress theming functions and how to use [WordPress Template Hierarchy](https://wphierarchy.com) with their theme. - -== Screenshots == - -1. Create new content types or extend existing ones -2. Add fields of many different types, with individual options for each so you can define your content type to be what you need it to be -3. Post Type pods will add fields to the Post editor -4. Taxonomy pods will add fields to the Taxonomy forms -5. User pods will add fields to the User forms -6. Comment pods will add fields to the Comment forms -7. Media pods will add fields to the Media forms -8. Create Advanced Content Types that exist only as you define them, outside of the normal WP object structure - -== Contributors == - -Pods really wouldn't be where it is without all of the contributions from our [donors](https://friends.pods.io) and [code/support contributors](https://github.com/pods-framework/pods/graphs/contributors). - -== Translations == - -Many thanks go out to the fine folks who have helped us translate Pods into many other languages. - -Join us in further translating the Pods interface at: [https://translate.wordpress.org/projects/wp-plugins/pods](https://translate.wordpress.org/projects/wp-plugins/pods) - -We are also available through our [Live Slack Chat](https://pods.io/chat/) to help our translators get started and to support them on the process. - -== Changelog == - -= 2.7.31 - September 23rd, 2021 = - -* Pods 2.8 is coming on October 11th! Check out the [Pods 2.8 Field Guide](https://pods.io/2021/02/11/pods-2-8-beta-1-released-and-the-field-guide-to-pods-2-8/) for more information. -* Fixed: Resolve issues where searching a Pod would cause queries like `post_title.t` or `display_name.t` unexpectedly. #6050 (@sc0ttkclark, @unknownnf) - -= 2.7.30 - August 12th, 2021 = - -* Fixed: Prevented a few PHP notices from showing on the new WordPress 5.8+ widgets screen. - -= 2.7.29 - August 4th, 2021 = - -* Security: Clean up post type and taxonomy labels so they avoid potential output escaping problems in WordPress core (@sc0ttkclark, reported by Muhammad Daffa via WPScan) -* Friends of Pods: Updated CTA text about our 2021 donor goals. (@sc0ttkclark) -* Added: Support for Timezones in datetime / time fields. #6042 (@JoryHogeveen) -* Added: Support for Pantheon WP Native Sessions plugin. (@sc0ttkclark) -* Enhancement: Optimized the PNG image assets using PNG8+Alpha with ImageAlpha and ImageOptim. #6028 (@lowwebtech) -* Fixed: Hidden fields now properly submit correctly. (@sc0ttkclark) -* Fixed: Post type `has_archive` no gets set to a false properly when disabled. #6069 (@JoryHogeveen) -* Fixed: Resolve PHP `strlen()`` warnings when validating text values being saved. #6062 (@pd-cm, @sc0ttkclark, @JoryHogeveen) -* Fixed: Sorting URLs in `PodsUI` include `post_type` and `taxonomy` when Advanced Content Types are set to be underneath a Post Type's top level menu. #6040 (@JoryHogeveen) -* Fixed: Fallback to the manage fields in `PodsUI` for reordering when reorder fields are not overridden. #6058 (@JoryHogeveen) -* Fixed: Depend on plupload when showing custom upload directory option for file fields. (@JoryHogeveen) - -= 2.7.28 - May 20th, 2021 = - -* Added: New upload directory option for File fields using Plupload that lets you choose to customize which directory the files end up in. #6021 (@JoryHogeveen) -* Added: Relationship fields now support custom selectors in the REST API. You can specify `my_field.some_field` to output a specific field in your REST API options for each relationship field. (@sc0ttkclark) -* Added: New `pods_image_for_post()` and `pods_image_url_for_post()` functions have been added for certain page builders like Oxygen. (@sc0ttkclark) -* Added: New query variable prefix option (`num_prefix`) for PodsUI instances. (@sc0ttkclark) -* Added: `pagination_type` and `pagination_location` options for PodsUI instances to support more flexible pagination options. (@sc0ttkclark) -* Enhancement: Implement `search` and `sort` field sets for PodsUI instances to more easily specify which fields are searchable or sortable. (@sc0ttkclark) -* Fixed: PHP fatal errors no longer occur for avatar fields in certain situations. #6007 (@JoryHogeveen) -* Fixed: PHP fatal errors no longer occur for PHP 8 in certain situations. #6012 (@JoryHogeveen) -* Fixed: Resolved an issue with relationship fields not outputting their full data to the REST API when the related object is not a valid pod. (@sc0ttkclark) -* Fixed: Resolved an issue with not saving the fields for the extended Media pod when making update requests through the REST API. (@sc0ttkclark) -* Fixed: Implemented a temporary PHP 7.4+ fix for Freemius. (@sc0ttkclark) -* Fixed: Searching WP-based objects in PodsUI interfaces now resolves to the proper fields. (@sc0ttkclark) - -= 2.7.27 - April 20th, 2021 = - -* Added: Support taxonomy and other object field filters in Pods::find(). #5994 (@JoryHogeveen) -* Added: WP 5.7 `filter_by_item` and `filter_by_date` labels. #5959 (@JoryHogeveen) -* Added: `pagination_type` shortcode param. #5977 (@JoryHogeveen) -* Enhancement: Allow ID as parameter for `pods_audio()` and `pods_video()`. #5999 (@JoryHogeveen, @sc0ttkclark) -* Enhancement: Use correct pagination item classes. #5179 (@JoryHogeveen) -* Fixed: Polylang compatibility for populating default field values. #5879 (@Chouby, @JoryHogeveen) -* Fixed: Prevent incorrect sanitizing of option fields since 2.7.25. #5909 (@JoryHogeveen) -* Fixed: Traversal display filters for single and multiple relationships. #5985 (@JoryHogeveen) -* Fixed: Support capitalized file extensions. #5975 (@sc0ttkclark, @JoryHogeveen) -* Fixed: Resolved PHP notice in the PodsAPI. #5952 (@JoryHogeveen, @sc0ttkclark) -* Fixed: Resolved PHP notice when using `?pods_debug_sql=1` on Pods Admin UI screens. (@sc0ttkclark) -* Fixed: Stop tracking Freemius add-ons and rely on just Pods itself. #5981 (@sc0ttkclark) -* Fixed: Prevent potentially unsafe HTML tags from being used in admin menu text. (@sc0ttkclark, props to Hagai Wechsler and Daniel Elkabes from WhiteSource Software) - -= 2.7.26 - January 8th, 2021 = - -* Fixed: Prevent PHP warnings in the `components/Templates/includes/element-pod_reference.php` file. #5914 (@JoryHogeveen) -* Added: New filter `pods_shortcode_detect_from_current_post` allows you to override whether a shortcode should detect the post object outside of the loop (default is only when `in_the_loop()`). This helps to fix problems that are part of the integration which the free Pods Beaver Themer Add-On uses. (@sc0ttkclark) - -= 2.7.25 - December 28th 2020 = - -**New Features & Enhancements** - -* Added: Custom no access message for templates. #5875 (@JoryHogeveen) -* Added: New filter `pods_field_validate_{$type}`. #1106 (@JoryHogeveen) - -**Bug Fixes** - -* Fixed: Ensure compatibility with the WordPress 5.6 jQuery update. #5892, #5896 & #5897 (@JoryHogeveen) -* Fixed: Prevent `wp_unslash()` from unnecessarily over sanitizing input. #5040 & #4424 (@JoryHogeveen) -* Fixed: Prevent issues with HTML entities in custom relationship values when it gets to JavaScript. #5894 (@JoryHogeveen) -* Fixed: Better support multiple languages in the Relationship AJAX search. #5888 (@JoryHogeveen) -* Fixed: Include the `post_type` value in attachment saves so that the more WordPress core actions trigger. #5748 (@JoryHogeveen) -* Fixed: Allow `the_excerpt` to be used as custom filter on singular pages. #5899 (@JoryHogeveen) -* Fixed: Better support caching of the avatar images/data and integrate with the `get_avatar_data` filter. #5771 (@JoryHogeveen) - - -= 2.7.24 - November 5th 2020 = - -**Bug Fixes** - -* Fixed: Fix media `[each]` loop if no `media` Pod exists. #5882 (@JoryHogeveen) -* Fixed: Fallback to default display field if custom option is invalid for relationship fields. #5839 & #5859 (@JoryHogeveen) -* Fixed: Use `pathinfo` to properly validate file extension. #5876 (@JoryHogeveen) - -= 2.7.23 - October 30th 2020 = - -**New Features & Enhancements** - -* Added: Support auto-templates for taxonomies, users and comments. #3962 & #5832 (@JoryHogeveen, @sc0ttkclark, @gwhitney) -* Added: Support template parameter and nested shortcode content for field shortcodes. #5801 (@JoryHogeveen) -* Added: Allow function calls in all tags, not just template tags. #4887 (@JoryHogeveen) -* Added: Support custom image sizes for all image field types in magic tags. #5870 (@JoryHogeveen) -* Added/Fixed: Support special magic tags in Pods Templates. #5697 (@JoryHogeveen) -* Added/Fixed: Support Pod related magic tags in shortcode query parameters. #5734 (@JoryHogeveen) -* Enhancement: Allow traversing in avatar attachment. #5870 (@JoryHogeveen) -* Enhancement: If the media Pod exists, use it's context to run media loops to support other fields and traversal. #5855 (@JoryHogeveen) -* Enhancement: Implement PHP 5.4 `session_status()` function. #5840 (@JoryHogeveen) -* Enhancement: Allow WP objects to be passed in `pods()`. #5845 (@JoryHogeveen) -* Compatibility: Enqueue DFV scripts when editing the page with Beaver Builder to fully support the media window. #5799 (@JoryHogeveen) -* Updated: Primary Branch header for GitHub Updater. #5847 (@afragen) - -**Bug Fixes** - -* Fixed: `.src` tags for PDF's now render the PDF file link instead of the thumbnail in templates `[each]` loops. #4040 (@JoryHogeveen) -* Fixed. HTML entities for relationship fields UI. #5843, #5835 & #5796 (@JoryHogeveen, @sc0ttkclark) -* Fixed: Select2/SelectWoo now also enqueue the locale files when available. #5860 (@JoryHogeveen) -* Fixed: Support lowercase ID's for magic tags in media loops #5852 (@JoryHogeveen, @sc0ttkclark) -* Fixed: Avatar should always return a square image. #2738 (@JoryHogeveen) -* Fixed: Selected items query for autocomplete relationships. #5542 & #5831 (@JoryHogeveen) -* Fixed: Prevent SQL errors on magic tags in some cases. #5797 (@JoryHogeveen, @sc0ttkclark) -* Fixed: Error if there is no DB prefix available. #5803 (@JoryHogeveen, @sc0ttkclark) -* Fixed: Fix edge case "No Access" error when all Pods were deleted. Redirect to next Pod admin page if needed. #4842 (@JoryHogeveen) -* Fixed: Removed empty filter in `ui/admin/setup-edit-field.php`. #5686 (@sc0ttkclark, @JoryHogeveen) -* Fixed: Prevent possible notice if image doesn't exist. #5866 (@JoryHogeveen) -* Fixed: Remove source maps from production builds. #5822 (@sc0ttkclark) -* Fixed: PHP warning in file field gallery view. #5809 (@JoryHogeveen) - -= 2.7.22 - August 13th 2020 = - -**Bug Fixes** - -* Fixed: WP 5.5+ compatibility layer for postbox headers so they appear and work correctly while still working for previous versions of WordPress. #5806 (@sc0ttkclark) -* Fixed: Patched a Freemius JS file that needed updating for WP 5.5+ compatibility. #5806 (@sc0ttkclark) -* Fixed: Prevent fatal errors about memory when using preview links for Advanced Content Types. #5783 (@JoryHogeveen) -* Fixed: Prevent fatal errors about memory when using certain magic tag / thumbnail combinations. #5805 (@JoryHogeveen) -* Fixed: Resolve our DFV JS `
            ` issues with `PodsUI` filters and add `.toggle-row` class handling for frontend. #5806 (@sc0ttkclark) -* Fixed: Ensure REST API responses for Media returns correct value when extended by Pods. #5763 (@JoryHogeveen) -* Fixed: Ensure pods_permission() unserializes when role/capability data is serialized. #5768 (@JoryHogeveen) - -= 2.7.21 - June 30th 2020 = - -**New Features & Enhancements** - -* Added: New filter: `pods_field_pick_object_data_params`. #5756 (@JoryHogeveen) -* Added: Pods fields & magic tags: Traverse through serialized metadata. #5603 (@JoryHogeveen) -* Added: Support `get_query_var()` in pods_v (and thus special magic tags: `{@query.##}`). #5719 (@JoryHogeveen) -* Added: WYSIWYG field option for custom editor height. #5673 (@JoryHogeveen) -* Enhancement: REST field options: Only display depth for array response type. #5714 (@JoryHogeveen) -* Updated: Refactor Pods::field() method. #5682 (@JoryHogeveen) - -**Bug Fixes** - -* Fixed: Relationship dropdown error & encoding. #5740 (@JoryHogeveen) -* Fixed: Getting single vs multiple metadata values edge case errors. #5661 (@JoryHogeveen) -* Fixed: Nested relationship fields should render as array of objects in REST. #5745 (@lkraav) -* Fixed: Add `noopener` and `noreferrer` for all target `_blank` links. #5742 (@JoryHogeveen) -* Fixed: Only check `delete_users` for single installations in `pods_is_admin()`. #5712 (@JoryHogeveen) -* Fixed: Deprecated taxonomy form actions. #5700 (@JoryHogeveen) -* Fixed: DateTime field: Allow input values compatible with the display format. #5687 (@JoryHogeveen) -* Fixed: Whitespace trimming for templates. #5672 (@sc0ttkclark) -* Fixed: Taxonomy option rewrite with front label tooltip. #5681 (@JoryHogeveen) -* Fixed: Pods test factory compatibility with WP core text factory. #5716 (@JoryHogeveen) - -= 2.7.20.1 - June 4th 2020 = - -* Security: Remove deprecated usage of escapeMarkup in selectWoo and tighten JS rendering (@sc0ttkclark, @miha.jirov) - -= 2.7.20 - April 5th 2020 = - -**Bug Fixes** - -* Fixed: Resolved issues with Freemius notices not being able to be properly dismissed. (@sc0ttkclark) - -= 2.7.19 - April 5th 2020 = - -This version was bugged due to a deployment that sent out a copy of 2.7.18 as 2.7.19. - -= 2.7.18 - April 3rd 2020 = - -**New Features & Enhancements** - -* Added: Add is_required() helper method for fields objects to abstract some logic. #5657 (@JoryHogeveen) -* Updated: Removed duplicate code from pods_list_filter() that is now in wp_list_filter(). #5644 (@JoryHogeveen) -* Updated: Now prefixing the Templates and Pages component menu items with "Pod" so they aren't as easily confused with normal WordPress menu items. #5647 (@JoryHogeveen) - -**Bug Fixes** - -* Fixed: Compatibility layer for ACF so it won't conflict anymore. #5667 (@sc0ttkclark) -* Fixed: Remove PHP 5.6+ only code that was causing issues for those running older PHP versions. #5659 (@JoryHogeveen) -* Fixed: Prevent PHP errors when enforcing numeric values during validation of number fields. #5666 (@JoryHogeveen) -* Fixed: Prevent deprecated warnings with special magic tags usage like `{@user.id}` instead of `{@user.ID}`. #5642 (@JoryHogeveen) -* Fixed: Fix the decimal/thousands separator logic used for number and currency field validation and saving. #5653 (@JoryHogeveen) -* Fixed: Resolve issues with `[if]` and `[else]` logic for boolean fields that was causing it to always evaluate to true. #5656 (@JoryHogeveen) -* Fixed: Only load Freemius on Pods Admin, Plugins, or the Updates screens. (@sc0ttkclark) - -= 2.7.17.1 - March 27th 2020 = - -**Bug Fixes** - -* Fixed: Double comma in custom pick display formats. #5637 (@JoryHogeveen) -* Fixed: Auto `use_current` not working correctly outside the loop. #5636 (@JoryHogeveen) -* Fixed: pods_trim() does not trim whitespaces by default. #5640 (@JoryHogeveen) - -= 2.7.17 - March 26th 2020 = - -**New Features & Enhancements** - -* Added: New callout for our Friends of Pods program will show up on the Pods Admin > Pods list so we can let people know how to donate. #5571 (@nicdford, @sc0ttkclark, @JoryHogeveen) -* Added: Freemius integration to support our new Friends of Pods add-ons and enable us to let people opt-in to usage stats for planning future compatibility decisions. #5624 (@sc0ttkclark) -* Added: New `not_found` tag to the Pods shortcode to return default string if no output is empty. #5580 (@JoryHogeveen) -* Added: New hooks when saving field table definitions (table-based Pods). #5623 (@sc0ttkclark) -* Added: New custom multi-relationship display format. #5612 (@JoryHogeveen) -* Added: Support traversing into post thumbnails objects. #5610 (@JoryHogeveen) -* Compatibility: Add ACF backwards compatibility functions/shortcode. #4855 (@sc0ttkclark) -* Compatibility: WordPress 5.4 - Add user Pod fields to privacy export data. #5606 (@JoryHogeveen) -* Compatibility: Match WordPress 5.4 CSS changes. #5608 (@JoryHogeveen) -* Enhancement: Shortcodes now automatically revert to the current queried object. #5598 (@JoryHogeveen) -* Enhancement: Add "full" to available image sizes. #5185 (@JoryHogeveen) -* Enhancement: Set Pods current queried object detection based on class instances instead of class parameters. #5617 (@JoryHogeveen) -* Docs: Update inline docs for pick field selected logic. #5014 & #5017 (@sc0ttkclark) - -**Bug Fixes** - -* Fixed: Date/Time - Correct empty value validation. #5534 & #5544 (@JoryHogeveen) -* Fixed: Date/Time - Allow midnight (00:00:00) as time value. #5616 (@JoryHogeveen) -* Fixed: Number/Currency - Parsing error for number format 9'999.99. #5559 & #5597 (@JoryHogeveen) -* Fixed: Number/Currency - Do not set default value of `0` if field is empty. #5539 (@JoryHogeveen) -* Fixed: CLI export/export-item commands. #5041 (@0xLBF) -* Fixed: Allow No (0) as an answer for radio and select boolean fields. #5549 (@JoryHogeveen) -* Fixed: Prevent get_meta() cache loop. #5577 (@JoryHogeveen) -* Fixed: Pods component descriptions. #5543 (@JoryHogeveen) -* Fixed: PHP 7.4 - Array and string offset access syntax with curly braces is deprecated. #5582 (@JoryHogeveen) -* Fixed: PHP 7.4 - Trying to access array offset on value of type bool. #5556 & #5615 (@JoryHogeveen) -* Fixed: PHP 7.4 - Array access notices. #5631 (@JoryHogeveen) -* Fixed: Replaced hook used for meta boxes in admin for custom component integrations to avoid deprecated notices from WordPress. #5622 (@sc0ttkclark) -* Fixed: Prevented potential fatal errors on Pod Template editor screen when pod configuration is broken. #5622 (@sc0ttkclark) -* Docs: Link to Gallery Documentation in Image field inline help doc. #5541 (@wpacademy) - -= 2.7.16.2 - November 14th 2019 = - -* Fixed: The last SVN tag was temporarily missing files, this release just ensures people get the update that has all files. - -= 2.7.16.1 - November 13th 2019 = - -* Fixed: Reverted changes in #5289 to auto templates that introduced breaking changes. We will revisit this in a future maintenance release. #5531 - -= 2.7.16 - November 13th 2019 = - -**Enhancements** - -* Enhancement: CSS fixes for WP 5.3. #5501 (@JoryHogeveen) -* Enhancement: Format traversed fields properly. #4932 (@jamesgol) -* Enhancement: ACT list view pagination. #5510 (@JoryHogeveen) -* Enhancement: Add PODS_SHORTCODE_ALLOW_EVALUATE_TAGS to debug info. #5310 (@JoryHogeveen) - -**Bug Fixes** - -* Fixed: Avoid SQL errors when using special magic tags. #5310 (@sc0ttkclark) -* Fixed: Validate shortcode query tags before default to current object. #5520 (@JoryHogeveen) -* Fixed: Unslash simple relationship values to support saving quoted values. #5517 (@JoryHogeveen) -* Fixed: Add sanitize_title optional to sluggables instead of applying default. #5516 (@JoryHogeveen) -* Fixed: DateTime: Always parse any manual input data. Also fixes clearing values. #5488 (@JoryHogeveen) -* Fixed: DateTime: jQuery date & time picker overlapping formats. #5467 (@JoryHogeveen) -* Fixed: DateTime: Fix datetime-local HTML5 input format. #5460 (@JoryHogeveen) -* Fixed: Could not submit a form if required checkbox not ticked. #5481 (@Turkal) -* Fixed: Allow migrate packages to import pages. #5476 (@jamesgol) -* Fixed: Allow pods_str_replace() function to handle non-strings. #5254 (@jamesgol) -* Fixed: Refactor and fix issues with Advanced Content Types capabilities. #5504 (@JoryHogeveen) -* Fixed: Add `object` key to prevent undefined index notice. #5493 (@JoryHogeveen) -* Fixed: Make sure number of arguments passed to PodsMeta->save_post() is correct. #5512 (@jamesgol) -* Fixed: ACT pagination URL for child type. #5510 (@JoryHogeveen) -* Fixed: Custom table relationships SQL error. #5505 (@JoryHogeveen) -* Fixed: Allow Pods to ALTER table if the SQL field definition has changed. #5507 (@jamesgol) -* Fixed: Admin menu: set hook priority to 9 instead of 99 to fix CPT submenu placement. #5497 (@JoryHogeveen) -* Fixed: Make auto templates for a Taxonomy Pod behave sensibly. #5289 (@gwhitney, @sc0ttkclark, @JoryHogeveen) - -= 2.7.15 - September 5th 2019 = - -**Enhancements** - -* Enhancement: Add year range option to date & datetime fields. #5442 (@JoryHogeveen) -* Enhancement: Support single select relationships in templates when using `[each]`. #4507 (@sc0ttkclark, @JoryHogeveen) -* Enhancement: Prevent creation of Pods using reserved keywords from WordPress Codex and Pods. #5428 (@JoryHogeveen) -* Enhancement: Allow all callables to be passed in magic tags. #5436 (@JoryHogeveen) - -**Bug Fixes** - -* Fixed: Always convert database value for date/time fields without timezone to maintain the actual value. #5423 & #5424 (@JoryHogeveen) -* Fixed: Solve issues with saving date/time fields in other locales. #5444, #5421, #5415 & #5451 (@JoryHogeveen) -* Fixed: Import from file with absolute path. #5430 (@mistraloz) -* Fixed: Fix numeric soft format issue removing decimals & numeric slider input formatting. #5281 & #5215 (@JoryHogeveen) -* Fixed: Fix & improve error handling & debug logs. #5452, #5450, #5440, #5419, #5435 & #5453 (@JoryHogeveen) -* Fixed: Corrected Malaysian Ringgit currency sign. #5446 (@JoryHogeveen) -* Fixed: Flush Pod cache before returning errors, #5420 (@JoryHogeveen) - -= 2.7.14 - July 9th 2019 = - -**Bug Fixes** - -* Fixed: Always convert database value for date/time fields with UTC timezone to maintain the actual value, #5382, #5402, #5403 (@JoryHogeveen) -* Fixed: Stop add new button from being disabled when no selection has been made yet for single select, #5401 (@pglewis) -* Fixed: Resolved PHP notices in `PodsAPI::save_pod_item()`, #5411 (@pglewis) +Most likely the answer is yes. We don't require any special CSS or display attributes to use Pods with your theme, so you should have little to no difficulty showing your content in your theme. If you encounter any issues, contact your theme developer and ask them about their support for the standard WordPress theming functions and how to use [WordPress Template Hierarchy](https://wphierarchy.com) with their theme. -= 2.7.13 - June 28th 2019 = +== How can I translate Pods into my own language? == -**Enhancements** +Many thanks go out to the fine folks who have helped us translate the Pods plugin into many other languages. -* Enhancement: Support meta fields as display field for relationships, #5299 (@sc0ttkclark) -* Enhancement: DateTime/Time field code and performance #5302 (@JoryHogeveen) -* Enhancement: Added Nigerian Naira currency, #5377 (@webcreativeng) -* Enhancement: Added filter `pods_enqueue_dfv_on_front` for enqueueing DFV scripts on frontend, #5313 & #5303 (@nicdford) -* Added: Add debug information for Pods to Site Health Info area, #5399 (@sc0ttclark, @JoryHogeveen) +Join us in further translating the Pods interface on the official [Translating WordPress dashboard](https://translate.wordpress.org/projects/wp-plugins/pods) -**Bug Fixes** +We are also available through our [Live Community Slack Chat](https://support.pods.io/chat/) to help our translators get started and to support them on the process. -* Fixed: Cursor is jumping to the start of the block when Gutenberg autosaves, #5274 (@pglewis) -* Fixed: Select drop-downs set to required, #5031 (@pglewis) -* Fixed: HTML escaping issue in the Manage Fields list, #5246 (@pglewis) -* Fixed: Translate Pods stuck with Portuguese translation in the Admin menus, #5259 (@JoryHogeveen) -* Fixed: option cache handling when using external object cache, #5294 (@sc0ttkclark) -* Fixed: Fix force WWW option on website/URL fields, #4881 (@pglewis) -* Fixed: Phone field should not put anything in the field input on 'blank' values, #4881 (@pglewis) -* Fixed: Versioned tag names are not compatible with Composer, #5278 (@pglewis) -* Fixed: `get_post_meta()` always retriggers `pods_transient_set()`, #4690 (@pglewis) -* Fixed: Date output in magic tags for date fields uses DateTime class by default instead of date_il8n, #5296 (@JoryHogeveen) -* Fixed: PHP 7.3 `compact()` notices due to undefined var names, #5266 (@sc0ttkclark) -* Fixed: Use `Marionette.noConflict()` to keep a private copy of Marionette, #5237 & #5354 (@pglewis) -* Fixed: Remove floats from fields within pods manage fields (UI), #5362 (@nicdford) -* Fixed: Set table charset for Pods Advanced Content Types to WP default charset, #5276 (@JoryHogeveen) -* Fixed: Avoid PHP warnings by removing unused $check_value logic in PodsField_Pick, #5205 (@ziqbal, @JoryHogeveen) -* Fixed: Fix PodsData fetch for when using object cache and settings pages, #4960 (@pcfreak30, @sc0ttclark, @JoryHogeveen) -* Fixed: Moved session_id() check outside the big conditional so it's always executed, #5182 (@mastef) -* Fixed: Change deprecated (since WP 5.1) hook `wpmu_new_blog` to `wp_insert_site` with backwards compatibility, #5369 (@JoryHogeveen) -* Fixed: Error when PodsInit isn't available on network pages, #3353 (@JoryHogeveen) -* Fixed: Shortcodes no longer stop the page from loading when they encounter SQL errors, #5279 (@sc0ttclark, @JoryHogeveen) +Are you looking to translate your Pods and Fields themselves? You'll want to enable the "Translate Pods" component from Pods Admin > Components. -= 2.7.12 - December 20th 2018 = - -**Enhancements** - -* Enhancement: Sort currency list alphabetically by name, add Indonesian Rupiah (Rp) and US Cent currency support, #5247 (@sc0ttkclark) - -**Bug Fixes** - -Fixed: Serial comma display works again for Users, Comments, and Media relationships when used in Pods::display() and magic tag templating without specifying the object field you want to display, #5251 (@sc0ttkclark) - -= 2.7.11 - December 7th 2018 = - -**Enhancements** - -* Enhancement: Added: New pods_data_auto_calculate_total_found filter can be set to true to auto-calculate total_found() number right away after a Pods::find() query runs, defaults to false, #5232, (@sc0ttkclark) - -**Bug Fixes** - -* Fixed: Javascript errors on pages without the Gutenberg editor active under certain circumstances, #5225 (@pglewis) -* Fixed: Avoid extra user queries when not necessary, #5230 (@sc0ttkclark) - -= 2.7.10 - December 5th 2018 = - -**Gutenberg / WordPress 5.0 Compatibility** - -* Fixed: TinyMCE Compatibility Bug for Gutenberg, #5217 (@pglewis) -* Fixed: Read-only Checkboxes now properly save values as 0 or 1, #4961 (@atanas-angelov-dev) -* Fixed: Scrollbar Compatibility bug for List View in Gutenberg Editor, #5220 (@pglewis) -* Fixed: Modal Support for Gutenberg, Add/edit Modal now triggers save and close to the modal, #5191 (@pglewis) -* Fixed: Component header parsing for developer/tableless mode, #5222 (@sc0ttkclark) -* Fixed: Currency symbol no longer overlays input field in WP 5.0, #5219 (@pglewis, @sc0ttkclark) - -**Enhancements** - -* Enhancement: Added support for new WP 5.0 custom post type labels used by Gutenberg, #5223 (@wpstudio, @sc0ttkclark) -* Enhancement: Add pods conditional logic handling on frontend forms, #5136 (@JoryHogeveen) -* Enhancement: Add current memory usage to stats, #5178 (@sc0ttkclark) -* Enhancement: Add support for Taxonomy descriptions, #4766 (@sc0ttkclark) -* Enhancement: Component Pages does not allow adding page templates in plugins, #4734 (@creabrain) -* Enhancement: Add Pods functions to Query Monitor conditional, #5208 (@JoryHogeveen) -* Enhancement: Add bi-directional status label to relationship fields, #5200 (@JoryHogeveen) -* Enhancement: Removed old forum feed, inserted the wordpress.org feed, and squelched warnings from SimplePie/PHP 7+, #5172, #4363 (@pglewis) - -**Bug Fixes** - -* Fixed: pods->save() does not clear fields with shorthand syntax, #5166 (@mastef) -* Fixed: Comma character breaks custom post type dropdown, #2042 (@sc0ttkclark) -* Fixed: Compatibility with Admin Columns 3.2+, #5129 (@JoryHogeveen, @DGStefan) -* Fixed: Missing Styles of DFV form field using $pods->form, #5056 (@pglewis) -* Fixed: "Single Select" Relationship Return differently depending on Format, #5138 (@pglewis) -* Fixed: Media modal doesn't work on frontend using pods form, #4715 (@pglewis) -* Fixed: Use minified versions of Backbone.Marionette and Backbone.Radio, #5115 -* Fixed: Always enqueue the DFV script by default if in the admin, #5111 (@pglewis, @sc0ttkclark) -* Fixed: Add static groups cache for PodsMeta::groups_get() to improve memory usage on bulk wp_insert_post and other similar calls, #5088 (@sc0ttkclark) -* Fixed: Only disable components when using PODS_TABLELESS if the component is relying on custom tables, #5206 (@JoryHogeveen) -* Fixed: PHP Warning for array key pods_rel not found, #5210 (@JoryHogeveen) - -= 2.7.9 - August 9th 2018 = - -**Features/Enhancements** - -* Added: Support for Pods::fields() argument keyed which when set to true will return the array for relationship fields with the IDs used as keys, #5092 (@sc0ttkclark) -* Added: pods_shortcode_output filter to allow customization of shortcode output based on shortcode attributes, #5083 (@sc0ttkclark) - -**Bug Fixes** - -* Fixed: Fix compatibility issue with Polylang & WPML when getting the current language from the edit post and edit tax pages. #5060 (JoryHogeveen) - -= 2.7.8 - July 26th 2018 = - -* Hotfix: Time field generates a fatal error on PHP prior to 5.5, #5079 (@davegaeddert) - -= 2.7.7 - July 26th 2018 = - -**Features/Enhancements/Improvements** - -* Code Quality: Disallow multiple assignments and assignment inside conditions, #5021 (@GaryJones) -* Code Quality: WordPress.WhiteSpace.PrecisionAlignment compliance, #5026 (@GaryJones) -* Code Quality: Use interpolation to construct all dynamic hook names, #4992 (@GaryJones) - -**Bug Fixes** - -* Fixed: 'others' capability checks for current_user_can pods_{$action}{$pod} vs pods{$action}others{$pod} capabilities, #5043 (@Ulminia, @sc0ttkclark) -* Fixed: "Export all" button for ACTs does not work, #5005 (@pglewis) -* Fixed: Pods Template Editor is adding two 'tabs' to the front of the template during Save. #5022 (@pglewis) -* Fixed: Midnight (00:00) results as 'empty' in an [if][/if] Template Tag. #4999 (@pglewis) -* Fixed: Non-internationalized string "Add Another Custom Capability". #5028 (@GaryJones, @pglewis) - -= 2.7.6 - June 8th 2018 = - -* Fixed: Records added modally via DFV's 'Add New' are not selected and don't refresh list view in 2.7.5, #5014 (@sc0ttkclark, @pglewis) - -= 2.7.5 - June 7th 2018 = - -**Bug Fixes** - -* Fixed: Only flush rewrite rules in an admin context, #5006 (@sc0ttkclark) -* Fixed: SelectWoo fields would sometimes call `focus()` inappropriately #4725 (@GaryJones) - -= 2.7.4 - June 6th 2018 = - -**Features/Enhancements** - -* Code Quality: Address some i18n code standard violations, #4982 (@GaryJones) -* Code Quality: All @since and @deprecated tags updated to use three digits everywhere, #4995 (@GaryJones) -* Added: Tooltip for the Hierarchical option for taxonomies, #4949 (@pglewis) - -**Bug Fixes** - -* Fixed: jQuery.fn.size() is deprecated #3898 (@GaryJones) -* Fixed: CLI: Fix missing negation on valid & exists checks #4989 (@GaryJones) -* Fixed: Check for localized 'help' before adding tooltip #4614 (@davidatwhieltrue, @GaryJones) -* Fixed: Autocomplete/List View broken with "Other WP Objects", #4504 (@pglewis, @sc0ttkclark) -* Fixed: HTML entities in a field's description are converted when the Pod is loaded again, #4495 (@pglewis) -* Fixed: Relationship fields related to the _pods_pod or _pods_field post type would not return the correct value, #4979 (@sc0ttkclark) -* Fixed: Code Editor for Pods Template double-escapes HTML when Visual Editor is OFF in WordPress, #3462 (@pglewis) -* Fixed: Pods breaks Theme Editor for PHP files, hangs loopback test #4595, #4931 (@jamesgol, @pglewis) -* Fixed: Time field cannot save midnight #3488, #4937 (@pglewis) -* Fixed: Resolve file uploads directory check logic for file exports #4970 (@elia-senatore-cippest, @sc0ttkclark) -* Fixed: Media modal issues in post edits, #4945, #4967 (@pglewis) -* Fixed: Fatal error if not logged in and accessing wp-admin, #4828 (@therealgilles) -* Fixed: Pick fields with predefined/custom lists using numeric keys not loading values #4892, #4753 (@pglewis) -* Fixed: Non-required color-picker field did not allow saving empty value #4919 (@JoryHogeveen) -* Fixed: CodeMirror fields in Taxonomy and User edit forms #4913 (@pglewis) - -= 2.7.3 - May 6th 2018 = - -**Bug Fixes** - -* Fixed: 'search' param for Pods shortcodes #4909 (@pglewis) -* Fixed: 'before_content' and 'after_content' were ignored in widgets #4891 (@pglewis) - -= 2.7.2.1 - May 5th 2018 = - -**Developer and deployment enhancements** - -* Added: .editorconfig file [http://editorconfig.org/](http://editorconfig.org/) #4571 (@JoryHogeveen) -* Updated: export-ignore list #4898 (@pglewis) - -**Bug Fixes** - -* Fixed: Pods Widget output #4891 (@pglewis) -* Fixed: Slider controls not showing #4895 (@pglewis) -* Fixed: Fatal exception attempting to parse Persian DateTime strings #4896 (@sc0ttkclark) -* Fixed: Array to string conversion notice in Pods form #4886 (@sc0ttkclark) - -= 2.7.2 - May 3rd 2018 = - -**New Features Added** - -* Added WP-CLI commands for Pods, more details at [https://docs.pods.io/advanced-topics/pods-wp-cli/](https://docs.pods.io/advanced-topics/pods-wp-cli/) (@sc0ttkclark) -* Added: Filter HTML class for li.pods-field form element to allow for more styling options. #4813 (@paddelboot) -* Added: Currency field enhancement: Add a currency sign before the field input. #4714 (@JoryHogeveen) -* Added: Currency formats with spacing between currency sign and value #4838 (@JoryHogeveen) - -**Bug Fixes & Corrections** - -* Fixed: Missing thickbox styles for `PodsUI::filters()` #4797 Fixes #4693 which was preventing Advanced Content Type Filters Popup from Loading (@pglewis) -* Fixed: Text field readonly no longer defaults to `true` #4794 Fixes #4791 (@pglewis) -* Fixed: Simplify how we inject the PHP string into the JS #4787 Fixes #4786 which was creating syntax error in JS for number fields (@pglewis) -* Fixed: Tooltips were not working in the Pods Templates or Roles and Capabilities components #4851 (Fixes #4850) (@pglewis) -* Fixed: Isolates qtip styles and functionality to pods only which should hopefully resolve any issues with conflicting with other plugins/themes that may use the tooltip functionality [#4834] Fixes #4832 where tooltips were not displaying (@nicdford) -* Fixed: Tooltip corrections: Update Pods Add New screen for extended taxonomies as Table Storage is not required since Term Meta was added by WordPress. #4609 (@pglewis) -* Fixed: Issue where fields with particularly long post titles would extend past the width of the container #4831( Fixes #4700) (@nicdford) -* Added: appropriate CSS namespace prefixes to avoid style conflicts #4632 (#4612) (@nicdford) -* Fixed: Prefix all form styles with `form.pods-manage`. Namespace prefix all pods-manage styles to avoid CSS conflicts with Gravity forms (#4615,#4612) (@JoryHogeveen) -* Fixed: Pods DFV fields no longer depend upon the specific instance of jQuery shipped with WordPress (#4680). (@pglewis) -* Fixed: Update all storage type tooltips. Many were still referencing old Custom Taxonomy Table Storage requirements that were no longer required after Term Meta support. Fixes #4835 (@pglewis) -* Fixed: Bug with decimal handler when converting to dash (-) #4829 (@JoryHogeveen) -* Fixed: Checkbox misalignment on custom settings pages (#4711) (@JoryHogeveen) -* Fixed: Quality of life visual updates and optimizations for the CLEditor (#4633) (@nicdford) -* Fixed: `%F` with PHP's `sprintf` function defaults to a precision of 6 decimal places, we now include the precision specifier whenever more than 6 decimal places of precision is needed. (#4741) (@0xLBF) -* Fixed: Extend the condition for WPML validation exception to cover the Translation Editor so required fields don't break the Translation Editor in WPML. (#4802) (@dgwatkins) -* Fixed: Corrects most relationship fields on media items when editing in grid mode. Select2 based fields still need a workaround (Autocomplete, List View). (#4795) (@pglewis) -* Fixed: Avoid printing null message in PodsUI #4796 (@davidatwhiletrue) -* Fixed: Single-select Post Thumbnail does not display in Pods Template traversal. Allow traversing into post_thumbnail. (#4719) (@jamesgol) -* Fixed: Disable the "Add New" button for relationships when we're inside a media modal window (#4864). This is just a workaround until we can iron out the CSS and display for a modal from a modal. (@pglewis) -* Fixed: Autotemplate hook validation to verify filter before applying Auto Templates (#4695) (@JoryHogeveen) -* Fixed: Allow user-meta (and other extended Pods) to work in templates (#4847) (@jamesgol) -* Fixed: Corrected conflicts with container CSS/JS around Date/Time Fields (#4878) (@pglewis,@nicdford) - -**Fixes for Unit Testing and Workflow** - -* Fixed: Skip npm install and js tests on the PHP 5.3/Precise box to fix #4788 (#4789) (@pglewis) -* Fixed: mockery 1.0 requires php >=5.6.0; downgrade to 0.9 for now #4818 @pglewis -* Fixed: PHP Codesniffer Fixes #4569 (@sc0ttkclark) -* Fixed: eslint rules and formatting for Javascript (DFV only) #4590 (@sc0ttkclark) - -= 2.7.1 - December 8th 2017 = - -* Fix table join logic for taxonomies when renaming meta fields #4613 @sc0ttkclark -* Fix Pods Form submit errors and 404s #4618 @pglewis -* Fix dashicons style conflicts with Pods Form #4626 @nicdford -* Roll-back minimum version requirement for MySQL from 5.5 to 5.1 #4634 @sc0ttkclark - -= 2.7 - December 4th 2017 = - -**New PHP & WP Minimum Version Requirements:** - -* PHP Version Change Requirement 5.3+ -* WP Version Change Required 4.5+ - -**Major Changes in 2.7 Release: Flexible Relationships:** - -* New Relationship Field Format "List View": The power of the new flexible relationships is our new modal window that opens within the existing record for relationship fields. This is modeled after the Media Modal from WordPress and provides full functionality to Add New related records or edit existing records all from within the parent record of the relationship. This is provided through our new List View field format for relationship fields. To see a demo of this field in action [head on over to our YouTube](https://youtu.be/V8c067GAEcA) -* Add New with Flexible Relationships: The new flexible relationships will automatically enable Add New on all your existing relationships, but you can disable this from the Additional Options tab for each relationship field. You can switch field formats to the new List View from additional options tab as well. -* Dynamic Field Views: The relationship fields and file upload fields have been rewritten to take advantage of "Dynamic Field Views", driven by JavaScript. More technical details about the directions we went towards these field changes can be read about in our ["Pods 2.7: What We Did and Why We Did It"](https://pods.io/2017/12/05/pods-2-7-developer-notes/) - -**Significant Improvements and Fixes:** - -* Enhancements for Date, Time & Date/Time Fields to improve class inheritance, use WP Defaults and allow for custom options for saving and display @JoryHOgeveen -* Gallery & Tile View for Upload/Media Fields #3589 @JoryHogeveen -* IsEmpty for all Date/Time Fields, Number, Currency, etc. improvements for `[if field][/if]` for Templates @JoryHogeveen -* Major fixes for Pods Templates: Proper handling of shortcodes within Pods Templates and in if/each blocks. Proper handling of all image tags and user traversal @jamesgol -* Comment Traversal #4118 @sc0ttkclark -* Update Compatibility with Admin Columns 3.0+ #4570 @JoryHogeveen -* Filter Added for Select2 Overrides #4571 @sc0ttkclark -* Fix for Advanced Content Types and Relationships in `[each][/each]` tags correcting for lowercase id. #4585 @0xLBF - -**Behind the Scenes Fixes and Improvements:** - -* js unit tests #3640, #4049 @pglewis -* pods_ui_get_params hook #3785 @telwing -* table storage list fields #4420 @jamesgol -* Refactor CSS @nicdford -* Built with Node @pglewis -* Pods Templates added for Polylang Translation Compatibility @JoryHogeveen -* SelectWoo migration from Select2 to address version incompatibilities #4546 @pglewis - -**Known Issues with this Release:** - -* Relationships to Taxonomy have Flexible Relationships disabled as the input screen for Taxonomy was not able to be accessed in an iFrame. Weโ€™re working on this for a future release. - -= 2.6.11.2 - August 4th, 2021 = -* Security: Clean up post type and taxonomy labels so they avoid potential output escaping problems in WordPress core (@sc0ttkclark, reported by Muhammad Daffa via WPScan) - -= 2.6.11.1 - June 4th, 2020 = -* Security: Remove deprecated usage of escapeMarkup in Select2 (@sc0ttkclark, @miha.jirov) - -= 2.6.11 - September 20th 2017 = -* Fixed: WordPress 4.8.2 introduced a breaking change that no longer correctly prepared number/currency queries. It did not introduce a vulnerability but only produced Database errors. -* Stay tuned for Pods 2.7 which will be out soon -- [Download Pods 2.7 RC1](https://github.com/pods-framework/pods/archive/release/2.7.zip) and join our [Pods Slack channel #pods-beta](https://pods.io/chat/) to help us finish the final testing - -= 2.6.10 - July 14th 2017 = -* Fixed: Pods Templates were creating erroneous output with nested `[if _fieldname_][else][/if]` and `[each _fieldname_][/each]` template tags inside HTML entities after 2.6.9 upgrade. This fix bypasses `do_shortcode` and also bypasses `do_shortcodes_in_html_tags` which was the problem with this particular fix. Fixes (#4324,#4307,#4307). (#4335). [@pglewis] -* Fixed: Multi-file fields save was causing array to string conversion warning. New function & helper added called `array_filter_walker` for backwards compatibility. Also fixes the 'editable' titles in Multiple File Upload. Fixes (#4112,#4313). (#4314). [@mgratch,@JoryHogeveen,@sc0ttkclark] -* Added: Pods Templates & Page Capabilities have been added to the Members Cap Filter and Pods Role Manager from Components, Roles & Capabilities. This corrects an issue where Pods Templates and Pods Pages were not available to Admins, only Network Admins. Admins will still need to have the pods_templates_ and pods_pages_ capabilities added to their role, but now they'll be able to do this without additional code. Fixes (#4311). (#4342). [@JoryHogeveen] -* Fixed: Corrected 2.x branch for GitHub Feed. Fixes (#4305). (#4306). [@sc0ttkclark] -* Fixed: Minor Spelling fixes related to i18n. (#4276) [@garrett-eclipse] -* Updated: Removed CodeClimate Integration (#4275) and updated glob 7.1 (#4242). [@Ramoonus] - -= 2.6.9 - May 30th 2017 = -* Added: Pods Template Component is now automatically active on initial installation or reinstallation of Pods. Fixes (#3446). (#4060,#4180). [@pglewis,@sc0ttkclark] -* Added: Auto Template Fix: Add configurations setting to override and allow Auto Templates to run against the_content outside of the WordPress_Loop. By default now, it will only run inside the WP Loop. (#4088). [@jamesgol] -* Added: Allow raw value in PodsUI rows. New type "raw" that can output HTML form elements; used in i18n component. Fixes (#3959). (#3960). [@JoryHogeveen] -* Fixed: Template Reference in Template Editor now properly displays without running out of memory. Fixes (#3370,#3992). (#4088,#4000). [@jamesgol] -* Fixed: post_author querying now works through traversal of related post type. Fixes (#3931). (#3953,#4065). [@sc0ttkclark,@pglewis] -* Fixed: Search the proper SQL column with "search" and meta based CPT. Fixes (#3858). (#4007). [@jamesgol] -* Fixed: Ensure call to pods_view returns shortcode generated content, instead of echo'ing. Fixes (#3433). (#4010) [@dom111] -* Fixed: Additional CSS Classes were not saved (#4003) so new Duplicating Pod now gives preference to existing field options values on duplication (#4028). [@pglewis] -* Fixed: duplicate_pod_item now works for WP objects. Fixes (#3238,#4025). (#4070). [@pglewis] -* Fixed: Hidden field did not save Default Values on fields with both Visibility hidden and a Default Value set. Fixes (#3996). (#4061). [@pglewis] -* Fixed: Use register_taxonomy_for_object_type for post types that support post formats. Was not originally being registered for Pods CPT. Fixes (#2165). (#4076,#4084). [@sc0ttkclark] -* Fixed: Help Text for HTML fields wpautop reference. Fixes (#4090,#4091). (#4089). [@JoryHogeveen] -* Fixed: Corrected Pods overriding preview link for post updated messages. Fixes (#4092). (#4093). [@tuanmh] -* Fixed: When using shortcodes/magic tags with PDF attachments, ._src returns an image since WP 4.7. This will now output the URL of the file. You can still get PDF generated images using ._src.image_size or ._img. Fixes (#4040). (#4111). [@JoryHogeveen] -* Fixed: Audio attachments will now work properly with pods_attachment_import. (#4155) [@sc0ttkclark] -* Fixed: Handling of Single & Double Quotes in post_thumbnail interpolation. Fixes (#4166). (#4167). [@quasel] -* Fixed: Adding back_link to wp_die() usage which allows Modal Add/Edit to give you a way to go back in the edit screen. Fixes (#4168). (#4169). [@sc0ttkclark] -* Fixed: Conflict with The Event Calendar issue with Handlebars (as we're using an older implementation). Temporary hack until 2.7 with the correct fix. (#4173). [@sc0ttkclark] -* Fixed: Missing images in unit test (#4177). [@sc0ttkclark] -* Fixed: Invalid AJAX error with frontend forms and Settings Pods; $id will always return for AJAX requests. Fixes (#4181). (#4184). [@JoryHogeveen] -* Fixed: Allow float values for menu positions and the option to remove trailing decimals from number field. Fixes issue where Pods Converted menu positions with decimals to INT on save. Fixes (#2839). (#4192). [@JoryHogeveen] -* Fixed: Composer: composer installers v1.2 to v1.3. (#4239) [@Ramoonus] -* Fixed: Editable Titles in Multiple File Upload fields are 'editable' again (broke in 2.6.8) without breaking bidirectional relationship saving. Fixes (#4112) and resolves (#3477,#3720). (#4264). [@sc0ttkclark] -* Fixed: Spelling error in UI. Fixes (#4266). (#4267). [@danmaby] -* Updated: Brand assets for Pods (icons and banners) for WordPress Plugin Directory. Fixes (#3948). (#4268) [@jimtrue] - -= 2.6.8 - January 17th 2017 = -* Added: WP Gallery display options for image fields. Fixes (#3905). (#3910). [@JoryHogeveen] -* Added: Add action after successful AJAX in admin_ajax. This allows other scripts to hook in the ajax handlers from Pods. Fixes (#3839). (#3840). [@JoryHogeveen] -* Added: Keep Plupload instances in `windows.pods_uploader[id]`. This makes it possible to bind event listeners to the file uploader. Fixes (#3763). (#3768). [@thirdender] -* Added: New singular capabilities for Taxonomies for Compatibility with WP 4.7. Fixes (#3896). (#3946). [@JoryHogeveen] -* Added: Enhance Currency Field storage. Fixes Adds new format as arrays for multiple values (label, name, sign) and decimal handling options. Fixes(#1915,#3453). (#3949). [@JoryHogeveen] -* Fixed: Number/Currency format validation error with French formatting. Fixes (#3842). (#3950). [@JoryHogeveen] -* Fixed: Additional save_user/save_post handling problems corrected and addition of Unit Tests. Fixes (#3918,#3801). (#3945). [sc0ttkclark] -* Fixed: Double qtip/tooltip when using single checkboxes (boolean type). Fixes (#3940). (#3943) [@JoryHogeveen] -* Fixed: Undefined Index Notice in (#3936). (#3941). [@sc0ttkclark] -* Fixed: Properly clear cache before running post-save actions in PodsAPI::save_pod_item. Prevents double saves being necessary to use the `pods_api_post_save_pod_item` filters to update WordPress Object fields. Fixes (#3917). (#3938). [@sc0ttkclark] -* Fixed: Revamp pods_error to handle multiple modes, PodsMeta now returns false instead of die/exception. Fixes (#3930). (#3937). [@sc0ttkclark] -* Fixed: Update save_post / save_user handling with better fallbacks when nonce not active. Fixes an issue where the $is_new_item was not set as expected on post saves and user saves. Fixes (#3801,#3918). (#3936). [@sc0ttkclark] -* Fixed: Add `pods_ui_get_find_params` filter for PodsUI to extend default `find()`. Fixes (#3925). (#3926). [@sc0ttkclark] -* Fixed: Compatibility additions for WP 4.7, Taxonomy Class (#3895,#3894) -* Fixed: Proper reset of the local var cache in Pods::$row when using add_to/remove_from/save. Fixes (#3784). (#3923). [@sc0ttkclark] -* Fixed: get_meta() $single usage to ensure it's always a boolean. Fixes (#3742). (#3921). [@sc0ttkclark,@JoryHogeveen] -* Fixed: Multiple Travis and Unit Test fixes and build functions. (#3942,#3913,#3911,#3907,#3903,#3888,#3887,#3886,#3885,#3883,#3882,#3881,#3880,#3869,#3868,#3819,#3770,#3750,#3745,#3743) [@Ramoonus,@sc0ttkclark] -* Fixed: Removing a Bad Init Call generated by a fix to correct plupload file field listings. Fixes (#3900,#3731). (#3901). [@pcfreak30] -* Fixed: Pass audio_args to the Audio Shortcode, src wasn't being passed when multiple audio files were on the same page using the same shortcode. Fixes (#3891). [@jamesgol] -* Fixed: Corrected non-printable character added after $api->cache_flush_pods() to settings-tools.php. Fixes (#3876). [@szepeviktor] -* Fixed: opcache names and add OPcache. Fixes (#3864). (#3875). [@szepeviktor] -* Fixed: Make sure self::$field_data is set in all cases. Corrects issue where relationship to predefined list was not working in AutoComplete/Select2 fields. Fixes (#3862). (#3863). [@jamesgol] -* Fixed: Unchecking Show in Menu in the Admin UI selection for Custom Taxonomies will now properly not show the Taxonomy. `show_in_menu` option for for Taxonomies. Fixes (#3848). (#3852). [@JoryHogeveen] -* Fixed: Make field type labels translatable. Fixes (#3849). (#3850). [@JoryHogeveen] -* Fixed: Store the old field name in meta. Pods already stored the old 'pod' name, but didn't do the same for fields after updating. Added for (#3841). (#3842). [@JoryHogeveen] -* Fixed: Fix error with PODS_LIGHT and components. Fixes (#2301,#3811,#2293). (#3837). [@JoryHogeveen] -* Fixed: Update the attachment parent if updating a post type. Only updates if the parent isn't set but allows file fields/upload fields to now properly show parent post. Fixes (#3808). (#3834). [@JoryHogeveen] -* Fixed: CSS fixes (remove old images + linter), fixing issues with gradient button not in WP Core. Fixes (#3812). (#3833). [@JoryHogeveen] -* Fixed: Improve CSS for Code Field (CodeMirror). Fixes (#3818). (#3832). [@JoryHogeveen] -* Fixed: Set Start of Week Day from General Settings; fixes issue where Calendar of datetime field in admin UI didn't follow the first day of week settings from Setting, General. Fixes (#3826). (#3831). [@JoryHogeveen] -* Fixed: PHP7 Compatibility issues, a few deprecated constructors and deprecated mysql_ with the use of $wpdb. Fixes (#3828). (#3830). [@JoryHogeveen] -* Fixed: Update postmeta cache before get_post_meta calls when bypassing cache, ensuring the meta is "fresh". (#3807). [@sc0ttkclark] -* Fixed: When preloading config after flushing cache, bypass cache. solves the issue when running multisite and youโ€™ve got an object cache drop-in that wonโ€™t flush cache for multisite when wp_cache_flush is called. (#3806). [@sc0ttkclark] -* Fixed: Fix error exporting taxonomy relationship over REST API. Fixes (#3606). (#3794). [@pcfreak30] -* Fixed: Use taxonomy capabilities in custom locations for taxonomy edit pages. Fixes an issue where Taxonomies assigned as Top Level Menu Items are not usable by Editors (only by Administrators). Fixes (#3569). (#3780). [@JoryHogeveen] -* Fixed: Correcting a bug in adding Taxonomy REST support. Fixes (#3777). (#3778). [@pcfreak30] -* Fixed: Clear `$related_item_cache` when saving a relationship. Fixes an issue where the $PodsAPI::save_relationships was not clearing the cache. Fixes (#3775). (#3776). [@pcfreak30] -* Fixed: jQuery fix to change from deprecated .live() to .on(). Fixes (#3771). (#3772). [@mikeschinkel] -* Fixed: Basic included post types from WP-API are no longer having their REST base overridden by Pods. Fixes (#3759). (#3760). [@sc0ttkclark] -* Fixed: Fix SQL for multilingual taxonomies for compatibility with PolyLang. Fixes (#3728). (#3754). [@JoryHogeveen] -* Fixed: Fix plupload file field listings, specifically fixing some issues in the CSS and jQuery. Fixes (#3731). (#3732). [@pcfreak30] -* Fixed: Removed max-length for default field value for Text & WYSIWYG fields. Fixes (#3729). (#3730). [@JoryHogeveen] -* Fixed: Updated URL for translation contributions. Fixes (#3725). (#3726). [@JoryHogeveen] -* Fixed: Validate field option dependencies based on location within tabs. Corrects and issue with compatibility between Pods SEO. Fixes (#3707). (#3723). [@JoryHogeveen] -* Fixed: Properly update bidirectional taggable relations. Corrects the issue where bidirectional relationships were creating new entries from the taggable choice in AutoComplete fields, but not saving the relationship. Fixes (#3477). (#3720). [@caleb] -* Fixed: Allow the entry of negative numbers in Currency fields. Fixes (#3708). (#3709). [@pcfreak30] - -= 2.6.7 - August 15th 2016 = -* Fixed: Magic Tag {@permalink} fixes for taxonomy / user / comment detail URL Mapping. Fixes (#3339). [@sc0ttkclark] -* Fixed: Pods Wizard for Forms now properly uses the `[podsform]` shortcode. Fixes (#3251). [@sc0ttkclark] -* Fixed: Issue with pll_get_post returning false instead of null. Fixes (#3596). (#3599) [@JoryHogeveen] -* Fixed: WYSIWYG editor type option is used as dependency by the editor options. Fixes (#3549). (#3610) [@JoryHogeveen] -* Fixed: Do not display metagroup if all fields are set to hidden. Fixes (#1614). (#3615) [@JoryHogeveen] -* Fixed: Allow post_status filter to be set for related post_type objects in the edit field UI (#3626). Fixes (#3594). [@JoryHogeveen] -* Fixed: Refactor object type checking in PodsRESTHandlers::get_handler (#3630). Fixes (#3629). [@pcfreak30] -* Fixed: Added PODS_DIR to directories that are checked by field_loader() (#3644). Fixes (#3643). [@jamesgol] -* Fixed: Improved field alignment on setting pages (#3649). Fixes (#3648). [@JoryHogeveen] -* Fixed: Check for PodsInit in general.php (#3665). Fixes (#3473,#2803,#3353). [@JoryHogeveen] -* Fixed: Taxonomy capabilities + No more hardcoded tax settings (#3678). Fixes (#3676,#3677). [@JoryHogeveen] -* Fixed: Allow field options to be filtered (UI). Also allows for il8n module to improve translation handling. (#3683). Fixes (#3682). [@JoryHogeveen] -* Fixed: WPML Compatibility (#3691). Related to (#142). [@srdjan-jcc] -* Fixed: Pods field() now properly handles user and media when the output type is pod/pods. Original issue resulted in `$object` being empty as `user` and `media` do not have a `pick_val` (#3694). Fixes (#3693). [@pcfreak30] -* Fixed: travis-ci: test with PHP 7.1 (#3702). [@Ramoonus] - -= 2.6.6 - June 23rd 2016 = -* Added: Polylang compatibility with latest versions along with fixes to longstanding issues with editing and displaying content, relationships, and taxonomy (#3574). Fixes (#3572, #3506) [@JoryHogeveen] -* Added: REST API v2 Compatibility (#3584). Switches `register_api_field` to `register_rest_field`. Fixes (#3581) [@sc0ttkclark] -* Added: Allow changing the Auto Templates Filter. This adds a new section in the Auto Templates tab that allows overriding the default `the_content` filter (#3542). Fixes (#3540) [@Shelob9] -* Added: Polylang support to pods_v post_id (#3562). Allows Pods templates that are translated to be properly selected. Fixes (#3561,#3537) [@jamesgol] -* Added: Create new 'post_id' method for pods_v (#3537). Provides a method to allow i18n plugins to return a different post id. Related to (#3542,#3526) [@jamesgol] -* Added: Add filter to PodsMeta->groups_get() allowing adjusting the groups via filter (#3548). Related to (#3547) [@jamesgol] -* Added: Use form_counter in field name to be unique and prevent conflicts. (#3535) Fixes (#3533) [@pcfreak30] -* Added: Add user, media and comment support to REST API (#3516). Related to (#3418,#3419) [@pcfreak30] -* Added: Filter the Pods Metas to Display (#3544). Fixes (#3520). [@coding-panda] -* Fixed: REST API cleanup for pick field handling. (#3560) Fixes (#3559) [@sc0ttkclark] -* Fixed: Exclude Unique Post fields from duplication during `$pods->save`. (#3564). Includes `ID`, `post_name`, `post_date`, `post_date_gmt`, `post_modified`, `post_modified_gmt` and `guid`. Fixes (#3563) [@pcfreak30] -* Fixed: Allow midnight (00:00) as valid time (#3555). If "Allow empty value" is unchecked and a value is not passed it will default to the current time, but it will still accept 00:00:00 as a valid value. Related to (#3488) [@jamesgol] -* Fixed: Pass $strict = false to load_pod (#3554). This will keep the "Pod not found" message from being displayed during register of other post types. Related to (#3416) [@jamesgol] -* Fixed: Don't add space to currency names that use HTML encoding (#3553). Fixes British pound currency symbols and others. Resolves (#3498) [@jamesgol] -* Fixed: Removed extra setting showing up in Auto Templates settings for Taxonomies (#3543). Fixes (#3541) [@Shelob9] -* Fixed: Use html_entity_decode to convert separator as it is an html entity. (#3536) Fixes (#3527) [@pcfreak30] -* Fixed: PodsRESTHandlers::write_handler needs to be static (#3511). Fixes (#3510) [@pcfreak30] - -= 2.6.5.2 - May 4th 2016 = -* Fixed: Typo in PLL Compatibility check corrected. (#3504) Fixes (#3503). Thank you @JoryHogeveen and @fmommeja for tracking down, fixing and validating this fix. [@JoryHogeveen] - -= 2.6.5.1 - May 4th, 2016 = -* Fixed: Additional Field Options tab disappears from field admin view. Fixes (#3501). [@sc0ttkclark] - -= 2.6.5 - May 3rd, 2016 = -* Fixed: Renaming of Pods with underscores to hyphenated names that was introduced in 2.6.3. Hyphenated Pods names will remain hyphenated and Underscored Pods names will remain underscored. Fixes (#3499). [@sc0ttkclark] -* Fixed: Support for new Polylang Versions with much kudos to @JoryHogeveen for tackling this (#3491). Fixes (#3490,#3223) [@JoryHogeveen] - -= 2.6.4 - April 25th, 2016 = -* Fixed: Modified Run activation/install priority to fire before plugins loaded. Fix for the Clearing Pods Cache automatically after Pods Upgrade (#3487). Fixes (#2558,#3348) [@sc0ttkclark] - -= 2.6.3.1 - April 21st, 2016 = -* Fixed: An Git / SVN deploy bug caused some files to not be properly pushed to WordPress.org SVN, this release is just to ensure everyone who may have updated to 2.6.3 during the period which we were fixing it will be able to still get the proper file updates - -= 2.6.3 - April 21st, 2016 = -* Fixed: Fix forcing underscores when loading Edit Pod Form (#3483). Fixes (#3095) [@sc0ttkclark] Kudos to @lkraav for helping us pin this particular issue down and bring it to resolution. -* Fixed: Clearing Pods Cache automatically after Pods Upgrade "Salt n'Pepa"'ing the cache keys (#3401). Fixes (#2558,#3348) [@sc0ttkclark] - -= 2.6.2 - March 24th, 2016 = -* Added: Support for object fields when using Pods::field() with a specific $field and $option. This was also used to correct a problem with "fetching" Custom Taxonomy's Term List when using Pods Feeds in Pods Gravity Forms Plugin. (#3437) [@sc0ttkclark] -* Fixed: Correcting CSS used for Dashicon to remove conflict with icon usage in Divi. (#3404,#3406) [@jimtrue] -* Fixed: Currency/Number Validation used to correct issue with Currency Usage in the Pods Gravity Forms plugin (#3436) [@sc0ttkclark] - -= 2.6.1 - February 15th, 2016 = -* Added: Additional Label support for Post Type / Taxonomy register functions (#3275) [@pcfreak30] -* Added: Add use_current option for Widget Single (#3393,#3394) [@sc0ttkclark] -* Added: Add option to website fields to open links in new window (#3388,#3387) [@sc0ttkclark] -* Fixed: 'type' not 'object_type' (#3378,#3351) [@pglewis] -* Fixed: Update Select2 to v3.2.0, should resolve #3344 (#3377,#344) [@pglewis] -* Fixed: Change Markup to Support CSS in WP 4.4 (Thanks to @nicdford we missed mentioning in 2.6 Change log) (#3277,#3270,#3279) -* Fixed: Non-Zero Array Keys here in PHP7 cause odd behaviour so just strip the keys (#3294,#3299) [@pglewis] -* Fixed: Corrected Dashicons Link in the Menu Options panel of Edit Pods (#3287,#3271) [@benbrandt] -* Fixed: Update Version number on 2.x (#3282,#3281) [@pglewis] -* Fixed: Typo's Rest into REST (#3303) [@Ramoonus] -* Fixed: Disable xdebug on Travis (#3284,#3283) [@pglewis] -* Fixed: Remove dockunit leftovers (#3307) [@Ramoonus] -* Fixed: Do not use Hashtag as name (#3316) [@Ramoonus] -* Fixed: Over-escaping strikes again (file upload, restrict file types with more than one mime type) (#3083,#3328) [@pglewis] -* Fixed: Refresh #3388 with 2.x (#3388,#3389) [@sc0ttkclark] -* Fixed: Replace usage of get_currentuserinfo with wp_get_current_user (preparation for WP 4.5) (#3399,#3398) [@sc0ttkclark] -* Fixed: Taxonomy custom meta fields returning false from REST API (#3365,#3369) [@anandamd] - -= 2.6 - December 9th, 2015 = -* Added: Support for Term Meta in WP 4.4 - Now create meta-based taxonomies and Pods just magically works! (#3169,#3163) [@sc0ttkclark] -* Added: Add REST API Support to Post Types, Taxonomies, Users. Read the update in https://github.com/pods-framework/pods/pull/3184 for step by step details. (#3184,#3182) [@Shelob9] -* Added: Added compatibility with the latest Polylang version, using $polylang-model to get the current language and version. (#3223) [@JoryHogeveen] -* Added: Inline hook docs in PodsAdmin class (#3180,#3179) [@Shelob9] -* Added: Fixes to REST API Admin Tab (thanks @nicdford) to display always but also explain why it won't work if not able to work. (#3246,#3259) [@Shelob9,@nicdford] -* Added: PHPunit support for clover-coverage FN (#3176) [@Ramoonus] -* Added: Travis do not allow PHP7 to fail (#3235) [@Ramoonus] -* Added: Tests for Mariadb and mysql 5.6+7 with PHP 5.6 Travis (#3212,#3208) [@Ramoonus] -* Added: Nonce and text translation to delete link in pod edit sidebar. Fixes issue where attempted to delete pod from edit page results in fatal error. (#3203,#3194) [@cpruitt] -* Added: Use phpcs standard wordpress in scrutinizer (#3166) [@Ramoonus] -* Added: phpunit support for clover-coverage (#3161) [@Ramoonus] -* Added: Travis allow PHP7 to fail (#3153) [@Ramoonus] -* Added: Travis include WordPress 4.3 in test matrix (#3152) [@Ramoonus] -* Added: Travis cache composer (#3151) [@Ramoonus] -* Added: Grunt ignore dockunit.json (#3150) [@Ramoonus] -* Updated: Dockunit - replace PHP 7 rc1 with rc4 (#3201) [@Ramoonus] -* Updated: Improve Contributing guidelines correcting wrong pull location and fixing correct release branch. (#3149,#3147) [@quasel] -* Fixed: Scheduled post preview message/URL. When a post was scheduled, the status message displayed at the top of the edit post page was malformed where the string placeholders were numbered. (#3234) [@sparkdevelopment] -* Fixed: Merged #3205 to fix install-wp-tests.sh (#3211,#3205) [@Ramoonus] -* Fixed: Add pods_auto_template_name filter, by context to change auto template (#3199,#3200,#3198) [@Shelob9] -* Fixed: Revert scrutinizer less is more (#3172,#3170) [@sc0ttkclark,@Ramoonus] -* Fixed: Remove limit of 5 in get_template_titles Auto Template (#3157,#3160) [@jimtrue] -* Fixed: Related_act.permalink calls to fix permalink/slug traversal in ACTs and related taxonomies (#3156,#3155,#2779) [@sc0ttkclark] -* Fixed: Added option to deselect Auto Template for Archive views. There needed an 'empty' selection to correct issue where Template error wouldn't go away. (#3148,#3146,#3142,#3247) [@Sgillessen] -* Fixed: Added Dockunit Badge (#3145) [@tlovett1] -* Removed: Double exclude path in scrutinizer (#3228) [@Ramoonus] -* Removed: Readme removed code coverage badge (#3220) [@Ramoonus] -* Removed: Dump composer in Scrutinizer (#3204,#3167) [@Ramoonus] -* Removed: Composer remove coveralls. Was not being used and needs phpunit support. Could also be replaced by php codesniffer or scrutinizer. (#3174) [@Ramoonus] - -= 2.5.5 - September 16th, 2015 = -* Added: Unit testing for PHPUnit 4.8 support. (#3090, #3069) Kudos to @Ramoonus -* Fixed: Drop External code coverage - timeout in Scrutinizer. (#3091) Kudos to @Ramoonus -* Fixed: Changed Content property to fix spacing issues with AutoComplete Field where the formatted selection fields have awkward spacing between the selection box and the selection list. (#3098, #3097, #3099) Kudos to @nicdford -* Fixed: Issue where [each] tag traversal did not work with Taxonomy in Pods Templates. Related notes regarding pod->object_fields for taxonomy added for 3.0 notes. (#3106, #3018, #3107, #3111) Major thanks to @pglewis -* Fixed: `permalink` field traversal has only been working for post types, not for related taxonomies. (#2779, #3114, #3115) Kudos to @pglewis -* Added: Support for CPT UI 1.0.x in CPT UI migration component by adding support for multiple possible option names for post types and taxonomies. (#3112, #3109, #3113, #3116, #3117) Kudos to @pglewis -* Added: Merged Auto Template into Pods Template Component. (#3125, #3105) Major thanks to @Shelob9 both for the original plugin and for incorporating this into Pods Templates. -* Added: License.txt changes to sync with GPL v2 (#3130, #3133) Kudos to @Ramoonus - -= 2.5.4 - August 10th, 2015 = -* Added: Support for Compare ALL with meta_query syntax. Kudos to @pcfreak30. (#3037, #3038) -* Added: Query_field tests (meta_query syntax for where) (#3033, #3032, #1662, #2689) -* Added: Support for autoCAST()ing meta_value orderby for dates and numbers (#3043, #3041, #3058) -* Added: Feature/pods page export support. Added 'pods_page_exists' filter to allow Pods Page content to be supplied from another source (eg exported files) (#3049, #3054) -* Added: Copy of EDDs scrutinizer (#2917, #3072) -* Removed: PHP4-style constructor removed in Pods Widgets (#3055, #3056, #3057) -* Fixed: PHP Doc Improvement (#3039, #3040) -* Fixed: Style escaping which created a quote encoding bug in PodsMeta.php. (#3053, #3032) - -= 2.5.3 - June 11th, 2015 = -* Added: Support for Term Splitting in WP 4.2 (#2856, #2660) -* Added: Support for Pod and Field names with dashes and prefixes with underscores (#3012, #3021, #3022) -* Added: Add git workflow and a link to it from contributing.md (#2490, #2496) -* Added: Unit tests for PodsField_Boolean (#2473, #2474) -* Added: Unit test to create pod factory object and moves fixture set up from traversal tests to test case. (#2445) -* Added: Additional Pods_Field_Text tests added to incorrect text dependencies. (#2388) -* Fixed: Fixes for Drag and Drop Reorder Action not working in ACT's (#3015, #3016) -* Fixed: Fix for pagination handling in shortcodes. Shortcodes currently use 'pagination' for two contexts (display and data) but if page or offset is supplied, it's only meant for one context (display). (#2807, #3004) -* Fixed: Update post field in pod instance before saving, related to MetaData (post field) not flushing after saving (#3000, #3002, #3003) -* Fixed: Corrects Delete not working for Edit Items (#2752, #2991) -* Fixed: Corrects ACT - Admin Order DESC not working && SQL error if order by an relationship field (#2843, #2989) -* Fixed: Composer: updated for phpunit 4.7 (#2987, #2988, #2783) -* Fixed: ui/js/jquery.pods.js fixes (#2971, #2972) -* Fixed: Remove `@internal` phpDoc for pods_query() (#2970, #2969, #2975) -* Fixed: Fix for ACT editor not staying on current item after saving (#2968, #2942, #2974) -* Fixed: Fix for over escaping icon URL in file fields previewer (#2957, #2956, #2955, #2978) -* Fixed: Fix for symlinked pods in local deve environment (#2946, #2945, #2949) -* Fixed: Removed Vestiges of Old Updater (#2940, #2983) -* Fixed: Clarify help text as to what does and doesn't get deleted on reset (#2792, #2778) -* Fixed: Missing $ in PodsInit line 494 (#2475, #2476) -* Fixed: Trim off whitespace when saving custom fields; code in classes/fields/pick.php already does this. (#2386, #2343) -* Fixed: Updated Taxonomy to get called after cache is flushed (#2264, #2375, #2382) -* Fixed: Cleared old unit tests from EDD (#2380) -* Fixed: Allow fields to be sorted by orderby; Two separate but connected issues. First if orderby is passed then the $data array is never populated. Then looping through $ids will always give it results sorted by priority in the relationships field (data returned by lookup_related_items) (#2350, #2277) - -= 2.5.2 - May 14th, 2015 = -* Fixed: Issues with default values for number and other types of fields. -* Fixed: Issue where Pods update was causing WP-API endpoints to 404. Rewirte rules now flush on wp_loaded. -* Fixed: Issue preventing proper display of fields in a related CPT via Pods::field() -* Fixed: Issue preventing codemirror from being enqueued in Pods templates and therefore breaking Pods tempaltes editor in certain configurations. -* Added: Added caching info to debug info. -* Fixed: Bug that was causing Pods to overwrite admin menus. -* Fixed: Issue preventing ongoing compatibility with Admin Columns. -* Improved: Style of components filter bar. -* Improved: Proper sanitization/ escaping of URLs. -* Fixed: Shortcode button was outputted in post editor when shortcodes were disabled. This will no longer happen. -* Improved: Translation strings in ui/admin/help -* Improved: Gradients in Pods wizard. -* Fixed: Issue preventing associated taxonomies to be fetched via Pods::field() and therefore magic tags. -* Improved: Icon font used for Pods admin icon. -* Improved: Elaborated on what data is and isn't deleted when Pods data is reset. -* Added: Compatibility with Github updater plugin. -* Updated: New youtube video in readme. -* Added: Support for term splitting in WordPress 4.2. -* Removed: Extra meta data with _pods_ prefix -* Fixed: Issue where multiple post type Pods objects called in same session were treated as the same in cache. -* Fixed: Double slashing in PodsView class. -* Improved: URL escaping in PodsUI +== Screenshots == -= 2.5.1.2 - March 16th, 2015 = -* Security Update: We recommend all Pods 2.x installations be updated to the latest version of Pods -* or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/ -* Fixed: Pods UI orderby now strictly enforces Database column format +1. Create new content types or extend existing ones +2. Add groups of fields and manage your content type +3. Add fields of many types with individual options for each +4. Creating or extending a Post Type will add groups of fields to the Post Editor +5. Creating or extending a Taxonomy will add groups of fields to the Term Editor +6. Extending Users will add groups of fields to the User Profile and Edit forms -= 2.5.1.1 - January 22nd, 2015 = -* Fixed missing files for font icon. +== Contributors == -= 2.5.1 - January 22nd, 2015 = -* Fixed: Issue preventing fields from being sorted by weight or by orderby, that was affecting image multi-select image field ordering. -* Fixed: Missing gradients in UI. -* Fixed: Use of anonymous function in PodsMeta.php causing issues with old versions of PHP. -* Fixed: Issue where hidden fields were being shown for admin users, when they should have been hidden. -* Fixed: Issue where PodsAPI::delete_field() was unable to delete fields in certain situations. -* Fixed: Issue with pods_version_check() usage that was causing a deprecated core function to run, when it was supposed to prevent it from running. -* Fixed: Issue with pods_error() that was causing it to display AJAX errors improperly. -* Fixed: Issue preventing public, publicly queryable & rewrite with front from saving choices in advanced options. -* Fixed: Magic tag for custom taxonomy, which was showing no content in Pods Templates in 2.5. -* Fixed: If block in Frontier. -* Fixed: Issue with custom taxonomy joins preventing "custom_tax.d.custom_field" type where clauses from working. +Pods really wouldn't be where it is without all the contributions from our [donors](https://friends.pods.io) and [code/support contributors](https://github.com/pods-framework/pods/graphs/contributors). -= 2.5 - December 30th, 2014 = -* Major performance enhancements can now make things run up to 400% faster (props to @jamesgol!) -* More unit tests -- now 1,858 tests with a total of 13,420 assertions covering all content type, storage type, and field variations (props to @sc0ttkclark, @clubduece, and @mordauk! it was a group effort) -* Added Travis-CI / Scrutinizer-CI for all pushes and pull requests to unit test and check for other issues -* Upgraded Code Mirror library -* Upgraded qTip library -* Updated translations -- Add your translations at http://wp-translate.org/projects/pods -* Fixed: Added nonces for multiple actions in the admin area to avoid accidental / unwanted results -* Fixed: Issue causing issues in admin with CodePress admin columns. -* Fixed: Issue preventing Pods Template editor from working with certain xcache configurations. -* Added: 'join' to the accepted tags for Pods Shortcode. -* Added: 'pods_data_pre_select_params' filter. -* Improve: PodsAPI::export_pod_item_lvl(), adding item ID to all steps. -* Simplify logic when creating new PodsAPI singleton internally. -* Switch from Pods::do_hook() to apply_filters() or do_action() for 'pods_pods_fields', 'pods_pods_field_related_output_type', 'pods_pods_field_', 'pods_pods_field', 'pods_pods_fetch', 'pods_pods_reset', 'pods_pods_total_found', 'pods_pods_filters' -* Fixed: YARRP support. -* Ensure that pods_v_sanitized() passes the $strict argument to pods_v(). -* Prevent use of date_i18n() in PodsData when not needed. -* Fixed: Issue where updating relationship to users in pods editor threw an erroneous error. -* Fixed: Hiding of text in title-prompt-text -* Updated design of new Pod wizard to match MP6 (props to @nikv!) -* Fixed: Inline docs for pods_api_get_table_info_default_post_status filter -* Fixed: Issue where Pods::field() showed cached data after saving via Pods::save(), without re-building the Pods Object. -* Allowed PodsField_Pick to save names -* Switched pods_v() to use switch/case instead of if/else where possible. -* Prevented Pods::id() from calling the field method unless it has to. -* In PodsData::select(), allow proper use of cache expiration time. -* Fixed: Issue in currency fields to ensure proper handling of decimals. -* Added a "pre_select" hook in PodsData. -* Improved traversal regex in Pods::find() to have better handling for variation of backticks. -* Removed usages of the deprecated WordPress function like_escape(). -* Remove redundant file/class checks for Pods Templates. -* Implement glotpress-grunt for manging translations. -* Fixed: Issue where get_current_screen(), in some contexts was used as an object, when it was null. -* Improved: Styling of shortcode insert button. -* Prevented string replace and trim from running on a form field default when default value is not a string -* Fixed: Issue preventing color pickers from working in front-end form. -* Switched from using $wpdb->prefix to $wpdb->base_prefix in pick field class. -* Fixed: Default avatars on the Discussion settings page replaced by user's custom avatar. -* When saving custom fields, whitespace is now trimmed. -* Better validation of custom fields when saving custom post types. -* Improved: Handling of required fields. -* Changed the default of $display_errors in Pods class to true. -* Allowed save_post_meta to delete single meta elements instead of update. -* Fixed: An issue preventing fields from being sorted by orderby. -* Fixed: Issue where fields, storing one value, returned arrays, instead of strings. -* Allowed extending the link category taxonomy, if in use. -* Added join as an acceptable tag for Pods shortcodes. -* Fixed pods_error(): reversed logic that was emitting an error instead of throwing an exception when $display_errors is false -* Fixed issue where user_url was created as a required field when extending users. -* Add ability to use pods_group_add() in the ACT editor. -* Security Update Reminder: As of Pods 2.4.2, we recommend all Pods 2.x installations be updated to the latest version, or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/ -* If you need assistance in upgrading your Pods 2.x site to the latest version of Pods, please don't hesitate to contact us at https://pods.io/help/ +== Changelog == -= 2.4.3 - June 23rd, 2014 = -* Fixed: Pods Templates component now has better handling of the new shortcodes -* Fixed: PodsUI data issue with Custom DB Table support -* Fixed: Readonly fields and noncing now works properly, Pods 2.4.2 caused all forms with readonly fields to fail submission -* Hardened: Further security hardening of the `[pods]` shortcode, added PODS_DISABLE_SHORTCODE constant to allow sites to disable the Pods shortcode altogether += 2.8 - October 18th, 2021 = -= 2.4.2 - June 22nd, 2014 = -* Security Update: We recommend all Pods 2.x installations be updated to the latest version of Pods to fix a noncing issue with form saving, or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/ +Read the full [Pods 2.8 Field Guide](https://pods.io/2021/02/11/pods-2-8-beta-1-released-and-the-field-guide-to-pods-2-8/) which includes information about all the features, enhancements, and changes in this major Pods release. -= 2.4.1 - June 19th, 2014 = -* Fixed: Display of of hidden fields in Pods Forms -* Fixed: Reordering fields in PodsUI -* Fixed: PodsUI Admin Icon Display -* Add new filter: โ€˜pods_pod_form_success_messageโ€™ for changing the message when Pods Forms are successfully submitted. -* Fixed: Issues in Packages component when importing existing fields. -* Added new filter: โ€˜pods_view_alt_viewโ€™ for overriding normal Pods Views to be loaded in via AJAX inline from Pods AJAX Views plugin. -* Fixed: PHP error in Pods Template reference. -* New Constant: PODS_PRELOAD_CONFIG_AFTER_FLUSH check to allow for preloading $api->load_pods() after a Pods Cache flush. -* Fixed: Issue with tabled-based SQL delete actions. -* Fixed: PodsUI SQL table-based lookups -* Added: New Hooks In ui/admin/form, which generates ACT editor, for adding additional forms or other content to editor. -* Added: Inline docs for 'pods_meta_default_box_title' filter and normalized args across each usage. -* Added: Item ID to pods_api::export() item array. -* Fixed: Update from GitHub functionality. -* Fixed: Issue where extended custom post types had diffrent names then original post type due to use of dashes in names. -* Improved UX for select2 field adding new items. -* Fixed: $params with unslashed data in Pods_Admin::admin_ajax() -* Fixed: Unwarranted base_dir warnings. -* Fixed: Pagination/search boolean checks. -* Fixed: Issue when mbstring module is not active. -* Fixed: Issue with markdown module header causing activation errors. -* New Filter: 'pods_admin_components_menu' to add/edit components submenu items. -* Added: Ability to use pods() without any parameters. Will pull the pod object based off of the current WP_Query queried object / object id +**Breaking compatability warning:** +* New minimum required versions have been updated as follows which includes notices to let you know if you need to update something. +* New minimum WP version required: WordPress 5.5+ (previously: WP 4.5+) โ€” Going forward we will support the last two major WP releases on each major feature release of Pods. +* New minimum PHP version required: PHP 5.6+ (previously: PHP 5.3+) โ€” Hey! You should take the time to update to PHP 7.4+ because thereโ€™s major speed improvements to be had ๐Ÿ™‚ +* New minimum MySQL version required: MySQL 5.5+ (previously: MySQL 5.1+) +* Refactored object handling for Pod and Field configurations โ€” instead of passing around arrays we now are using a fully scoped object for these configs. This gives us flexibility to lazy load and pull things as-needed from the database instead of always pulling entire Pods and Fields configurations all at once on any page it may not be needed. This also reduces how much we have to use/cache on each page further reducing overall memory usage on every page. It remains backward compatible in most array usage cases like `$pod['name']` but be aware that PHP ArrayAccess overloading errors may occur when manipulating Pod configs like `$pod['fields']['your_field']['name'] = 'My new field name';` or `$pod['options']['some_option'] = 1;` -= 2.4 - April 16th, 2014 = -* After a long road, we've got a new minor release out that fixes a large number of outstanding bugs and adds a few improvements that were within reach right away. -* In Pods 3.0 we're focusing on finishing some overarching performance improvements that are necessary to support large installs with the new Loop and Repeatable fields features. -* Added: Tagging feature for Relationship fields with Autocomplete (Select2) which lets you add new items on-demand when saving -* Added: PodsAPI::get_changed_fields() that can be used when in a pre-save hook to return array of changed values or used in PodsAPI::save_pods_item() to track changes to fields -* Added: _pods_location to $params for PodsAPI::save_pod_item which will contain the URL of the form it was submitted from -* Added: New Pods Template editor revamp to include auto-complete for magic tags and field reference, which can be further extended by installing Pods Frontier -* Added: An optional download link to File Upload field type -* Added: Additional Currency formats to Currency field type -* Added: created/modified functionality (see Advanced Content Types) to other Pod types, as long as they are date/datetime fields -* Added: Support for JetPack Publicize and Markdown modules -* Added: Max character length option for paragraph fields -* Added: Actions before and after Pods Form all and individual form fields are outputted -* Added: New constant PODS_ALLOW_FULL_META for for enabling/disabling get_post_meta( $id ) interaction with Pods (on by default) -* Added: New constant PODS_DISABLE_SHORTCODE_SQL to disable SQL-related parameters in shortcode -* Added: 'pods_admin_media_button' filter to disable the Pods shortcode button in post editor -* Added: 'pods_api_save_pod_item_track_changed_fields_{POD_NAME}' filter for tracking changes to fields -* Added: 'pods_pick_ignore_internal' filter to enable/disable Relationships with core Pods types (_pods_pod, etc) -* Added: 'pods_image_default' filter to allow for placekitten.com or other image placeholder scripts for testing -* Added: Improved Pods Template code sanitization -* Added: Better names for many fields in Pods Editor -* Added: New and improved help bubbles in Pods Editor -* Added: Instructions about using Pods Templates in Pods Widgets -* Added: New descriptions for Pods Pages and Pods Advanced Content Types component descriptions -* Added: Support links in Pods Admin -> Help -* Added: Currently active theme to Pods Debug info list -* Added: Inline docs for 'pods_api_get_table_info_default_post_status' filter -* Added: Inline docs for 'pods_admin_menu' filter -* Added: Inline docs for 'pods_admin_setup_edit_options' (and related) filters -* Added: Inline docs for 'pods_admin_setup_edit_tabs' (and related) filters -* Fixed: Issues with user tables in multisite -* Fixed: Issue with PodsForm::default_value -* Fixed: With Pods UI. Keep view when generating pagination links -* Fixed: Bug with custom extensions for allowed file types in upload fields -* Fixed: Compatibility problem with changes to plupload in WordPress 3.9 that prevented upload pop-up from loading -* Fixed: Array to string conversion error for CSS fields in Pods UI -* Fixed: Magic tags for taxonomies in Pods Templates -* Fixed: Fixed jQuery scope in Pods Form inline JavaScript -* Fixed: Added 'output' to reserved content types names and reserved query vars -* Fixed: Issue where required currency and number fields could be saved at default value -* Fixed: Undefined method error in WP 3.4 due to use of WP_User::to_array() which was added in WP 3.5 -* Fixed: Issue with ability to use filters on reorder page with Pods UI -* Fixed: Pre-save enforcing of max length for meta-based values -* Fixed: Extra spaces in custom defined list labels -* Fixed: Pagination default value for Pods shortcode -* Fixed: PodsForm::submit_button() method that had been lost from previous versions -* Fixed: Usage of pods_v in currency.php for optimzation purposes -* Fixed: Correct parent_file to highlight the correct top level menu -* Fixed: Improper wording for text at top of settings page field +**Features and changes in this release** +* Feature: Now you can add multiple groups of fields. (@sc0ttkclark, @zrothauser) +* Feature: Our Edit Pod screen is powered by our all new React form interfaces, tooltips, and they use our new Pods Admin REST API endpoints. (@sc0ttkclark, @zrothauser) +* Feature: All of our form fields are powered by React now in preparation for Pods 2.9 repeatable fields that we're working on next. (@sc0ttkclark, @zrothauser) +* Feature: New field types for Heading and HTML. (@sc0ttkclark, @zrothauser) +* Feature: New Pods Blocks available and the underlying Pods Block PHP API is compatible with ACF Blocks if you've ever used those before. (@sc0ttkclark, @zrothauser) +* Feature: REST API endpoints are now available to create/edit various objects: Pods, Pod Groups, and Pod Fields. (@sc0ttkclark) +* Feature: WP-CLI commands that mirror the REST API endpoints we have. (@sc0ttkclark) +* Feature: The new WYSIWYG editor option to use [Quill Editor](https://github.com/zenoamaro/react-quill) is now available and the CLEditor has been removed. (@sc0ttkclark, @zrothauser) +* Compatibility: Completely updated compatibility with WPML and Polylang plugins. Found a bug? Have a great feature idea? Get on GitHub and tell us about it and we'll get right on it: https://pods.io/submit/ Our GitHub has the full list of all prior releases of Pods: https://github.com/pods-framework/pods/releases - == Upgrade Notice == -= 2.7 = -This upgrade requires a minimum PHP version of 5.3+ and WordPress 4.5+. += 2.8 = +This upgrade requires a minimum PHP version of 5.6+ and WordPress 5.5+. diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 554780e3b0..0000000000 --- a/rollup.config.js +++ /dev/null @@ -1,60 +0,0 @@ -import includePaths from 'rollup-plugin-includepaths'; -import replace from 'rollup-plugin-replace'; -import nodeResolve from 'rollup-plugin-node-resolve'; -import commonjs from 'rollup-plugin-commonjs'; -import html from 'rollup-plugin-html'; -import babel from 'rollup-plugin-babel'; -import { uglify } from 'rollup-plugin-uglify'; - -const includePathOptions = { - include: {}, - paths: [ 'ui/js' ], - external: [], - extensions: [ '.js', '.html' ] -}; - -export default { - input: 'ui/js/pods-dfv/_src/pods-dfv.js', - output: { - file: 'ui/js/pods-dfv/pods-dfv.min.js', - format: 'iife', - name: 'PodsDFV', // One single object added to the global namespace - globals: { - 'jquery': 'jQuery', - 'underscore': '_', - 'backbone': 'Backbone', - 'backbone.marionette': 'Marionette' - } - }, - external: [ - 'jquery', - 'underscore', - 'backbone', - 'backbone.marionette' - ], - plugins: [ - includePaths( includePathOptions ), - html(), - replace( { - // Needed for React, see https://github.com/rollup/rollup/issues/487#issuecomment-177596512 - 'process.env.NODE_ENV': JSON.stringify( 'production' ) - } ), - nodeResolve(), - commonjs( { - include: 'node_modules/**' - } ), - babel( { - babelrc: false, // Ignore the .babelrc file which is there for mocha tests - ignore: [ 'node_modules/**' ], - presets: [ - [ 'env', { modules: false } ], - [ 'react' ] - ], - plugins: [ - 'transform-object-rest-spread', - 'external-helpers' - ] - } ), - uglify() - ] -}; diff --git a/sql/update-2.0-beta.php b/sql/update-2.0-beta.php index d778211adb..5bceebeb2b 100644 --- a/sql/update-2.0-beta.php +++ b/sql/update-2.0-beta.php @@ -39,13 +39,11 @@ // Update to 2.0.0-b-11 if ( version_compare( $pods_version, '2.0.0-b-11', '<' ) ) { - $date_fields = $wpdb->get_results( - " + $date_fields = $wpdb->get_results( " SELECT `ID` FROM `{$wpdb->posts}` WHERE ( `post_name` = 'created' OR `post_name` = 'modified' ) AND `post_type` = '_pods_field' - " - ); + " ); if ( ! empty( $date_fields ) ) { foreach ( $date_fields as $date ) { @@ -71,8 +69,7 @@ $_GET = $oldget; - $number_fields = $wpdb->get_results( - " + $number_fields = $wpdb->get_results( " SELECT `p`.`ID` FROM `{$wpdb->posts}` AS `p` LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` @@ -80,8 +77,7 @@ `p`.`post_type` = '_pods_field' AND `pm`.`meta_key` = 'type' AND `pm`.`meta_value` = 'number' - " - ); + " ); if ( ! empty( $number_fields ) ) { foreach ( $number_fields as $number ) { @@ -155,8 +151,7 @@ pods_no_conflict_on( 'post' ); // convert field types based on options set - $fields = $wpdb->get_results( - " + $fields = $wpdb->get_results( " SELECT `p`.`ID` FROM `{$wpdb->posts}` AS `p` LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` @@ -164,8 +159,7 @@ `p`.`post_type` = '_pods_field' AND `pm`.`meta_key` = 'type' AND `pm`.`meta_value` = 'date' - " - ); + " ); if ( ! empty( $fields ) ) { foreach ( $fields as $field ) { @@ -192,8 +186,7 @@ }//end foreach }//end if - $fields = $wpdb->get_results( - " + $fields = $wpdb->get_results( " SELECT `p`.`ID` FROM `{$wpdb->posts}` AS `p` LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` @@ -201,8 +194,7 @@ `p`.`post_type` = '_pods_field' AND `pm`.`meta_key` = 'type' AND `pm`.`meta_value` = 'number' - " - ); + " ); if ( ! empty( $fields ) ) { foreach ( $fields as $field ) { @@ -223,8 +215,7 @@ } } - $fields = $wpdb->get_results( - " + $fields = $wpdb->get_results( " SELECT `p`.`ID` FROM `{$wpdb->posts}` AS `p` LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` @@ -232,8 +223,7 @@ `p`.`post_type` = '_pods_field' AND `pm`.`meta_key` = 'type' AND `pm`.`meta_value` = 'paragraph' - " - ); + " ); if ( ! empty( $fields ) ) { foreach ( $fields as $field ) { @@ -255,8 +245,7 @@ } } - $fields = $wpdb->get_results( - " + $fields = $wpdb->get_results( " SELECT `p`.`ID` FROM `{$wpdb->posts}` AS `p` LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID` @@ -264,8 +253,7 @@ `p`.`post_type` = '_pods_field' AND `pm`.`meta_key` = 'type' AND `pm`.`meta_value` = 'text' - " - ); + " ); if ( ! empty( $fields ) ) { foreach ( $fields as $field ) { @@ -338,18 +326,13 @@ * @param $options */ function pods_2_beta_migrate_type( $id, $options ) { - global $wpdb; foreach ( $options as $old => $new ) { - $wpdb->query( - $wpdb->prepare( - "UPDATE `{$wpdb->postmeta}` SET `meta_key` = %s WHERE `meta_key` = %s", array( - $new, - $old, - ) - ) - ); + $wpdb->query( $wpdb->prepare( "UPDATE `{$wpdb->postmeta}` SET `meta_key` = %s WHERE `meta_key` = %s", array( + $new, + $old, + ) ) ); } } @@ -357,7 +340,6 @@ function pods_2_beta_migrate_type( $id, $options ) { * @return array */ function pods_2_alpha_migrate_pods() { - $api = pods_api(); $api->display_errors = true; @@ -436,7 +418,6 @@ function pods_2_alpha_migrate_pods() { * @return array */ function pods_2_alpha_migrate_helpers() { - $api = pods_api(); $helper_rows = pods_query( "SELECT * FROM `@wp_pods_objects` WHERE `type` = 'helper'", false ); @@ -466,7 +447,6 @@ function pods_2_alpha_migrate_helpers() { * @return array */ function pods_2_alpha_migrate_pages() { - $api = pods_api(); $page_rows = pods_query( "SELECT * FROM `@wp_pods_objects` WHERE `type` = 'page'", false ); @@ -495,7 +475,6 @@ function pods_2_alpha_migrate_pages() { * @return array */ function pods_2_alpha_migrate_templates() { - $api = pods_api(); $tpl_rows = pods_query( "SELECT * FROM `@wp_pods_objects` WHERE `type` = 'template'", false ); diff --git a/sql/upgrade/PodsUpgrade.php b/sql/upgrade/PodsUpgrade.php index 2c115a4783..668877c68f 100644 --- a/sql/upgrade/PodsUpgrade.php +++ b/sql/upgrade/PodsUpgrade.php @@ -29,7 +29,6 @@ class PodsUpgrade { * */ public function __construct() { - $this->api = pods_api(); $this->get_tables(); @@ -40,7 +39,6 @@ public function __construct() { * @param null $_blog_id Blog ID to install. */ public function install( $_blog_id = null ) { - /** * @var $wpdb WPDB */ @@ -57,7 +55,14 @@ public function install( $_blog_id = null ) { do_action( 'pods_install', PODS_VERSION, $pods_version, $_blog_id ); - if ( ( ! pods_tableless() ) && false !== apply_filters( 'pods_install_run', null, PODS_VERSION, $pods_version, $_blog_id ) && 0 === (int) pods_v( 'pods_bypass_install' ) ) { + /** + * Allow filtering of whether the Pods SQL installation should be run. Return false to bypass. + * + * @param bool $run Whether the Pods SQL installation should be run. + */ + $run = apply_filters( 'pods_install_run', true, PODS_VERSION, $pods_version, $_blog_id ); + + if ( false !== $run && ! pods_tableless() && 0 === (int) pods_v( 'pods_bypass_install' ) ) { $sql = file_get_contents( PODS_DIR . 'sql/dump.sql' ); $sql = apply_filters( 'pods_install_sql', $sql, PODS_VERSION, $pods_version, $_blog_id ); @@ -107,7 +112,6 @@ public function install( $_blog_id = null ) { * */ public function get_tables() { - /** * @var $wpdb WPDB */ @@ -126,7 +130,6 @@ public function get_tables() { * */ public function get_progress() { - $methods = get_class_methods( $this ); foreach ( $methods as $method ) { @@ -148,7 +151,6 @@ public function get_progress() { * @return mixed|void */ public function ajax( $params ) { - if ( ! isset( $params->step ) ) { return pods_error( __( 'Invalid upgrade process.', 'pods' ) ); } @@ -167,10 +169,9 @@ public function ajax( $params ) { /** * @param $method * @param $v - * @param null $x + * @param null $x */ public function update_progress( $method, $v, $x = null ) { - if ( empty( $this->version ) ) { return; } @@ -188,12 +189,11 @@ public function update_progress( $method, $v, $x = null ) { /** * @param $method - * @param null $x + * @param null $x * * @return bool */ public function check_progress( $method, $x = null ) { - $method = str_replace( 'migrate_', '', $method ); if ( isset( $this->progress[ $method ] ) ) { @@ -211,7 +211,6 @@ public function check_progress( $method, $x = null ) { * */ public function upgraded() { - if ( empty( $this->version ) ) { return; } @@ -235,7 +234,6 @@ public function upgraded() { * */ public function cleanup() { - /** * @var $wpdb WPDB */ diff --git a/sql/upgrade/PodsUpgrade_2_0_0.php b/sql/upgrade/PodsUpgrade_2_0_0.php index 8653ce229c..e663e5a875 100644 --- a/sql/upgrade/PodsUpgrade_2_0_0.php +++ b/sql/upgrade/PodsUpgrade_2_0_0.php @@ -14,7 +14,6 @@ class PodsUpgrade_2_0_0 extends PodsUpgrade { * @return array|bool|int|mixed|null|void */ public function prepare_pods() { - /** * @var $wpdb WPDB */ @@ -39,7 +38,6 @@ public function prepare_pods() { * @return array|bool|int|mixed|null|void */ public function prepare_fields() { - /** * @var $wpdb WPDB */ @@ -64,7 +62,6 @@ public function prepare_fields() { * @return array|bool|int|mixed|null|void */ public function prepare_relationships() { - /** * @var $wpdb WPDB */ @@ -89,7 +86,6 @@ public function prepare_relationships() { * @return array|bool|int|mixed|null|void */ public function prepare_index() { - /** * @var $wpdb WPDB */ @@ -114,7 +110,6 @@ public function prepare_index() { * @return array|bool|int|mixed|null|void */ public function prepare_templates() { - /** * @var $wpdb WPDB */ @@ -139,7 +134,6 @@ public function prepare_templates() { * @return array|bool|int|mixed|null|void */ public function prepare_pages() { - /** * @var $wpdb WPDB */ @@ -164,7 +158,6 @@ public function prepare_pages() { * @return array|bool|int|mixed|null|void */ public function prepare_helpers() { - /** * @var $wpdb WPDB */ @@ -191,7 +184,6 @@ public function prepare_helpers() { * @return array|bool|int|mixed|null|void */ public function prepare_pod( $params ) { - /** * @var $wpdb WPDB */ @@ -262,7 +254,6 @@ public function prepare_pod( $params ) { * */ public function migrate_1_x() { - $old_version = get_option( 'pods_version' ); if ( 0 < strlen( $old_version ) ) { @@ -289,7 +280,6 @@ public function migrate_1_x() { * @return array|string */ public function migrate_pods() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -516,7 +506,6 @@ public function migrate_pods() { * @return string */ public function migrate_fields() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -556,7 +545,6 @@ public function migrate_fields() { * @return string */ public function migrate_relationships() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -658,12 +646,10 @@ public function migrate_relationships() { $old_field = $old_field[0]; - $related_field = $this->api->load_field( - array( + $related_field = $this->api->load_field( array( 'name' => $old_field->name, 'pod' => $old_field->pod, - ) - ); + ) ); if ( empty( $related_field ) ) { continue; @@ -733,7 +719,6 @@ public function migrate_relationships() { * @return string */ public function migrate_settings() { - return $this->migrate_roles(); } @@ -741,7 +726,6 @@ public function migrate_settings() { * @return string */ public function migrate_roles() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -813,7 +797,6 @@ public function migrate_roles() { * @return array|string */ public function migrate_templates() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -839,7 +822,6 @@ public function migrate_templates() { * @return array|string */ public function migrate_pages() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -863,7 +845,6 @@ public function migrate_pages() { * @return array|string */ public function migrate_helpers() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -901,7 +882,6 @@ public function migrate_helpers() { * @return mixed|string|void */ public function migrate_pod( $params ) { - /** * @var $wpdb WPDB */ @@ -943,13 +923,11 @@ public function migrate_pod( $params ) { $old_columns = array(); foreach ( $pod_data['fields'] as $field ) { - if ( ! in_array( - $field['name'], array( + if ( ! in_array( $field['name'], array( 'created', 'modified', 'author', - ), true - ) && ! in_array( $field['type'], array( 'file', 'pick' ), true ) ) { + ), true ) && ! in_array( $field['type'], array( 'file', 'pick' ), true ) ) { $columns[] = pods_sanitize( $field['name'] ); $old_columns[] = pods_v( '_pods_1x_field_name', $field['options'], $field['name'], false ); } @@ -1004,7 +982,6 @@ public function migrate_pod( $params ) { * @return string */ public function migrate_cleanup() { - update_option( 'pods_framework_upgraded_1_x', 1 ); PodsInit::$components->activate_component( 'templates' ); @@ -1020,7 +997,6 @@ public function migrate_cleanup() { * */ public function restart() { - /** * @var $wpdb WPDB */ @@ -1041,7 +1017,6 @@ public function restart() { * */ public function cleanup() { - /** * @var $wpdb WPDB */ diff --git a/sql/upgrade/PodsUpgrade_2_1_0.php b/sql/upgrade/PodsUpgrade_2_1_0.php index c284af2469..90aa0eff23 100644 --- a/sql/upgrade/PodsUpgrade_2_1_0.php +++ b/sql/upgrade/PodsUpgrade_2_1_0.php @@ -20,7 +20,6 @@ public function __construct() { * @return array|bool|int|mixed|null|void */ public function prepare_relationships() { - $relationship_fields = $this->api->load_fields( array( 'type' => 'pick' ) ); $count = 0; @@ -36,7 +35,6 @@ public function prepare_relationships() { * @return string */ public function migrate_relationships() { - if ( true === $this->check_progress( __FUNCTION__ ) ) { return '1'; } @@ -73,7 +71,6 @@ public function migrate_relationships() { $sql = ' '; - // if serialized (or array), save as individual meta items and save new order meta key }//end foreach @@ -94,7 +91,6 @@ public function migrate_relationships() { * @return string */ public function migrate_cleanup() { - $this->upgraded(); $this->api->cache_flush_pods(); @@ -106,7 +102,6 @@ public function migrate_cleanup() { * */ public function restart() { - $upgraded = get_option( 'pods_framework_upgraded' ); if ( empty( $upgraded ) || ! is_array( $upgraded ) ) { @@ -116,7 +111,7 @@ public function restart() { delete_option( 'pods_framework_upgrade_' . str_replace( '.', '_', $this->version ) ); if ( in_array( $this->version, $upgraded, true ) ) { - // @codingStandardsIgnoreLine + // @codingStandardsIgnoreLine unset( $upgraded[ array_search( $this->version, $upgraded ) ] ); } @@ -127,7 +122,6 @@ public function restart() { * */ public function cleanup() { - $this->restart(); } } diff --git a/src/Pods/API/Whatsit/Value_Field.php b/src/Pods/API/Whatsit/Value_Field.php new file mode 100644 index 0000000000..31fb752248 --- /dev/null +++ b/src/Pods/API/Whatsit/Value_Field.php @@ -0,0 +1,229 @@ +_field = $field; + } + + /** + * Easy to reference init static function for array_map() to use. + * + * @param Whatsit $field The field object. + * + * @return Value_Field + */ + public static function init( Whatsit $field ) { + return new static( $field ); + } + + /** + * On cast to string, return object identifier. + * + * @return string Object identifier. + * + * @uses Whatsit::__toString() + */ + public function __toString() { + return $this->_field->get_identifier(); + } + + /** + * Check if offset exists. + * + * @param mixed $offset Offset name. + * + * @return bool Whether the offset exists. + */ + public function offsetExists( $offset ) { + return $this->__isset( $offset ); + } + + /** + * Get offset value. + * + * @param mixed $offset Offset name. + * + * @return mixed|null Offset value, or null if not set. + */ + public function &offsetGet( $offset ) { + // We fake the pass by reference to avoid PHP errors for backcompat. + $value = $this->__get( $offset ); + + return $value; + } + + /** + * Set offset value. + * + * @param mixed $offset Offset name. + * @param mixed $value Offset value. + */ + public function offsetSet( $offset, $value ) { + if ( null === $offset ) { + // Do not allow $object[] additions. + return; + } + + $this->__set( $offset, $value ); + } + + /** + * Unset offset value. + * + * @param mixed $offset Offset name. + */ + public function offsetUnset( $offset ) { + $this->__unset( $offset ); + } + + /** + * Check if offset exists. + * + * @param mixed $offset Offset name. + * + * @return bool Whether the offset exists. + * + * @uses Whatsit::__isset() + */ + public function __isset( $offset ) { + if ( 'value' === $offset ) { + return isset( $this->_value ); + } + + return $this->_field->__isset( $offset ); + } + + /** + * Get offset value. + * + * @param mixed $offset Offset name. + * + * @return mixed|null Offset value, or null if not set. + * + * @uses Whatsit::__get() + */ + public function __get( $offset ) { + if ( 'value' === $offset ) { + return $this->_value; + } + + return $this->_field->__get( $offset ); + } + + /** + * Set offset value. + * + * @param mixed $offset Offset name. + * @param mixed $value Offset value. + * + * @uses Whatsit::__set() + */ + public function __set( $offset, $value ) { + if ( 'value' === $offset ) { + $this->_value = $value; + + return; + } + + $this->_field->__set( $offset, $value ); + } + + /** + * Unset offset value. + * + * @param mixed $offset Offset name. + * + * @uses Whatsit::__unset() + */ + public function __unset( $offset ) { + if ( 'value' === $offset ) { + $this->_value = null; + + return; + } + + $this->_field->__unset( $offset ); + } + + /** + * Call a method on the field. + * + * @param string $method The method name. + * @param array $arguments List of arguments. + * + * @return mixed The method response. + */ + public function __call( $method, $arguments ) { + return call_user_func_array( [ $this->_field, $method ], $arguments ); + } + + /** + * Get the field object. + * + * @return Whatsit|Field|Object_Field The field object. + */ + public function get_field_object() { + return $this->_field; + } + + /** + * Get the field value. + * + * @return mixed The field value. + */ + public function get_field_value() { + return $this->_value; + } + + /** + * Set the field object. + * + * @param Whatsit|Field|Object_Field The field object. + */ + public function set_field_object( $field ) { + $this->_field = $field; + } + + /** + * Set the field value. + * + * @param mixed The field value. + */ + public function set_field_value( $value ) { + $this->_value = $value; + } + +} diff --git a/src/Pods/Admin/Config/Base.php b/src/Pods/Admin/Config/Base.php new file mode 100644 index 0000000000..bdaeb7a3af --- /dev/null +++ b/src/Pods/Admin/Config/Base.php @@ -0,0 +1,38 @@ + __( 'Field Details', 'pods' ), + ]; + + $field_types = PodsForm::field_types(); + + foreach ( $field_types as $type => $field_type_data ) { + $core_tabs[ 'additional-field-' . $type ] = [ + 'name' => 'additional-field-' . $type, + /* translators: %s: Field type label. */ + 'label' => sprintf( _x( '%s Options', 'Field type options', 'pods' ), $field_type_data['label'] ), + 'depends-on' => [ + 'type' => $type, + ], + ]; + } + + $core_tabs['advanced'] = __( 'Advanced', 'pods' ); + + // Only include kitchen sink if dev mode on and not running Codecept tests. + if ( pods_developer() && ! function_exists( 'codecept_debug' ) ) { + $core_tabs['kitchen-sink'] = __( 'Kitchen Sink (temp)', 'pods' ); + } + + $pod_type = $pod['type']; + $pod_name = $pod['name']; + + $tabs = $core_tabs; + + /** + * Filter the Pod Field option tabs for a specific pod type and name. + * + * @since 2.8.0 + * + * @param array $core_tabs Tabs to set. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $tabs = (array) apply_filters( "pods_admin_setup_edit_field_tabs_{$pod_type}_{$pod_name}", $tabs, $pod ); + + /** + * Filter the Pod Field option tabs for a specific pod type. + * + * @since 2.8.0 + * + * @param array $tabs Tabs to set. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $tabs = (array) apply_filters( "pods_admin_setup_edit_field_tabs_{$pod_type}", $tabs, $pod ); + + /** + * Filter the Pod Field option tabs. + * + * @since 2.8.0 + * + * @param array $tabs Tabs to set. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $tabs = (array) apply_filters( 'pods_admin_setup_edit_field_tabs', $tabs, $pod ); + + // Sort and then enforce the core tabs to be in front. + uksort( $tabs, 'strnatcmp' ); + + $tabs = array_merge( $core_tabs, $tabs ); + + return $tabs; + } + + /** + * Get list of fields for the Field object. + * + * @since 2.8.0 + * + * @param \Pods\Whatsit\Pod $pod The pod object. + * @param array $tabs The list of tabs for the pod object. + * + * @return array List of fields for the Field object. + */ + public function get_fields( \Pods\Whatsit\Pod $pod, array $tabs ) { + $field_types = PodsForm::field_types(); + $tableless_field_types = PodsForm::tableless_field_types(); + + $options = []; + + $options['basic'] = [ + 'label' => [ + 'name' => 'label', + 'label' => __( 'Label', 'pods' ), + 'type' => 'text', + 'default' => '', + 'help' => 'help', + 'required' => true, + ], + 'name' => [ + 'name' => 'name', + 'label' => __( 'Name', 'pods' ), + 'type' => 'slug', + 'default' => '', + 'attributes' => [ + 'maxlength' => 50, + ], + 'help' => 'help', + 'required' => true, + ], + 'description' => [ + 'name' => 'description', + 'label' => __( 'Description', 'pods' ), + 'type' => 'text', + 'default' => '', + 'help' => 'help', + ], + 'type' => [ + 'name' => 'type', + 'label' => __( 'Field Type', 'pods' ), + 'type' => 'pick', + 'default' => 'text', + 'required' => true, + 'data' => [], + 'dependency' => true, + 'help' => 'help', + ], + 'pick_object' => [ + 'name' => 'pick_object', + 'label' => __( 'Related Type', 'pods' ), + 'type' => 'pick', + 'default' => '', + 'data' => [], + 'pick_show_select_text' => 0, + 'dependency' => true, + 'depends-on' => [ + 'type' => 'pick', + ], + 'help' => 'help', + ], + 'pick_custom' => [ + 'name' => 'pick_custom', + 'label' => __( 'Custom Defined Options', 'pods' ), + 'type' => 'paragraph', + 'default' => '', + 'required' => true, + 'depends-on' => [ + 'type' => 'pick', + 'pick_object' => 'custom-simple', + ], + 'help' => __( 'One option per line, use value|Label for separate values and labels', 'pods' ), + ], + 'pick_table' => [ + 'name' => 'pick_table', + 'label' => __( 'Related Table', 'pods' ), + 'type' => 'pick', + 'default' => '', + 'data' => [], + 'pick_show_select_text' => 0, + 'depends-on' => [ + 'type' => 'pick', + 'pick_object' => 'table', + ], + 'help' => 'help', + ], + 'sister_id' => [ + 'name' => 'sister_id', + 'label' => __( 'Bi-directional Field', 'pods' ), + 'type' => 'pick', + 'default' => '', + 'data' => [], + 'depends-on' => [ + 'type' => 'pick', + 'pick_object' => PodsForm::field_method( 'pick', 'bidirectional_objects' ), + ], + 'help' => __( 'Bi-directional fields will update their related field for any item you select. This feature is only available for two relationships between two Pods.

            For example, when you update a Parent pod item to relate to a Child item, when you go to edit that Child item you will see the Parent pod item selected.', 'pods' ), + ], + 'required' => [ + 'name' => 'required', + 'label' => __( 'Required', 'pods' ), + 'type' => 'boolean', + 'default' => 0, + 'boolean_yes_label' => '', + 'help' => __( 'This will require a non-empty value to be entered.', 'pods' ), + ], + ]; + $options['advanced'] = [ + 'visual' => [ + 'name' => 'visual', + 'label' => __( 'Visual', 'pods' ), + 'type' => 'heading', + ], + 'class' => [ + 'name' => 'class', + 'label' => __( 'Additional CSS Classes', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'values' => [ + 'name' => 'values', + 'label' => __( 'Values', 'pods' ), + 'type' => 'heading', + ], + 'default_value' => [ + 'name' => 'default_value', + 'label' => __( 'Default Value', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'options' => [ + 'text_max_length' => - 1, + ], + ], + 'default_value_parameter' => [ + 'name' => 'default_value_parameter', + 'label' => __( 'Set Default Value via Parameter', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'visibility' => [ + 'name' => 'visibility', + 'label' => __( 'Visibility', 'pods' ), + 'type' => 'heading', + ], + 'restrict_access' => [ + 'type' => 'boolean_group', + 'name' => 'restrict_access', + 'label' => __( 'Restrict Access', 'pods' ), + 'boolean_group' => [ + 'logged_in_only' => [ + 'name' => 'logged_in_only', + 'label' => __( 'Restrict access to Logged In Users', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + 'help' => __( 'This field will only be able to be edited by logged in users. This is not required to be on for the other Restrict Access options to work.', 'pods' ), + ], + 'admin_only' => [ + 'name' => 'admin_only', + 'label' => __( 'Restrict access to Admins', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + 'help' => __( 'This field will only be able to be edited by users with the ability to manage_options or delete_users, or super admins of a WordPress Multisite network', 'pods' ), + ], + 'restrict_role' => [ + 'name' => 'restrict_role', + 'label' => __( 'Restrict access by Role', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + ], + 'restrict_capability' => [ + 'name' => 'restrict_capability', + 'label' => __( 'Restrict access by Capability', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + ], + 'hidden' => [ + 'name' => 'hidden', + 'label' => __( 'Hide field from UI', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'help' => __( 'This option is overridden by access restrictions. If the user does not have access to edit this field, it will be hidden. If no access restrictions are set, this field will always be hidden.', 'pods' ), + ], + 'read_only' => [ + 'name' => 'read_only', + 'label' => __( 'Make field "Read Only" in UI', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'help' => __( 'This option is overridden by access restrictions. If the user does not have access to edit this field, it will be read only. If no access restrictions are set, this field will always be read only.', 'pods' ), + 'depends-on' => [ + 'type' => [ + 'boolean', + 'color', + 'currency', + 'date', + 'datetime', + 'email', + 'number', + 'paragraph', + 'password', + 'phone', + 'slug', + 'text', + 'time', + 'website', + ], + ], + ], + ], + ], + 'roles_allowed' => [ + 'name' => 'roles_allowed', + 'label' => __( 'Role(s) Allowed', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'pick_object' => 'role', + 'pick_format_type' => 'multi', + 'default' => 'administrator', + 'depends-on' => [ + 'restrict_role' => true, + ], + 'help' => __( 'If none are selected, this option will be ignored.', 'pods' ), + ], + 'capability_allowed' => [ + 'name' => 'capability_allowed', + 'label' => __( 'Capability Allowed', 'pods' ), + 'help' => __( 'Comma-separated list of capabilities, for example add_podname_item, please see the Roles and Capabilities component for the complete list and a way to add your own.', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ + 'restrict_capability' => true, + ], + 'help' => __( 'If none are selected, this option will be ignored.', 'pods' ), + ], + ]; + + $pick_tables = pods_transient_get( 'pods_tables' ); + + if ( empty( $pick_tables ) ) { + $pick_tables = [ + '' => __( '-- Select Table --', 'pods' ), + ]; + + global $wpdb; + + $tables = $wpdb->get_results( 'SHOW TABLES', ARRAY_N ); + + if ( ! empty( $tables ) ) { + foreach ( $tables as $table ) { + $pick_tables[ $table[0] ] = $table[0]; + } + } + + pods_transient_set( 'pods_tables', $pick_tables, WEEK_IN_SECONDS ); + } + + $field_settings = [ + 'field_types_select' => [], + 'pick_object' => PodsForm::field_method( 'pick', 'related_objects', true ), + 'pick_table' => $pick_tables, + 'sister_id' => [ + '' => __( 'No Related Fields Found', 'pods' ), + ], + ]; + + $pod_name = $pod['name']; + $pod_type = $pod['type']; + + foreach ( $field_types as $type => $field_type_data ) { + /** + * @var $field_type PodsField + */ + $field_type_object = PodsForm::field_loader( $type, $field_type_data['file'] ); + + $field_type_vars = get_class_vars( get_class( $field_type_object ) ); + + if ( ! isset( $field_type_vars['pod_types'] ) ) { + $field_type_vars['pod_types'] = true; + } + + $options[ 'additional-field-' . $type ] = []; + + // Only show supported field types + if ( true !== $field_type_vars['pod_types'] ) { + if ( empty( $field_type_vars['pod_types'] ) ) { + continue; + } elseif ( is_array( $field_type_vars['pod_types'] ) && ! in_array( $pod_type, $field_type_vars['pod_types'], true ) ) { + continue; + } elseif ( ! is_array( $field_type_vars['pod_types'] ) && $pod_type !== $field_type_vars['pod_types'] ) { + continue; + } + } + + if ( ! empty( PodsForm::$field_group ) ) { + if ( ! isset( $field_settings['field_types_select'][ PodsForm::$field_group ] ) ) { + $field_settings['field_types_select'][ PodsForm::$field_group ] = []; + } + + $field_settings['field_types_select'][ PodsForm::$field_group ][ $type ] = $field_type_data['label']; + } else { + if ( ! isset( $field_settings['field_types_select'][ __( 'Other', 'pods' ) ] ) ) { + $field_settings['field_types_select'][ __( 'Other', 'pods' ) ] = []; + } + + $field_settings['field_types_select'][ __( 'Other', 'pods' ) ][ $type ] = $field_type_data['label']; + } + + $type_options = PodsForm::ui_options( $type ); + + $dev_mode = pods_developer(); + + if ( ! $dev_mode ) { + foreach ( $type_options as $type_option => $option_data ) { + if ( ! empty( $option_data['developer_mode'] ) ) { + unset( $type_options[ $type_option ] ); + } + } + } + + /** + * Modify Additional Field Options tab + * + * @since 2.7.0 + * + * @param array $type_options Additional field type options, + * @param string $type Field type, + * @param array $options Tabs, indexed by label, + * @param null|\Pods\Whatsit\Pod $pod Pods object for the Pod this UI is for. + */ + $type_options = apply_filters( "pods_admin_setup_edit_{$type}_additional_field_options", $type_options, $type, $options, $pod ); + $type_options = apply_filters( 'pods_admin_setup_edit_additional_field_options', $type_options, $type, $options, $pod ); + + $options[ 'additional-field-' . $type ] = $type_options; + }//end foreach + + /** + * Allow filtering the field settings by pod name. + * + * @param array $field_settings List of field settings to use. + * @param null|\Pods\Whatsit\Pod $pod Pods object for the Pod this UI is for. + * @param array $tabs List of registered tabs + */ + $field_settings = apply_filters( "pods_field_settings_{$pod_name}", $field_settings, $pod ); + + /** + * Allow filtering the field settings by pod name. + * + * @param array $field_settings List of field settings to use. + * @param null|\Pods\Whatsit\Pod $pod Pods object for the Pod this UI is for. + * @param array $tabs List of registered tabs + */ + $field_settings = apply_filters( 'pods_field_settings', $field_settings, $pod, $tabs ); + + $options['basic']['type']['data'] = $field_settings['field_types_select']; + $options['basic']['pick_object']['data'] = $field_settings['pick_object']; + $options['basic']['pick_table']['data'] = $field_settings['pick_table']; + + // @todo Look into supporting these in the future. + /*Tribe__Main::array_insert_after_key( 'visibility', $options['advanced'], [ + 'search' => [ + 'label' => __( 'Include in searches', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'default' => 1, + 'type' => 'boolean', + ], + ] ); + + Tribe__Main::array_insert_after_key( 'validation', $options['advanced'], [ + 'regex_validation' => [ + 'label' => __( 'RegEx Validation', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'message_regex' => [ + 'label' => __( 'Message if field does not pass RegEx', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'message_required' => [ + 'label' => __( 'Message if field is blank', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'required' => true ], + ], + 'message_unique' => [ + 'label' => __( 'Message if field is not unique', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'unique' => true ], + ], + ] );*/ + + if ( 'table' === $pod['storage'] || 'pod' === $pod['type'] ) { + $options['basic']['unique'] = [ + 'name' => 'unique', + 'label' => __( 'Unique', 'pods' ), + 'type' => 'boolean', + 'default' => 0, + 'boolean_yes_label' => '', + 'help' => __( 'This will require that the field value entered is unique and has not been saved before.', 'pods' ), + 'excludes-on' => [ + 'type' => $tableless_field_types, + ], + ]; + } + + // Only include kitchen sink if dev mode on and not running Codecept tests. + if ( pods_developer() && ! function_exists( 'codecept_debug' ) ) { + $options['kitchen-sink'] = json_decode( file_get_contents( PODS_DIR . 'tests/codeception/_data/kitchen-sink-config.json' ), true ); + } + + $pod_type = $pod['type']; + $pod_name = $pod['name']; + + /** + * Add admin fields to the Pod Fields editor for a specific Pod. + * + * @since 2.8.0 + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( "pods_admin_setup_edit_field_options_{$pod_type}_{$pod_name}", $options, $pod, $tabs ); + + /** + * Add admin fields to the Pod Fields editor for any Pod of a specific content type. + * + * @since 2.8.0 + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( "pods_admin_setup_edit_field_options_{$pod_type}", $options, $pod, $tabs ); + + /** + * Add admin fields to the Pod Fields editor for all Pods. + * + * @since 2.8.0 + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( 'pods_admin_setup_edit_field_options', $options, $pod, $tabs ); + + return $options; + } +} diff --git a/src/Pods/Admin/Config/Group.php b/src/Pods/Admin/Config/Group.php new file mode 100644 index 0000000000..1e57cb11d9 --- /dev/null +++ b/src/Pods/Admin/Config/Group.php @@ -0,0 +1,279 @@ + __( 'Group Details', 'pods' ), + 'advanced' => __( 'Advanced', 'pods' ), + ]; + + // Only include kitchen sink if dev mode on and not running Codecept tests. + if ( pods_developer() && ! function_exists( 'codecept_debug' ) ) { + $core_tabs['kitchen-sink'] = __( 'Kitchen Sink (temp)', 'pods' ); + } + + $pod_type = $pod['type']; + $pod_name = $pod['name']; + + $tabs = $core_tabs; + + /** + * Filter the Pod Group option tabs for a specific pod type and name. + * + * @since 2.8.0 + * + * @param array $core_tabs Tabs to set. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $tabs = (array) apply_filters( "pods_admin_setup_edit_group_tabs_{$pod_type}_{$pod_name}", $tabs, $pod ); + + /** + * Filter the Pod Group option tabs for a specific pod type. + * + * @since 2.8.0 + * + * @param array $tabs Tabs to set. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $tabs = (array) apply_filters( "pods_admin_setup_edit_group_tabs_{$pod_type}", $tabs, $pod ); + + /** + * Filter the Pod Group option tabs. + * + * @since 2.8.0 + * + * @param array $tabs Tabs to set. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $tabs = (array) apply_filters( 'pods_admin_setup_edit_group_tabs', $tabs, $pod ); + + // Sort and then enforce the core tabs to be in front. + uksort( $tabs, 'strnatcmp' ); + + $tabs = array_merge( $core_tabs, $tabs ); + + return $tabs; + } + + /** + * Get list of fields for the Group object. + * + * @since 2.8.0 + * + * @param \Pods\Whatsit\Pod $pod The pod object. + * @param array $tabs The list of tabs for the pod object. + * + * @return array List of fields for the Group object. + */ + public function get_fields( \Pods\Whatsit\Pod $pod, array $tabs ) { + $options = []; + + $options['basic'] = [ + 'label' => [ + 'name' => 'label', + 'label' => __( 'Label', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'required' => true, + 'default' => '', + ], + 'name' => [ + 'name' => 'name', + 'label' => __( 'Name', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'slug', + 'required' => true, + 'default' => '', + ], + /*'description' => [ + 'name' => 'description', + 'label' => __( 'Description', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ],*/ + /*'type' => [ + 'name' => 'type', + 'label' => __( 'Type', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => '', + 'data' => [], + ],*/ + ]; + + $options['advanced'] = [ + 'visibility' => [ + 'name' => 'visibility', + 'label' => __( 'Visibility', 'pods' ), + 'type' => 'heading', + ], + 'restrict_access' => [ + 'type' => 'boolean_group', + 'name' => 'restrict_access', + 'label' => __( 'Restrict Access', 'pods' ), + 'boolean_group' => [ + 'logged_in' => [ + 'name' => 'logged_in', + 'label' => __( 'Restrict access to Logged In Users', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + 'help' => __( 'This group of field will only be able to be edited by logged in users. This is not required to be on for the other Restrict Access options to work.', 'pods' ), + ], + 'admin_only' => [ + 'name' => 'admin_only', + 'label' => __( 'Restrict access to Admins', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + 'help' => __( 'This group of fields will only be able to be edited by users with the ability to manage_options or delete_users, or super admins of a WordPress Multisite network', 'pods' ), + ], + 'restrict_role' => [ + 'name' => 'restrict_role', + 'label' => __( 'Restrict access by Role', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + ], + 'restrict_capability' => [ + 'name' => 'restrict_capability', + 'label' => __( 'Restrict access by Capability', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + ], + ], + ], + 'roles_allowed' => [ + 'name' => 'roles_allowed', + 'label' => __( 'Role(s) Allowed', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'pick_object' => 'role', + 'pick_format_type' => 'multi', + 'default' => 'administrator', + 'depends-on' => [ + 'restrict_role' => true, + ], + 'help' => __( 'If none are selected, this option will be ignored.', 'pods' ), + ], + 'capability_allowed' => [ + 'name' => 'capability_allowed', + 'label' => __( 'Capability Allowed', 'pods' ), + 'help' => __( 'Comma-separated list of capabilities, for example add_podname_item, please see the Roles and Capabilities component for the complete list and a way to add your own.', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ + 'restrict_capability' => true, + ], + 'help' => __( 'If none are selected, this option will be ignored.', 'pods' ), + ], + ]; + + $object_type = $pod->get_type(); + + $is_post_type = 'post_type' === $object_type; + $is_comment_type = 'comment' === $object_type; + + if ( $is_post_type || $is_comment_type ) { + $options['basic']['meta_box_context'] = [ + 'name' => 'meta_box_context', + 'label' => __( 'Meta Box Context', 'pods' ), + 'help' => [ + __( 'See add_meta_box() documentation.', 'pods' ), + 'https://developer.wordpress.org/reference/functions/add_meta_box/#parameters', + ], + 'type' => 'pick', + 'default' => 'normal', + 'data' => [ + 'normal' => __( 'Normal', 'pods' ), + 'side' => __( 'Side', 'pods' ), + 'advanced' => __( 'Advanced', 'pods' ), + ], + 'pick_show_select_text' => 0, + ]; + + if ( $is_comment_type ) { + unset( $options['basic']['group_context']['data']['advanced'] ); + } + + $options['basic']['meta_box_priority'] = [ + 'name' => 'meta_box_priority', + 'label' => __( 'Meta Box Priority', 'pods' ), + 'help' => [ + __( 'See add_meta_box() documentation.', 'pods' ), + 'https://developer.wordpress.org/reference/functions/add_meta_box/#parameters', + ], + 'type' => 'pick', + 'default' => 'default', + 'data' => [ + 'high' => __( 'High', 'pods' ), + 'default' => __( 'Default', 'pods' ), + 'low' => __( 'Low', 'pods' ), + ], + 'pick_show_select_text' => 0, + ]; + } + + // Only include kitchen sink if dev mode on and not running Codecept tests. + if ( pods_developer() && ! function_exists( 'codecept_debug' ) ) { + $options['kitchen-sink'] = json_decode( file_get_contents( PODS_DIR . 'tests/codeception/_data/kitchen-sink-config.json' ), true ); + } + + $pod_type = $pod['type']; + $pod_name = $pod['name']; + + /** + * Add admin fields to the Pod Groups editor for a specific Pod. + * + * @since 2.8.0 + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( "pods_admin_setup_edit_group_options_{$pod_type}_{$pod_name}", $options, $pod, $tabs ); + + /** + * Add admin fields to the Pod Groups editor for any Pod of a specific content type. + * + * @since 2.8.0 + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( "pods_admin_setup_edit_group_options_{$pod_type}", $options, $pod, $tabs ); + + /** + * Add admin fields to the Pod Groups editor for all Pods. + * + * @since 2.8.0 + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( 'pods_admin_setup_edit_group_options', $options, $pod, $tabs ); + + return $options; + } +} diff --git a/src/Pods/Admin/Config/Pod.php b/src/Pods/Admin/Config/Pod.php new file mode 100644 index 0000000000..894923d47a --- /dev/null +++ b/src/Pods/Admin/Config/Pod.php @@ -0,0 +1,1590 @@ + [ + 'label' => __( 'Label', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ), + 'text_max_length' => 30, + ], + 'label_singular' => [ + 'label' => __( 'Singular Label', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => pods_v( 'label_singular', $pod, pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ) ), + 'text_max_length' => 30, + ], + 'placeholder_enter_title_here' => [ + 'label' => __( 'New post title placeholder text', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'placeholder' => __( 'Add title' ), + 'object_type' => [ 'post_type' ], + ], + 'label_add_new' => [ + 'label' => __( 'Add New', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type', 'pod' ], + ], + 'label_add_new_item' => [ + 'label' => __( 'Add new %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_new_item' => [ + 'label' => __( 'New %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type', 'pod' ], + ], + 'label_new_item_name' => [ + 'label' => __( 'New %s Name', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_edit' => [ + 'label' => __( 'Edit', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_edit_item' => [ + 'label' => __( 'Edit %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_update_item' => [ + 'label' => __( 'Update %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy', 'pod' ], + ], + 'label_duplicate' => [ + 'label' => __( 'Duplicate', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_duplicate_item' => [ + 'label' => __( 'Duplicate %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_delete_item' => [ + 'label' => __( 'Delete %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_view' => [ + 'label' => __( 'View', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_view_item' => [ + 'label' => __( 'View %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_view_items' => [ + 'label' => __( 'View %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_back_to_manage' => [ + 'label' => __( 'Back to Manage', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_manage' => [ + 'label' => __( 'Manage', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_manage_items' => [ + 'label' => __( 'Manage %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_reorder' => [ + 'label' => __( 'Reorder', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_reorder_items' => [ + 'label' => __( 'Reorder %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_all_items' => [ + 'label' => __( 'All %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_search' => [ + 'label' => __( 'Search', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_search_items' => [ + 'label' => __( 'Search %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_popular_items' => [ + 'label' => __( 'Popular %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_parent' => [ + 'label' => __( 'Parent %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type', 'pod' ], + ], + 'label_parent_item' => [ + 'label' => __( 'Parent %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_parent_item_colon' => [ + 'label' => __( 'Parent %s:', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_not_found' => [ + 'label' => __( 'Not Found', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'label_no_items_found' => [ + 'label' => __( 'No %s Found', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'pod' ], + ], + 'label_not_found_in_trash' => [ + 'label' => __( 'Not Found in Trash', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type', 'pod' ], + ], + 'label_archives' => [ + 'label' => __( '%s Archives', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_attributes' => [ + 'label' => __( '%s Attributes', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_insert_into_item' => [ + 'label' => __( 'Insert into %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_uploaded_to_this_item' => [ + 'label' => __( 'Uploaded to this %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_featured_image' => [ + 'label' => __( 'Featured Image', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working + 'object_type' => [ 'post_type' ], + ], + 'label_set_featured_image' => [ + 'label' => __( 'Set featured Image', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working + 'object_type' => [ 'post_type' ], + ], + 'label_remove_featured_image' => [ + 'label' => __( 'Remove featured Image', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working + 'object_type' => [ 'post_type' ], + ], + 'label_use_featured_image' => [ + 'label' => __( 'Use as featured Image', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working + 'object_type' => [ 'post_type' ], + ], + 'label_filter_items_list' => [ + 'label' => __( 'Filter %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_items_list_navigation' => [ + 'label' => __( '%s list navigation', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type', 'taxonomy' ], + ], + 'label_items_list' => [ + 'label' => __( '%s list', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'Items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type', 'taxonomy' ], + ], + 'label_separate_items_with_commas' => [ + 'label' => __( 'Separate %s with commas', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_add_or_remove_items' => [ + 'label' => __( 'Add or remove %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_choose_from_the_most_used' => [ + 'label' => __( 'Choose from the most used %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_no_terms' => [ + 'label' => __( 'No %s', 'pods' ), + 'label_param' => 'label', + 'label_param_default' => __( 'items', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + 'label_item_published' => [ + 'label' => __( '%s Published.', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_item_published_privately' => [ + 'label' => __( '%s published privately.', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_item_reverted_to_draft' => [ + 'label' => __( '%s reverted to draft.', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_item_scheduled' => [ + 'label' => __( '%s scheduled.', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'label_item_updated' => [ + 'label' => __( '%s updated.', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'filter_by_date' => [ + 'label' => __( 'Filter by date', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'post_type' ], + ], + 'filter_by_item' => [ + 'label' => __( 'Filter by %s', 'pods' ), + 'label_param' => 'label_singular', + 'label_param_default' => __( 'Item', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'object_type' => [ 'taxonomy' ], + ], + ]; + + $options['labels'] = []; + + /** + * Filter through all labels if they have an object_type set and match it against the current object type + */ + foreach ( $labels as $label => $label_data ) { + if ( array_key_exists( 'object_type', $label_data ) ) { + if ( in_array( $pod_type, $label_data['object_type'], true ) ) { + // Do not add the object_type to the actual label data + unset( $label_data['object_type'] ); + + $options['labels'][ $label ] = $label_data; + } + } else { + $options['labels'][ $label ] = $label_data; + } + } + } elseif ( 'settings' === $pod_type ) { + $options['labels'] = [ + 'label' => [ + 'label' => __( 'Page Title', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => str_replace( '_', ' ', pods_v( 'name', $pod ) ), + 'text_max_length' => 30, + ], + 'menu_name' => [ + 'label' => __( 'Menu Name', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ), + 'text_max_length' => 30, + ], + ]; + }//end if + + if ( 'post_type' === $pod_type ) { + $options['admin-ui'] = [ + 'description' => [ + 'label' => __( 'Post Type Description', 'pods' ), + 'help' => __( 'A short descriptive summary of what the post type is.', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'show_ui' => [ + 'label' => __( 'Show Admin UI', 'pods' ), + 'help' => __( 'Whether to generate a default UI for managing this post type in the admin.', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'public', $pod, true ), + 'boolean_yes_label' => '', + ], + 'show_in_menu' => [ + 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ), + 'help' => __( 'Whether to show the post type in the admin menu.', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'public', $pod, true ), + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'menu_location_custom' => [ + 'label' => __( 'Parent Menu ID (optional)', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'menu_name' => [ + 'label' => __( 'Menu Name', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'menu_position' => [ + 'label' => __( 'Menu Position', 'pods' ), + 'help' => __( 'This will be the position of the menu item. See WordPress.org Developer Docs for more details about how positioning works.', 'pods' ), + 'type' => 'number', + 'number_decimals' => 2, + 'number_format' => '9999.99', + 'number_format_soft' => 1, + 'default' => 0, + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'menu_icon' => [ + 'label' => __( 'Menu Icon', 'pods' ), + 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the site tag type special magic tags. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a Dashicon. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'show_in_nav_menus' => [ + 'label' => __( 'Show in Navigation Menus', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + ], + 'show_in_admin_bar' => [ + 'label' => __( 'Show in Admin Bar "New" Menu', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'name_admin_bar' => [ + 'label' => __( 'Admin bar name', 'pods' ), + 'help' => __( 'Defaults to singular name', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'show_in_admin_bar' => true ], + ], + ]; + + $post_type_name = pods_v( 'name', $pod, 'post_type', true ); + + /** + * Allow filtering the default post status. + * + * @param string $default_post_status The default post status. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + */ + $default_post_status = apply_filters( "pods_api_default_status_{$post_type_name}", 'draft', $pod ); + + $options['connections'] = [ + 'post_type_built_in_taxonomies' => [ + 'name' => 'post_type_built_in_taxonomies', + 'label' => __( 'Enable Connections to Taxonomy', 'pods' ), + 'help' => __( 'You can enable the ability to select terms from these Taxonomies on any post for this Post Type. Once connected, posts from this Custom Post Type will appear in the Taxonomy archive page of the associated Taxonomies selected. Only Categories and Tag need to be specifically selected to be shown on Taxonomy archives on their own.', 'pods' ), + 'type' => 'boolean_group', + 'boolean_group' => [], + 'dependency' => true, + ], + ]; + + // Only show this if it is a Custom Post Type. + if ( '' === $pod_object ) { + $options['connections']['archive_show_in_taxonomies'] = [ + 'name' => 'archive_show_in_taxonomies', + 'label' => __( 'Show in Taxonomy Archives', 'pods' ), + 'help' => __( 'You can include posts from this Custom Post Type in the Taxonomy archive page for Categories and Tags. These Taxonomies operate differently in WordPress and require an opt-in to have Custom Post Types included.', 'pods' ), + 'type' => 'boolean_group', + 'boolean_group' => [], + 'depends-on-any' => [ + 'built_in_taxonomies_category' => true, + 'built_in_taxonomies_post_tag' => true, + ], + ]; + } + + $options['connections']['register_custom_post_type'] = [ + 'name' => 'register_custom_post_type', + 'label' => __( 'Add new connections', 'pods' ), + 'type' => 'html', + 'html_content' => sprintf( + 'Create a new Custom Post Type', + esc_url( admin_url( 'admin.php?page=pods-add-new&create_extend=create&type=post_type' ) ) + ), + ]; + + $options['advanced'] = [ + 'public' => [ + 'label' => __( 'Public', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + ], + 'publicly_queryable' => [ + 'label' => __( 'Publicly Queryable', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'public', $pod, true ), + 'boolean_yes_label' => '', + ], + 'exclude_from_search' => [ + 'label' => __( 'Exclude from Search', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => ! pods_v( 'public', $pod, true ), + 'boolean_yes_label' => '', + ], + 'capability_type' => [ + 'label' => __( 'User Capability', 'pods' ), + 'help' => __( 'Uses these capabilities for access to this post type: edit_{capability}, read_{capability}, and delete_{capability}', 'pods' ), + 'type' => 'pick', + 'default' => 'post', + 'data' => [ + 'post' => 'post', + 'page' => 'page', + 'custom' => __( 'Custom Capability', 'pods' ), + ], + 'pick_show_select_text' => 0, + 'dependency' => true, + ], + 'capability_type_custom' => [ + 'label' => __( 'Custom User Capability', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => pods_v( 'name', $pod ), + 'depends-on' => [ 'capability_type' => 'custom' ], + ], + 'capability_type_extra' => [ + 'label' => __( 'Additional User Capabilities', 'pods' ), + 'help' => __( 'Enables additional capabilities for this Post Type including: delete_{capability}s, delete_private_{capability}s, delete_published_{capability}s, delete_others_{capability}s, edit_private_{capability}s, and edit_published_{capability}s', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + ], + 'has_archive' => [ + 'label' => __( 'Enable Archive Page', 'pods' ), + 'help' => __( 'If enabled, creates an archive page with list of of items in this custom post type. Functions like a category page for posts. Can be controlled with a template in your theme called "archive-{$post-type}.php".', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'has_archive_slug' => [ + 'label' => __( 'Archive Page Slug Override', 'pods' ), + 'help' => __( 'If archive page is enabled, you can override the slug used by WordPress, which defaults to the name of the post type.', 'pods' ), + 'type' => 'slug', + 'slug_fallback' => '-', + 'default' => '', + 'depends-on' => [ 'has_archive' => true ], + ], + 'hierarchical' => [ + 'label' => __( 'Hierarchical', 'pods' ), + 'help' => __( 'Allows for parent/ child relationships between items, just like with Pages. Note: To edit relationships in the post editor, you must enable "Page Attributes" in the "Supports" section below.', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'rewrite' => [ + 'label' => __( 'Rewrite', 'pods' ), + 'help' => __( 'Allows you to use pretty permalinks, if set in WordPress Settings->Permalinks. If not enabled, your links will be in the form of "example.com/?pod_name=post_slug" regardless of your permalink settings.', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'rewrite_custom_slug' => [ + 'label' => __( 'Custom Rewrite Slug', 'pods' ), + 'help' => __( 'Changes the first segment of the URL, which by default is the name of the Pod. For example, if your Pod is called "foo", if this field is left blank, your link will be "example.com/foo/post_slug", but if you were to enter "bar" your link will be "example.com/bar/post_slug".', 'pods' ), + 'type' => 'slug', + 'slug_fallback' => '-', + 'default' => '', + 'depends-on' => [ 'rewrite' => true ], + ], + 'rewrite_with_front' => [ + 'label' => __( 'Rewrite with Front', 'pods' ), + 'help' => __( 'Allows permalinks to be prepended with your front base (example: if your permalink structure is /blog/, then your links will be: Unchecked->/news/, Checked->/blog/news/)', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'depends-on' => [ 'rewrite' => true ], + 'boolean_yes_label' => '', + ], + 'rewrite_feeds' => [ + 'label' => __( 'Rewrite Feeds', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'depends-on' => [ 'rewrite' => true ], + 'boolean_yes_label' => '', + ], + 'rewrite_pages' => [ + 'label' => __( 'Rewrite Pages', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'depends-on' => [ 'rewrite' => true ], + 'boolean_yes_label' => '', + ], + 'query_var' => [ + 'label' => __( 'Query Var', 'pods' ), + 'help' => __( 'The Query Var is used in the URL and underneath the WordPress Rewrite API to tell WordPress what page or post type you are on. For a list of reserved Query Vars, read WordPress Query Vars from the WordPress Codex.', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + ], + 'can_export' => [ + 'label' => __( 'Exportable', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + ], + 'default_status' => [ + 'label' => __( 'Default Status', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'pick_object' => 'post-status', + 'default' => $default_post_status, + 'pick_show_select_text' => 0, + ], + 'post_type_supports' => [ + 'name' => 'post_type_supports', + 'type' => 'boolean_group', + 'label' => __( 'Supports', 'pods' ), + 'boolean_group' => [ + 'supports_title' => [ + 'name' => 'supports_title', + 'label' => __( 'Title', 'pods' ), + 'type' => 'boolean', + ], + 'supports_editor' => [ + 'name' => 'supports_editor', + 'label' => __( 'Editor', 'pods' ), + 'type' => 'boolean', + ], + 'supports_author' => [ + 'name' => 'supports_author', + 'label' => __( 'Author', 'pods' ), + 'type' => 'boolean', + ], + 'supports_thumbnail' => [ + 'name' => 'supports_thumbnail', + 'label' => __( 'Featured Image', 'pods' ), + 'type' => 'boolean', + 'dependency' => true, + ], + 'supports_excerpt' => [ + 'name' => 'supports_excerpt', + 'label' => __( 'Excerpt', 'pods' ), + 'type' => 'boolean', + ], + 'supports_trackbacks' => [ + 'name' => 'supports_trackbacks', + 'label' => __( 'Trackbacks', 'pods' ), + 'type' => 'boolean', + ], + 'supports_custom_fields' => [ + 'name' => 'supports_custom_fields', + 'label' => __( 'Manually Edit Custom Fields (can cause slow performance)', 'pods' ), + 'type' => 'boolean', + ], + 'supports_comments' => [ + 'name' => 'supports_comments', + 'label' => __( 'Comments', 'pods' ), + 'type' => 'boolean', + ], + 'supports_revisions' => [ + 'name' => 'supports_revisions', + 'label' => __( 'Revisions', 'pods' ), + 'type' => 'boolean', + ], + 'supports_page_attributes' => [ + 'name' => 'supports_page_attributes', + 'label' => __( 'Page Attributes', 'pods' ), + 'type' => 'boolean', + ], + 'supports_post_formats' => [ + 'name' => 'supports_post_formats', + 'label' => __( 'Post Formats', 'pods' ), + 'type' => 'boolean', + ], + ], + ], + 'supports_custom' => [ + 'name' => 'supports_custom', + 'type' => 'text', + 'label' => __( 'Advanced Supports', 'pods' ), + 'help' => __( 'Comma-separated list of custom "supports" values to pass to register_post_type.', 'pods' ), + ], + 'revisions_to_keep_limit' => [ + 'name' => 'revisions_to_keep_limit', + 'type' => 'number', + 'default' => '0', + 'label' => __( 'Maximum revisions to keep per post', 'pods' ), + 'description' => __( 'The default "0" will fallback to the normal WordPress default.', 'pods' ), + 'help' => __( 'Enter -1 to keep ALL revisions. Enter any positive number to limit the number of revisions kept to that amount.', 'pods' ), + 'depends-on' => [ 'supports_revisions' => true ], + ], + 'delete_with_user' => [ + 'label' => __( 'Allow posts to be deleted when author is deleted', 'pods' ), + 'help' => __( 'When you go to delete a user who is an author of any posts for this post type, you will be given an option to reassign all of their posts to a different author or to delete their posts. With this option on, it will be included in posts to delete upon choosing to delete all posts.', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => __( 'Include posts from this post type when deleting authors and choosing not to reassign posts to a new author.', 'pods' ), + ], + ]; + + /** + * Allow filtering the list of supported features for the post type + * + * @since 2.8.0 + * + * @param array $supports The list of supported features for the post type. + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options['advanced']['post_type_supports']['boolean_group'] = apply_filters( 'pods_admin_config_pod_fields_post_type_supported_features', $options['advanced']['post_type_supports']['boolean_group'], $options, $pod, $tabs ); + + $related_objects = PodsForm::field_method( 'pick', 'related_objects', true ); + + $available_taxonomies = []; + + if ( ! empty( $related_objects[ __( 'Taxonomies', 'pods' ) ] ) ) { + $available_taxonomies = (array) $related_objects[ __( 'Taxonomies', 'pods' ) ]; + } + + foreach ( $available_taxonomies as $taxonomy => $label ) { + $taxonomy = pods_str_replace( 'taxonomy-', '', $taxonomy, 1 ); + + $field_name = 'built_in_taxonomies_' . $taxonomy; + + $options['connections']['post_type_built_in_taxonomies']['boolean_group'][ $field_name ] = [ + 'name' => $field_name, + 'label' => $label, + 'type' => 'boolean', + ]; + + if ( 'category' === $taxonomy || 'post_tag' === $taxonomy ) { + $field_name = 'archive_show_in_taxonomies_' . $taxonomy; + + $options['connections']['archive_show_in_taxonomies']['boolean_group'][ $field_name ] = [ + 'name' => $field_name, + 'label' => $label, + 'type' => 'boolean', + ]; + } + } + } elseif ( 'taxonomy' === $pod_type ) { + $options['admin-ui'] = [ + 'description' => [ + 'label' => __( 'Taxonomy Description', 'pods' ), + 'help' => __( 'A short descriptive summary of what the taxonomy is.', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'show_ui' => [ + 'label' => __( 'Show Admin UI', 'pods' ), + 'help' => __( 'Whether to generate a default UI for managing this taxonomy.', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'public', $pod, true ), + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'show_in_menu' => [ + 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ), + 'help' => __( 'Whether to show the taxonomy in the admin menu.', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'public', $pod, true ), + 'dependency' => true, + 'depends-on' => [ 'show_ui' => true ], + 'boolean_yes_label' => '', + ], + 'menu_name' => [ + 'label' => __( 'Menu Name', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'show_ui' => true ], + ], + 'menu_location' => [ + 'label' => __( 'Menu Location', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => 'default', + 'depends-on' => [ 'show_ui' => true ], + 'data' => [ + 'default' => __( 'Default - Add to associated Post Type(s) menus', 'pods' ), + 'settings' => __( 'Add a submenu item to Settings menu', 'pods' ), + 'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ), + 'submenu' => __( 'Add a submenu item to another menu', 'pods' ), + 'objects' => __( 'Make a new menu item', 'pods' ), + 'top' => __( 'Make a new menu item below Settings', 'pods' ), + ], + 'pick_show_select_text' => 0, + 'dependency' => true, + ], + 'menu_location_custom' => [ + 'label' => __( 'Custom Menu Location', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'depends-on' => [ 'menu_location' => 'submenu' ], + ], + 'menu_position' => [ + 'label' => __( 'Menu Position', 'pods' ), + 'help' => __( 'This will be the position of the menu item. See WordPress.org Developer Docs for more details about how positioning works.', 'pods' ), + 'type' => 'number', + 'number_decimals' => 2, + 'number_format' => '9999.99', + 'number_format_soft' => 1, + 'default' => 0, + 'depends-on' => [ 'menu_location' => [ 'objects', 'top' ] ], + ], + 'menu_icon' => [ + 'label' => __( 'Menu Icon URL', 'pods' ), + 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the site tag type special magic tags. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a Dashicon. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'menu_location' => [ 'objects', 'top' ] ], + ], + 'show_in_nav_menus' => [ + 'label' => __( 'Show in Navigation Menus', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'public', $pod, true ), + 'boolean_yes_label' => '', + ], + 'show_tagcloud' => [ + 'label' => __( 'Allow in Tag Cloud Widget', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ), + 'boolean_yes_label' => '', + ], + // @todo check https://core.trac.wordpress.org/ticket/36964 + 'show_tagcloud_in_edit' => [ + 'label' => __( 'Allow Tag Cloud on term edit pages', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'show_ui', $pod, pods_v( 'show_tagcloud', $pod, true ) ), + 'boolean_yes_label' => '', + ], + 'show_in_quick_edit' => [ + 'label' => __( 'Allow in quick/bulk edit panel', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ), + 'boolean_yes_label' => '', + ], + ]; + + $options['admin-ui']['show_admin_column'] = [ + 'label' => __( 'Show Taxonomy column on Post Types', 'pods' ), + 'help' => __( 'Whether to add a column for this taxonomy on the associated post types manage screens', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'boolean_yes_label' => '', + ]; + + // Integration for Single Value Taxonomy UI + if ( function_exists( 'tax_single_value_meta_box' ) ) { + $options['admin-ui']['single_value'] = [ + 'label' => __( 'Single Value Taxonomy', 'pods' ), + 'help' => __( 'Use a drop-down for the input instead of the WordPress default', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'boolean_yes_label' => '', + ]; + + $options['admin-ui']['single_value_required'] = [ + 'label' => __( 'Single Value Taxonomy - Required', 'pods' ), + 'help' => __( 'A term will be selected by default in the Post Editor, not optional', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'boolean_yes_label' => '', + ]; + } + + $options['connections'] = [ + 'taxonomy_associated_post_types' => [ + 'name' => 'taxonomy_associated_post_types', + 'label' => __( 'Enable Connections to Post Types', 'pods' ), + 'help' => __( 'You can enable the ability to select posts from these post types on any term for this taxonomy.', 'pods' ), + 'type' => 'boolean_group', + 'boolean_group' => [], + ], + 'register_custom_taxonomy' => [ + 'name' => 'register_custom_taxonomy', + 'label' => __( 'Add new connections', 'pods' ), + 'type' => 'html', + 'html_content' => sprintf( + 'Create a new Custom Taxonomy', + esc_url( admin_url( 'admin.php?page=pods-add-new&create_extend=create&type=taxonomy' ) ) + ), + ], + ]; + + $options['advanced'] = [ + 'public' => [ + 'label' => __( 'Public', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + ], + 'hierarchical' => [ + 'label' => __( 'Hierarchical', 'pods' ), + 'help' => __( 'Hierarchical taxonomies will have a list with checkboxes to select an existing category in the taxonomy admin box on the post edit page (like default post categories). Non-hierarchical taxonomies will just have an empty text field to type-in taxonomy terms to associate with the post (like default post tags).', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'rewrite' => [ + 'label' => __( 'Rewrite', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'rewrite_custom_slug' => [ + 'label' => __( 'Custom Rewrite Slug', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'slug', + 'slug_fallback' => '-', + 'default' => '', + 'depends-on' => [ 'rewrite' => true ], + ], + 'rewrite_with_front' => [ + 'label' => __( 'Rewrite with Front', 'pods' ), + 'help' => __( 'Allows permalinks to be prepended with your front base (example: if your permalink structure is /blog/, then your links will be: Unchecked->/news/, Checked->/blog/news/)', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + 'depends-on' => [ 'rewrite' => true ], + ], + 'rewrite_hierarchical' => [ + 'label' => __( 'Hierarchical Permalinks', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => true, + 'boolean_yes_label' => '', + 'depends-on' => [ 'rewrite' => true ], + ], + 'capability_type' => [ + 'label' => __( 'User Capability', 'pods' ), + 'help' => __( 'Uses WordPress term capabilities by default', 'pods' ), + 'type' => 'pick', + 'default' => 'default', + 'data' => [ + 'default' => 'Default', + 'custom' => __( 'Custom Capability', 'pods' ), + ], + 'pick_show_select_text' => 0, + 'dependency' => true, + ], + 'capability_type_custom' => [ + 'label' => __( 'Custom User Capability', 'pods' ), + 'help' => __( 'Enables additional capabilities for this Taxonomy including: manage_{capability}_terms, edit_{capability}_terms, assign_{capability}_terms, and delete_{capability}_terms', 'pods' ), + 'type' => 'text', + 'default' => pods_v( 'name', $pod ), + 'depends-on' => [ 'capability_type' => 'custom' ], + ], + 'query_var' => [ + 'label' => __( 'Query Var', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'boolean_yes_label' => '', + ], + 'query_var' => [ + 'label' => __( 'Query Var', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'query_var_string' => [ + 'label' => __( 'Custom Query Var Name', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'query_var' => true ], + ], + 'sort' => [ + 'label' => __( 'Remember order saved on Post Types', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'boolean_yes_label' => '', + ], + 'update_count_callback' => [ + 'label' => __( 'Function to call when updating counts', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'default' => '', + ], + 'default_term_name' => [ + 'label' => __( 'Default term name', 'pods' ), + 'type' => 'text', + 'default' => '', + 'dependency' => true, + ], + 'default_term_slug' => [ + 'label' => __( 'Default term slug', 'pods' ), + 'type' => 'text', + 'default' => '', + 'excludes-on' => [ 'default_term_name' => '' ], + ], + 'default_term_description' => [ + 'label' => __( 'Default term description', 'pods' ), + 'type' => 'wysiwyg', + 'default' => '', + 'excludes-on' => [ 'default_term_name' => '' ], + ], + ]; + + $related_objects = PodsForm::field_method( 'pick', 'related_objects', true ); + + $available_post_types = []; + + if ( ! empty( $related_objects[ __( 'Post Types', 'pods' ) ] ) ) { + $available_post_types = (array) $related_objects[ __( 'Post Types', 'pods' ) ]; + } + + foreach ( $available_post_types as $post_type => $label ) { + $post_type = pods_str_replace( 'post_type-', '', $post_type, 1 ); + + $field_name = 'built_in_post_types_' . $post_type; + + $options['connections']['taxonomy_associated_post_types']['boolean_group'][ $field_name ] = [ + 'name' => $field_name, + 'label' => $label, + 'type' => 'boolean', + ]; + } + + $options['connections']['taxonomy_associated_post_types']['boolean_group']['built_in_post_types_attachment'] = [ + 'name' => 'built_in_post_types_attachment', + 'label' => __( 'Media', 'pods' ) . ' (attachment)', + 'type' => 'boolean', + ]; + } elseif ( 'settings' === $pod_type ) { + $options['admin-ui'] = [ + 'ui_style' => [ + 'label' => __( 'Admin UI Style', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => 'settings', + 'data' => [ + 'settings' => __( 'Normal Settings Form', 'pods' ), + 'post_type' => __( 'Post Type UI', 'pods' ), + 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ), + ], + 'dependency' => true, + ], + 'menu_location' => [ + 'label' => __( 'Menu Location', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => 'settings', + 'data' => [ + 'settings' => __( 'Add a submenu item to Settings menu', 'pods' ), + 'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ), + 'submenu' => __( 'Add a submenu item to another menu', 'pods' ), + 'top' => __( 'Make a new menu item below Settings', 'pods' ), + ], + 'dependency' => true, + ], + 'menu_location_custom' => [ + 'label' => __( 'Custom Menu Location', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'depends-on' => [ 'menu_location' => 'submenu' ], + ], + 'menu_position' => [ + 'label' => __( 'Menu Position', 'pods' ), + 'help' => __( 'This will be the position of the menu item. See WordPress.org Developer Docs for more details about how positioning works.', 'pods' ), + 'type' => 'number', + 'number_decimals' => 2, + 'number_format' => '9999.99', + 'number_format_soft' => 1, + 'default' => 0, + 'depends-on' => [ 'menu_location' => 'top' ], + ], + 'menu_icon' => [ + 'label' => __( 'Menu Icon URL', 'pods' ), + 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the site tag type special magic tags. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a Dashicon. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'menu_location' => 'top' ], + ], + ]; + + // @todo fill this in + $options['advanced'] = [ + 'temporary' => 'This type has the fields hardcoded', + // :( + ]; + } elseif ( 'pod' === $pod_type ) { + $actions_enabled = [ + 'add', + 'edit', + 'duplicate', + 'delete', + ]; + + if ( 1 === (int) pods_v( 'ui_export', $pod ) ) { + $actions_enabled = [ + 'add', + 'edit', + 'duplicate', + 'delete', + 'export', + ]; + } + + $options['admin-ui'] = [ + 'ui_style' => [ + 'label' => __( 'Admin UI Style', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => 'settings', + 'data' => [ + 'post_type' => __( 'Normal (Looks like the Post Type UI)', 'pods' ), + 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ), + ], + 'dependency' => true, + ], + 'show_in_menu' => [ + 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'boolean', + 'default' => false, + 'boolean_yes_label' => '', + 'dependency' => true, + ], + 'menu_location_custom' => [ + 'label' => __( 'Parent Menu ID (optional)', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'text', + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'menu_position' => [ + 'label' => __( 'Menu Position', 'pods' ), + 'help' => __( 'This will be the position of the menu item. See WordPress.org Developer Docs for more details about how positioning works.', 'pods' ), + 'type' => 'number', + 'number_decimals' => 2, + 'number_format' => '9999.99', + 'number_format_soft' => 1, + 'default' => 0, + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'menu_icon' => [ + 'label' => __( 'Menu Icon URL', 'pods' ), + 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the site tag type special magic tags. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a Dashicon. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ), + 'type' => 'text', + 'default' => '', + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'ui_icon' => [ + 'label' => __( 'Header Icon', 'pods' ), + 'help' => __( 'This is the icon shown to the left of the heading text at the top of the manage pages for this content type.', 'pods' ), + 'type' => 'file', + 'default' => '', + 'file_edit_title' => 0, + 'depends-on' => [ 'show_in_menu' => true ], + ], + 'ui_actions_enabled' => [ + 'label' => __( 'Actions Available', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => $actions_enabled, + 'data' => [ + 'add' => __( 'Add New', 'pods' ), + 'edit' => __( 'Edit', 'pods' ), + 'duplicate' => __( 'Duplicate', 'pods' ), + 'delete' => __( 'Delete', 'pods' ), + 'reorder' => __( 'Reorder', 'pods' ), + 'export' => __( 'Export', 'pods' ), + ], + 'pick_format_type' => 'multi', + 'dependency' => true, + ], + 'ui_reorder_field' => [ + 'label' => __( 'Reorder Field', 'pods' ), + 'help' => __( 'This is the field that will be reordered on, it should be numeric.', 'pods' ), + 'type' => 'text', + 'default' => 'menu_order', + 'depends-on' => [ 'ui_actions_enabled' => 'reorder' ], + ], + 'ui_fields_manage' => [ + 'label' => __( 'Admin Table Columns', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => [], + 'data' => [], + 'pick_format_type' => 'multi', + ], + 'ui_filters' => [ + 'label' => __( 'Search Filters', 'pods' ), + 'help' => __( 'help', 'pods' ), + 'type' => 'pick', + 'default' => [], + 'data' => [], + 'pick_format_type' => 'multi', + ], + ]; + + if ( ! empty( $pod['fields'] ) ) { + if ( isset( $pod['fields'][ pods_v( 'pod_index', $pod, 'name' ) ] ) ) { + $options['admin-ui']['ui_fields_manage']['default'][] = pods_v( 'pod_index', $pod, 'name' ); + } + + if ( isset( $pod['fields']['modified'] ) ) { + $options['admin-ui']['ui_fields_manage']['default'][] = 'modified'; + } + + foreach ( $pod['fields'] as $field ) { + $type = ''; + + if ( isset( $field_types[ $field['type'] ] ) ) { + $type = ' (' . $field_types[ $field['type'] ]['label'] . ')'; + } + + $options['admin-ui']['ui_fields_manage']['data'][ $field['name'] ] = $field['label'] . $type; + $options['admin-ui']['ui_filters']['data'][ $field['name'] ] = $field['label'] . $type; + } + + $options['admin-ui']['ui_fields_manage']['data']['id'] = 'ID'; + } else { + unset( $options['admin-ui']['ui_fields_manage'] ); + unset( $options['admin-ui']['ui_filters'] ); + }//end if + + $index_fields = [ + 'id' => 'ID', + ]; + + $hierarchical_fields = []; + + foreach ( $pod['fields'] as $field ) { + if ( ! in_array( $field['type'], $tableless_field_types, true ) ) { + $index_fields[ $field['name'] ] = $field['label']; + } + + if ( 'pick' == $field['type'] && 'pod' === pods_v( 'pick_object', $field ) && $pod['name'] === pods_v( 'pick_val', $field ) && 'single' === pods_v( 'pick_format_type', $field ) ) { + $hierarchical_fields[ $field['name'] ] = $field['label']; + } + } + + // Set empty message if none found. + if ( empty( $hierarchical_fields ) ) { + $hierarchical_fields = [ + '' => __( 'No Hierarchical Fields found', 'pods' ), + ]; + } + + $options['advanced'] = [ + 'detail_url' => [ + 'label' => __( 'Detail Page URL', 'pods' ), + 'help' => __( 'This is the path relative to your WordPress site URL so you can call {@detail_url} to automatically link to it. Enter something like "my-pod-page/{@permalink}/" to automatically link to "https://mysite.com/my-pod-page/my-pod-item/".', 'pods' ), + 'type' => 'text', + 'text_placeholder' => 'my-pod-page/{@permalink}/', + ], + 'pod_index' => [ + 'label' => __( 'Title Field', 'pods' ), + 'help' => __( 'If you delete the "name" field, we need to specify the field to use as your primary title field. This field will serve as an index of your content. Most commonly this field represents the name of a person, place, thing, or a summary field.', 'pods' ), + 'default' => 'name', + 'type' => 'pick', + 'data' => $index_fields, + 'pick_format_single' => 'autocomplete', + ], + 'hierarchical' => [ + 'label' => __( 'Hierarchical', 'pods' ), + 'help' => __( 'You can enable automatic hierarchical parent / child handling which shows a special built-in interface for data entry.', 'pods' ), + 'default' => 0, + 'type' => 'boolean', + 'dependency' => true, + 'boolean_yes_label' => '', + ], + 'pod_parent' => [ + 'label' => __( 'Hierarchical Parent Field', 'pods' ), + 'help' => __( 'You can enable automatic hierarchical parent / child handling which shows a special built-in interface for data entry.', 'pods' ), + 'default' => 'parent', + 'type' => 'pick', + 'data' => $hierarchical_fields, + 'depends-on' => [ + 'hierarchical' => true, + ], + 'pick_format_single' => 'autocomplete', + ], + ]; + }//end if + + // Only include kitchen sink if dev mode on and not running Codecept tests. + if ( pods_developer() && ! function_exists( 'codecept_debug' ) ) { + $options['kitchen-sink'] = json_decode( file_get_contents( PODS_DIR . 'tests/codeception/_data/kitchen-sink-config.json' ), true ); + } + + $pod_type = $pod['type']; + $pod_name = $pod['name']; + + /** + * Add admin fields to the Pods editor for a specific Pod. + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( "pods_admin_setup_edit_options_{$pod_type}_{$pod_name}", $options, $pod, $tabs ); + + /** + * Add admin fields to the Pods editor for any Pod of a specific content type. + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( "pods_admin_setup_edit_options_{$pod_type}", $options, $pod, $tabs ); + + /** + * Add admin fields to the Pods editor for all Pods. + * + * @param array $options The Options fields. + * @param \Pods\Whatsit\Pod $pod Current Pods object. + * @param array $tabs List of registered tabs. + */ + $options = apply_filters( 'pods_admin_setup_edit_options', $options, $pod, $tabs ); + + return $options; + } +} diff --git a/src/Pods/Admin/Service_Provider.php b/src/Pods/Admin/Service_Provider.php new file mode 100644 index 0000000000..c534a183d2 --- /dev/null +++ b/src/Pods/Admin/Service_Provider.php @@ -0,0 +1,39 @@ +container->singleton( Pod::class, Pod::class ); + $this->container->singleton( Group::class, Group::class ); + $this->container->singleton( Field::class, Field::class ); + $this->container->singleton( Settings::class, Settings::class ); + + $this->hooks(); + } + + /** + * Hooks all the methods and actions the class needs. + * + * @since 2.8.0 + */ + protected function hooks() { + add_action( 'pods_admin_settings_init', $this->container->callback( Settings::class, 'hook' ) ); + } +} diff --git a/src/Pods/Admin/Settings.php b/src/Pods/Admin/Settings.php new file mode 100644 index 0000000000..78df336348 --- /dev/null +++ b/src/Pods/Admin/Settings.php @@ -0,0 +1,226 @@ +get_settings(); + + return pods_v( $setting_name, $settings, $default ); + } + + /** + * Get the Pods settings. + * + * @since 2.8.0 + * + * @return array The setting values. + */ + public function get_settings() { + $settings = get_option( self::OPTION_NAME, [] ); + + if ( ! $settings ) { + $settings = []; + } + + // Register settings with Wisdom Tracker. + $settings['wisdom_registered_setting'] = 1; + + $defaults = $this->get_setting_fields(); + + $layout_field_types = PodsForm::layout_field_types(); + + // Set up defaults as needed. + foreach ( $defaults as $setting_name => $setting ) { + // Skip layout field types. + if ( isset( $setting['type'] ) && in_array( $setting['type'], $layout_field_types, true ) ) { + continue; + } + + if ( isset( $settings[ $setting_name ] ) || ! isset( $setting['default'] ) ) { + continue; + } + + $settings[ $setting_name ] = $setting['default']; + } + + return $settings; + } + + /** + * Update the value for a Pods setting. + * + * @since 2.8.0 + * + * @param string $setting_name The setting name. + * @param mixed $setting_value The setting value. + */ + public function update_setting( $setting_name, $setting_value ) { + $settings = $this->get_settings(); + + if ( null !== $setting_value ) { + $settings[ $setting_name ] = $setting_value; + } elseif ( isset( $settings[ $setting_name ] ) ) { + unset( $settings[ $setting_name ] ); + } + + $this->update_option( $settings ); + } + + /** + * Update the settings for a Pods. + * + * @since 2.8.0 + * + * @param array $setting_values The list of settings to update, pass null as a value to remove it. + */ + public function update_settings( array $setting_values ) { + $settings = $this->get_settings(); + $settings = array_merge( $settings, $setting_values ); + + foreach ( $settings as $setting_name => $setting_value ) { + if ( null === $setting_value ) { + unset( $settings[ $setting_name ] ); + } + } + + $this->update_option( $settings ); + } + + /** + * Handle saving the Pods settings to the option. + * + * @param array $settings The Pods settings to be saved. + */ + private function update_option( array $settings ) { + /** + * Allow filtering whether Pods settings are set to autoload. + * + * @param string $autoload Whether Pods settings should be saved as autoload, set to 'yes' to autoload (default) and 'no' to not autoload. + */ + $autoload = apply_filters( 'pods_admin_settings_autoload', 'yes' ); + + update_option( self::OPTION_NAME, $settings, $autoload ); + } + + /** + * Get the list of Pods settings fields. + * + * @since 2.8.0 + * + * @return array The list of Pods settings fields. + */ + public function get_setting_fields() { + $session_auto_start = pods_session_auto_start( true ); + $session_auto_start_overridden = null !== $session_auto_start; + + $fields['sessions'] = [ + 'label' => __( 'Sessions', 'pods' ), + 'type' => 'heading', + ]; + + $disabled_text = sprintf( + '%1$s
            %2$s: %3$s', + __( 'This setting is disabled because it is forced through the PODS_SESSION_AUTO_START constant elsewhere.', 'pods' ), + __( 'Current value', 'pods' ), + $session_auto_start ? __( 'Enabled', 'pods' ) : __( 'Disabled', 'pods' ) + ); + + $fields['session_auto_start'] = [ + 'name' => 'session_auto_start', + 'label' => __( 'Secure anonymous public form submissions using PHP sessions (potential performance impacts)', 'pods' ), + 'help' => __( 'Sessions will be used to secure submissions from public forms from logged out visitors to ensure they do not submit fields they are not allowed to access. Auto-detecting sessions will automatically turn this setting on the first anonymous submission so that future submissions will be secured going forward.', 'pods' ), + 'type' => 'pick', + 'default' => '0', + 'readonly' => $session_auto_start_overridden, + 'description' => $session_auto_start_overridden ? $disabled_text : '', + 'pick_format' => 'single', + 'pick_format_single' => 'radio', + 'data' => [ + '0' => __( 'Disable sessions', 'pods' ), + '1' => __( 'Enable sessions', 'pods' ), + 'auto' => __( 'Auto-detect sessions (enable on first anonymous submission)', 'pods' ), + ], + ]; + + $pods_init = pods_init(); + + $is_wisdom_opted_out = ! $pods_init->stats_tracking || ! $pods_init->stats_tracking->get_is_tracking_allowed(); + + $fields['wisdom-opt-in'] = [ + 'label' => __( 'Stats Tracking', 'pods' ), + 'type' => 'heading', + ]; + + // Only register if they are already opted-in. + $fields['wisdom_opt_out'] = [ + 'name' => 'wisdom_opt_out', + 'label' => __( 'Would you like to opt-out of tracking?', 'pods' ), + 'description' => __( 'Thank you for installing our plugin. We\'d like your permission to track its usage on your site. We won\'t record any sensitive data, only information regarding the WordPress environment, your site admin email address, and plugin settings. We will only use this information help us make improvements to the plugin and provide better support when you reach out. Tracking is completely optional.', 'pods' ), + 'type' => 'pick', + 'default' => $is_wisdom_opted_out ? '1' : '', + 'pick_format' => 'single', + 'pick_format_single' => 'radio', + 'data' => [ + '' => __( 'Track usage on my site', 'pods' ), + '1' => __( 'DO NOT track usage on my site', 'pods' ), + ], + ]; + + return $fields; + } + + /** + * Add custom settings fields. + * + * @since 2.8.0 + * + * @param array $fields List of fields to filter. + * + * @return array List of filtered fields. + */ + public function add_settings_fields( $fields ) { + $setting_fields = $this->get_setting_fields(); + + return array_merge( $fields, $setting_fields ); + } + +} diff --git a/src/Pods/Blocks/API.php b/src/Pods/Blocks/API.php new file mode 100644 index 0000000000..6878b3f5c3 --- /dev/null +++ b/src/Pods/Blocks/API.php @@ -0,0 +1,258 @@ +get_blocks(); + $js_blocks = $this->get_js_blocks(); + + // The Pods Blocks JS API. + $pods_blocks_options_file = file_get_contents( PODS_DIR . 'ui/js/blocks/pods-blocks-api.min.asset.json' ); + + $pods_blocks_options = json_decode( $pods_blocks_options_file, true ); + + wp_register_script( 'pods-blocks-api', PODS_URL . 'ui/js/blocks/pods-blocks-api.min.js', $pods_blocks_options['dependencies'], $pods_blocks_options['version'], true ); + + wp_set_script_translations( 'pods-blocks-api', 'pods' ); + + wp_localize_script( 'pods-blocks-api', 'podsBlocksConfig', [ + 'blocks' => $js_blocks , + // No custom collections to register directly with JS right now. + 'collections' => [], + ] ); + + // The 'block_categories' filter has been deprecated in WordPress 5.8+ and replaced by 'block_categories_all'. + if ( pods_version_check( 'wp', '5.8-beta0' ) ) { + add_filter( 'block_categories_all', [ $this, 'register_block_collections' ] ); + } else { + add_filter( 'block_categories', [ $this, 'register_block_collections' ] ); + } + + foreach ( $blocks as $block ) { + $block_name = $block['blockName']; + + unset( $block['blockName'], $block['fields'] ); + + register_block_type( $block_name, $block ); + } + + $registered = true; + } + + /** + * Setup core blocks. + * + * @since 2.8.0 + */ + public function setup_core_blocks() { + static $setup = false; + + if ( $setup ) { + return; + } + + /** + * Allow any integrations to be set up before core blocks and collections are called. + * + * @since 2.8.0 + */ + do_action( 'pods_blocks_api_pre_init' ); + + tribe( 'pods.blocks.collection.pods' ); + tribe( 'pods.blocks.field' ); + tribe( 'pods.blocks.form' ); + tribe( 'pods.blocks.list' ); + tribe( 'pods.blocks.single' ); + tribe( 'pods.blocks.view' ); + + /** + * Allow custom blocks to be registered with Pods. + * + * @since 2.8.0 + */ + do_action( 'pods_blocks_api_init' ); + + $setup = true; + } + + /** + * Get list of registered blocks for the Pods Blocks API. + * + * @since 2.8.0 + * + * @return array List of registered blocks. + */ + public function get_blocks() { + static $blocks = []; + + if ( ! empty( $blocks ) ) { + return $blocks; + } + + $this->setup_core_blocks(); + + $api = pods_api(); + + /** @var Block[] $blocks */ + $blocks = $api->_load_objects( [ + 'object_type' => 'block', + // Disable DB queries for now. + 'bypass_post_type_find' => false, + ] ); + + // Ensure the response is an array. + $blocks = array_values( $blocks ); + + $blocks = array_map( static function ( $block ) { + return $block->get_block_args(); + }, $blocks ); + + return $blocks; + } + + /** + * Get list of registered blocks for the Pods Blocks API and prepare them for JavaScript registerBlockType(). + * + * @since 2.8.0 + * + * @return array List of registered blocks prepared for JavaScript registerBlockType(). + */ + public function get_js_blocks() { + static $js_blocks = []; + + if ( ! empty( $js_blocks ) ) { + return $js_blocks; + } + + $blocks = $this->get_blocks(); + + foreach ( $blocks as $block_key => $block ) { + $js_block = []; + + // Remove render options. + unset( $block['render_callback'], $block['render_custom_callback'], $block['render_template'], $block['render_template_path'] ); + + // Remove assets options. + unset( $block['enqueue_assets'], $block['enqueue_script'], $block['enqueue_style'] ); + + foreach ( $block as $key => $value ) { + // Prepare the keys as camelCase. + $key = pods_js_camelcase_name( $key ); + + // Skip if the value is null. + if ( null === $value ) { + continue; + } + + $js_block[ $key ] = $value; + } + + if ( ! isset( $js_block['usesContext'] ) ) { + $js_block['usesContext'] = []; + } + + $js_blocks[ $block_key ] = $js_block; + } + + return $js_blocks; + } + + /** + * Get list of registered block collections for the Pods Blocks API. + * + * @since 2.8.0 + * + * @return array List of registered block collections. + */ + public function get_block_collections() { + static $collections = []; + + if ( ! empty( $collections ) ) { + return $collections; + } + + $this->setup_core_blocks(); + + $api = pods_api(); + + /** @var Block_Collection[] $block_collections */ + $block_collections = $api->_load_objects( [ + 'object_type' => 'block-collection', + ] ); + + // Ensure the response is an array. + $block_collections = array_values( $block_collections ); + + $block_collections = array_map( static function ( $block_collection ) { + return $block_collection->get_block_collection_args(); + }, $block_collections ); + + return $block_collections; + } + + /** + * Register block collections by adding them to the list of 'categories'. + * + * @since 2.8.0 + * + * @param array $collections List of block 'categories' from WordPress. + * + * @return array List of block 'categories' with custom block collections added. + */ + public function register_block_collections( array $collections ) { + $block_collections = $this->get_block_collections(); + + if ( empty( $block_collections ) ) { + return $collections; + } + + foreach ( $block_collections as $collection ) { + $collections[] = [ + 'slug' => $collection['namespace'], + 'title' => $collection['title'], + 'icon' => $collection['icon'], + ]; + } + + return $collections; + } + + /** + * Remove our legacy Pods widgets from the Legacy Widget block. + * + * @since 2.8.0 + * + * @param array $widgets An array of excluded widget-type IDs. + * + * @return array An array of excluded widget-type IDs. + */ + public function remove_from_legacy_widgets( $widgets ) { + $widgets[] = 'pods_widget_field'; + $widgets[] = 'pods_widget_form'; + $widgets[] = 'pods_widget_list'; + $widgets[] = 'pods_widget_single'; + $widgets[] = 'pods_widget_view'; + + return $widgets; + } +} diff --git a/src/Pods/Blocks/Collections/Base.php b/src/Pods/Blocks/Collections/Base.php new file mode 100644 index 0000000000..44e006ea28 --- /dev/null +++ b/src/Pods/Blocks/Collections/Base.php @@ -0,0 +1,50 @@ +block_collection(); + + if ( empty( $collection ) ) { + return; + } + + $collection['name'] = $this->slug(); + + pods_register_block_collection( $collection ); + } + + /** + * Get the name/slug of this block collection. + * + * @since 2.8.0 + * + * @return string + */ + public function slug() { + return ''; + } + + /** + * Get block collection configuration to register with Pods. + * + * @since 2.8.0 + * + * @return array Block collection configuration. + */ + public function block_collection() { + return []; + } +} diff --git a/src/Pods/Blocks/Collections/Pods.php b/src/Pods/Blocks/Collections/Pods.php new file mode 100644 index 0000000000..f457a5c1c9 --- /dev/null +++ b/src/Pods/Blocks/Collections/Pods.php @@ -0,0 +1,38 @@ + true, + 'label' => __( 'Pods Blocks', 'pods' ), + 'namespace' => $this->slug(), + 'icon' => 'pods', + ]; + } +} diff --git a/src/Pods/Blocks/Service_Provider.php b/src/Pods/Blocks/Service_Provider.php new file mode 100644 index 0000000000..ca0e0c150a --- /dev/null +++ b/src/Pods/Blocks/Service_Provider.php @@ -0,0 +1,48 @@ +container->singleton( 'pods.blocks', API::class ); + $this->container->singleton( 'pods.blocks.collection.pods', Pods::class, [ 'register_with_pods' ] ); + $this->container->singleton( 'pods.blocks.field', Field::class, [ 'register_with_pods' ] ); + $this->container->singleton( 'pods.blocks.form', Form::class, [ 'register_with_pods' ] ); + $this->container->singleton( 'pods.blocks.list', Item_List::class, [ 'register_with_pods' ] ); + $this->container->singleton( 'pods.blocks.single', Item_Single::class, [ 'register_with_pods' ] ); + $this->container->singleton( 'pods.blocks.view', View::class, [ 'register_with_pods' ] ); + + $this->hooks(); + } + + /** + * Hooks all the methods and actions the class needs. + * + * @since 2.8.0 + */ + protected function hooks() { + add_action( 'pods_setup_content_types', tribe_callback( 'pods.blocks', 'register_blocks' ) ); + add_filter( 'widget_types_to_hide_from_legacy_widget_block', tribe_callback( 'pods.blocks', 'remove_from_legacy_widgets' ) ); + } +} diff --git a/src/Pods/Blocks/Types/Base.php b/src/Pods/Blocks/Types/Base.php new file mode 100644 index 0000000000..ca6b66ff09 --- /dev/null +++ b/src/Pods/Blocks/Types/Base.php @@ -0,0 +1,157 @@ +fields(); + + $defaults = []; + + foreach ( $fields as $field ) { + $defaults[ $field['name'] ] = $this->default_attribute( $field ); + } + + return $defaults; + } + + /** + * Get the default attribute for a field. + * + * @since 2.8.0 + * + * @param array $field The field to get the default attribute for. + * + * @return mixed The default attribute for a field. + */ + public function default_attribute( $field ) { + $default_value = isset( $field['default'] ) ? $field['default'] : ''; + + if ( 'pick' === $field['type'] && isset( $field['data'] ) ) { + foreach ( $field['data'] as $key => $value ) { + if ( ! is_array( $value ) ) { + $value = [ + 'label' => $value, + 'value' => $key, + ]; + } + + if ( $default_value === $value['value'] ) { + $default_value = $value; + + break; + } + } + } + + return $default_value; + } + + /** + * Get list of Field configurations to register with Pods for the block. + * + * @since 2.8.0 + * + * @return array List of Field configurations. + */ + public function fields() { + return []; + } + + /** + * Register the block with Pods. + * + * @since 2.8.0 + */ + public function register_with_pods() { + $block = $this->block(); + + if ( empty( $block ) ) { + return; + } + + $block['name'] = $this->slug(); + + $this->assets(); + $this->hook(); + + pods_register_block_type( $block, $this->fields() ); + } + + /** + * Get block configuration to register with Pods. + * + * @since 2.8.0 + * + * @return array Block configuration. + */ + public function block() { + return []; + } + + /* + * {@inheritDoc} + * + * @since 2.8.0 + */ + public function attributes( $params = [] ) { + // Convert any potential array values for pick/boolean. + foreach ( $params as $param => $value ) { + if ( is_array( $value ) ) { + if ( isset( $value['label'], $value['value'] ) ) { + $params[ $param ] = $value['value']; + } elseif ( isset( $value[0]['label'], $value[0]['value'] ) ) { + $params[ $param ] = array_values( wp_list_pluck( $value, 'value' ) ); + } + } + } + + return parent::attributes( $params ); + } + + /** + * Render content for block with placeholder template. + * + * @since 2.8.0 + * + * @param string $heading The heading text. + * @param string $content The content text. + * @param null|string $image The image content or null if not set. + * + * @return string The content to render. + */ + public function render_placeholder( $heading, $content, $image = null ) { + ob_start(); + ?> +
            +
            + +
            +

            +

            +
            +
            + + + +
            + true, + 'label' => __( 'Pods Field Value', 'pods' ), + 'description' => __( 'Display a single Pod item\'s field value (custom fields).', 'pods' ), + 'namespace' => 'pods', + 'category' => 'pods', + 'icon' => 'pods', + 'renderType' => 'php', + 'render_callback' => [ $this, 'render' ], + 'keywords' => [ + 'pods', + 'field', + 'value', + 'custom', + 'meta', + ], + 'uses_context' => [ + 'postType', + 'postId', + ], + 'transforms' => [ + 'from' => [ + [ + 'type' => 'shortcode', + 'tag' => 'pods', + 'attributes' => [ + 'name' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'name', + ], + 'slug' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'slug', + ], + 'field' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'field', + ], + ], + 'isMatchConfig' => [ + [ + 'name' => 'field', + 'required' => true, + ], + ], + ], + ], + ], + ]; + } + + /** + * Get list of Field configurations to register with Pods for the block. + * + * @since 2.8.0 + * + * @return array List of Field configurations. + */ + public function fields() { + $api = pods_api(); + + $all_pods = $api->load_pods( [ 'names' => true ] ); + $all_pods = array_merge( [ + '' => '- ' . __( 'Use Current Pod', 'pods' ) . ' -', + ], $all_pods ); + + return [ + [ + 'name' => 'name', + 'label' => __( 'Pod Name', 'pods' ), + 'type' => 'pick', + 'data' => $all_pods, + 'default' => '', + 'description' => __( 'Choose the pod to reference, or reference the Pod in the current context of this block.', 'pods' ), + ], + [ + 'name' => 'slug', + 'label' => __( 'Slug or ID', 'pods' ), + 'type' => 'text', + 'description' => __( 'Defaults to using the current pod item.', 'pods' ), + ], + [ + 'name' => 'field', + 'label' => __( 'Field Name', 'pods' ), + 'type' => 'text', + 'description' => __( 'This is the field name you want to display.', 'pods' ), + ], + ]; + } + + /** + * Since we are dealing with a Dynamic type of Block we need a PHP method to render it. + * + * @since 2.8.0 + * + * @param array $attributes The block attributes. + * @param string $content The block default content. + * @param WP_Block|null $block The block instance. + * + * @return string The block content to render. + */ + public function render( $attributes = [], $content = '', $block = null ) { + $attributes = $this->attributes( $attributes ); + $attributes = array_map( 'trim', $attributes ); + + if ( empty( $attributes['field'] ) ) { + if ( wp_is_json_request() && did_action( 'rest_api_init' ) ) { + return $this->render_placeholder( + '' . esc_html__( 'Pods Field Value', 'pods' ), + esc_html__( 'Please specify a "Field Name" under "More Settings" to configure this block.', 'pods' ) + ); + } + + return ''; + } + + // Use current if no pod name / slug provided. + if ( empty( $attributes['name'] ) || empty( $attributes['slug'] ) ) { + $attributes['use_current'] = true; + } elseif ( ! isset( $attributes['use_current'] ) ) { + $attributes['use_current'] = false; + } + + if ( $attributes['use_current'] && $block instanceof WP_Block && ! empty( $block->context['postType'] ) ) { + // Detect post type / ID from context. + $attributes['name'] = $block->context['postType']; + + if ( ! empty( $block->context['postId'] ) ) { + $attributes['slug'] = $block->context['postId']; + + unset( $attributes['use_current'] ); + } + } elseif ( + ! empty( $attributes['use_current'] ) + && ! empty( $_GET['post_id'] ) + && wp_is_json_request() + && did_action( 'rest_api_init' ) + ) { + $attributes['slug'] = absint( $_GET['post_id'] ); + + if ( empty( $attributes['name'] ) ) { + $attributes['name'] = get_post_type( $attributes['slug'] ); + } + + unset( $attributes['use_current'] ); + } + + return pods_shortcode( $attributes ); + } +} diff --git a/src/Pods/Blocks/Types/Form.php b/src/Pods/Blocks/Types/Form.php new file mode 100644 index 0000000000..a810ae1cdf --- /dev/null +++ b/src/Pods/Blocks/Types/Form.php @@ -0,0 +1,239 @@ + true, + 'label' => __( 'Pods Form', 'pods' ), + 'description' => __( 'Display a form for creating and editing Pod items.', 'pods' ), + 'namespace' => 'pods', + 'category' => 'pods', + 'icon' => 'pods', + 'renderType' => 'php', + 'render_callback' => [ $this, 'render' ], + 'keywords' => [ + 'pods', + 'form', + 'input', + ], + 'uses_context' => [ + 'postType', + 'postId', + ], + 'transforms' => [ + 'from' => [ + [ + 'type' => 'shortcode', + 'tag' => 'pods-form', + 'attributes' => [ + 'name' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'name', + ], + 'slug' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'slug', + ], + 'fields' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'fields', + ], + 'label' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'label', + ], + 'thank_you' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'thank_you', + ], + 'form_output_type' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'form_output_type', + ], + ], + 'isMatchConfig' => [ + [ + 'name' => 'name', + 'required' => false, + ], + ], + ], + [ + 'type' => 'shortcode', + 'tag' => 'pods', + 'attributes' => [ + 'name' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'name', + ], + 'slug' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'slug', + ], + 'fields' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'fields', + ], + 'label' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'label', + ], + 'thank_you' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'thank_you', + ], + 'form_output_type' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'form_output_type', + ], + ], + 'isMatchConfig' => [ + [ + 'name' => 'form', + 'required' => true, + ], + ], + ], + ], + ], + ]; + } + + /** + * Get list of Field configurations to register with Pods for the block. + * + * @since 2.8.0 + * + * @return array List of Field configurations. + */ + public function fields() { + $api = pods_api(); + + $all_pods = $api->load_pods( [ 'names' => true ] ); + $all_pods = array_merge( [ + '' => '- ' . __( 'Use Current Pod', 'pods' ) . ' -', + ], $all_pods ); + + return [ + [ + 'name' => 'name', + 'label' => __( 'Pod Name', 'pods' ), + 'type' => 'pick', + 'data' => $all_pods, + 'default' => '', + 'description' => __( 'Choose the pod to reference, or reference the Pod in the current context of this block.', 'pods' ), + ], + [ + 'name' => 'slug', + 'label' => __( 'Slug or ID', 'pods' ), + 'type' => 'text', + 'description' => __( 'Use this to enable editing of an item.', 'pods' ), + ], + [ + 'name' => 'fields', + 'label' => __( 'Form Fields', 'pods' ), + 'type' => 'paragraph', + 'description' => __( 'Comma-separated list of the Pod Fields you want to include. Default is to show all.', 'pods' ), + ], + [ + 'name' => 'label', + 'label' => __( 'Submit Button Label', 'pods' ), + 'type' => 'text', + 'description' => __( 'The label to show in the submit button of the form.', 'pods' ), + ], + [ + 'name' => 'thank_you', + 'label' => __( 'Redirect URL', 'pods' ), + 'type' => 'text', + 'description' => __( 'After someone submits the form, they can be redirected anywhere you would like. You can reference the saved item ID by using "X_ID_X" in the URL. The default is to not redirect.', 'pods' ), + ], + [ + 'name' => 'form_output_type', + 'label' => __( 'Output Type', 'pods' ), + 'type' => 'pick', + 'data' => [ + 'div' => 'Div containers (
            )', + 'ul' => 'Unordered list (
              )', + 'p' => 'Paragraph elements (

              )', + 'table' => 'Table rows (

            )', + ], + 'default' => 'div', + 'description' => __( 'Choose how you want your form HTML to be set up. This allows you flexibility to build and style your forms with any CSS customizations you would like. Some output types are naturally laid out better in certain themes.', 'pods' ), + ], + ]; + } + + /** + * Since we are dealing with a Dynamic type of Block we need a PHP method to render it. + * + * @since 2.8.0 + * + * @param array $attributes The block attributes. + * @param string $content The block default content. + * @param WP_Block|null $block The block instance. + * + * @return string The block content to render. + */ + public function render( $attributes = [], $content = '', $block = null ) { + $attributes = $this->attributes( $attributes ); + $attributes = array_map( 'trim', $attributes ); + + // Prevent any previews of this block. + if ( wp_is_json_request() && did_action( 'rest_api_init' ) ) { + return $this->render_placeholder( + esc_html__( 'Form', 'pods' ), + esc_html__( 'No preview is available for this Pods Form, you will see it when you view or preview this on the front of your site.', 'pods' ), + '' . esc_attr__( 'Generic placeholder image depicting a common form layout', 'pods' ) . '' + ); + } + + // Detect post type / ID from context. + if ( empty( $attributes['name'] ) && $block instanceof WP_Block && ! empty( $block->context['postType'] ) ) { + $attributes['name'] = $block->context['postType']; + + if ( isset( $attributes['slug'] ) && '{@post.ID}' === $attributes['slug'] && ! empty( $block->context['postId'] ) ) { + $attributes['slug'] = $block->context['postId']; + } + } + + return pods_shortcode_form( $attributes ); + } +} diff --git a/src/Pods/Blocks/Types/Item_List.php b/src/Pods/Blocks/Types/Item_List.php new file mode 100644 index 0000000000..2734caed4c --- /dev/null +++ b/src/Pods/Blocks/Types/Item_List.php @@ -0,0 +1,420 @@ + true, + 'label' => __( 'Pods Item List', 'pods' ), + 'description' => __( 'List multiple Pod items.', 'pods' ), + 'namespace' => 'pods', + 'category' => 'pods', + 'icon' => 'pods', + 'renderType' => 'php', + 'render_callback' => [ $this, 'render' ], + 'keywords' => [ + 'pods', + 'item', + 'list', + ], + 'uses_context' => [ + 'postType', + ], + 'transforms' => [ + 'from' => [ + [ + 'type' => 'shortcode', + 'tag' => 'pods', + 'attributes' => [ + 'name' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'name', + ], + 'template' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'template', + ], + 'template_custom' => [ + // Pull this from content or the attribute. + 'type' => 'content', + 'source' => 'shortcode', + 'attribute' => 'template_custom', + ], + 'content_before' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'content_before', + ], + 'content_after' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'content_after', + ], + 'not_found' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'not_found', + ], + 'limit' => [ + 'type' => 'integer', + 'source' => 'shortcode', + 'attribute' => 'limit', + ], + 'orderby' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'orderby', + ], + 'where' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'where', + ], + 'pagination' => [ + 'type' => 'boolean', + 'source' => 'shortcode', + 'attribute' => 'pagination', + ], + 'pagination_location' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'pagination_location', + ], + 'pagination_type' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'pagination_type', + ], + 'filters_enable' => [ + 'type' => 'boolean', + 'source' => 'shortcode', + 'attribute' => 'filters_enable', + ], + 'filters' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'filters', + ], + 'filters_label' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'filters_label', + ], + 'filters_location' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'filters_location', + ], + 'cache_mode' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'cache_mode', + ], + 'expires' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'expires', + ], + ], + 'isMatchConfig' => [ + [ + 'name' => 'slug', + 'excluded' => true, + ], + [ + 'name' => 'field', + 'excluded' => true, + ], + [ + 'name' => 'form', + 'excluded' => true, + ], + [ + 'name' => 'view', + 'excluded' => true, + ], + ], + ], + ], + ], + ]; + } + + /** + * Get list of Field configurations to register with Pods for the block. + * + * @since 2.8.0 + * + * @return array List of Field configurations. + */ + public function fields() { + $api = pods_api(); + + $all_pods = $api->load_pods( [ 'names' => true ] ); + $all_pods = array_merge( [ + '' => '- ' . __( 'Use Current Pod', 'pods' ) . ' -', + ], $all_pods ); + + $all_templates = $api->load_templates( [ 'names' => true ] ); + $all_templates = array_merge( [ + '' => '- ' . __( 'Use Custom Template', 'pods' ) . ' -', + ], $all_templates ); + + $cache_modes = [ + [ + 'label' => 'Disable Caching', + 'value' => 'none', + ], + [ + 'label' => 'Object Cache', + 'value' => 'cache', + ], + [ + 'label' => 'Transient', + 'value' => 'transient', + ], + [ + 'label' => 'Site Transient', + 'value' => 'site-transient', + ], + ]; + + /** + * Allow filtering of the default cache mode used for the Pods shortcode. + * + * @since 2.8.0 + * + * @param string $default_cache_mode Default cache mode. + */ + $default_cache_mode = apply_filters( 'pods_shortcode_default_cache_mode', 'none' ); + + return [ + [ + 'name' => 'name', + 'label' => __( 'Pod Name', 'pods' ), + 'type' => 'pick', + 'data' => $all_pods, + 'default' => '', + 'description' => __( 'Choose the pod to reference, or reference the Pod in the current context of this block.', 'pods' ), + ], + [ + 'name' => 'template', + 'label' => __( 'Template', 'pods' ), + 'type' => 'pick', + 'data' => $all_templates, + 'default' => '', + 'description' => __( 'You can choose a previously saved Pods Template here. We recommend saving your Pods Templates with our Templates component so you can enjoy the full editing experience.', 'pods' ), + ], + [ + 'name' => 'template_custom', + 'label' => __( 'Custom Template', 'pods' ), + 'type' => 'paragraph', + 'description' => __( 'You can specify a custom template to use, it accepts HTML and magic tags. Any content here will override whatever Template you may have chosen above.', 'pods' ), + ], + [ + 'name' => 'content_before', + 'label' => __( 'Content Before List', 'pods' ), + 'type' => 'paragraph', + 'description' => __( 'This content will appear before the list of templated items. A useful way to use this option is if you have a template that uses "li" HTML tags, you can use the "ul" HTML tag to start an unordered list. This will only be shown if items were found.', 'pods' ), + ], + [ + 'name' => 'content_after', + 'label' => __( 'Content After List', 'pods' ), + 'type' => 'paragraph', + 'description' => __( 'This content will appear after the list of templated items. A useful way to use this option is if you have a template that uses "li" HTML tags, you can use the "/ul" HTML tag to end an unordered list. This will only be shown if items were found.', 'pods' ), + ], + [ + 'name' => 'not_found', + 'label' => __( 'Not Found Content', 'pods' ), + 'type' => 'paragraph', + 'default' => __( 'No content was found.', 'pods' ), + 'description' => __( 'If there are no items shown, this content will be shown in the block\'s place.', 'pods' ), + ], + [ + 'name' => 'limit', + 'label' => __( 'Limit', 'pods' ), + 'type' => 'number', + 'default' => 15, + 'description' => __( 'Specify the number of items to show but keep in mind that the more items you show the longer it may take for the page to load. You should avoid using "-1" here unless you know what you\'re doing. If your pod has many items, it could stop the page from loading and cause errors. Default number of items to show is to show 15 items. See also: find()', 'pods' ), + ], + [ + 'name' => 'orderby', + 'label' => __( 'Order By', 'pods' ), + 'type' => 'text', + 'description' => __( 'You can specify what field to order by here. That could be t.post_title ASC or you may want to use a custom field like my_field.meta_value ASC. The normal MySQL syntax works here, so you can sort ascending with ASC or descending with DESC. See also: find()', 'pods' ), + ], + [ + 'name' => 'where', + 'label' => __( 'Where', 'pods' ), + 'type' => 'text', + 'description' => __( 'You can specify what field to restrict the item list by here. That could be t.post_title LIKE "%repairs%" or you may want to reference a custom field like my_field.meta_value = "123". For a list of all things available for you to query, follow the find() Notation Options. See also: find()', 'pods' ), + ], + [ + 'name' => 'pagination', + 'label' => __( 'Enable Pagination', 'pods' ), + 'type' => 'boolean', + 'description' => __( 'Whether to show pagination for the list of items. This will only show if there is more than one page of items found.', 'pods' ), + ], + [ + 'name' => 'pagination_location', + 'label' => __( 'Pagination Location', 'pods' ), + 'type' => 'pick', + 'data' => [ + 'before' => __( 'Before list', 'pods' ), + 'after' => __( 'After list', 'pods' ), + 'both' => __( 'Before and After list', 'pods' ), + ], + 'default' => 'after', + 'description' => __( 'The location to show the pagination.', 'pods' ), + ], + [ + 'name' => 'pagination_type', + 'label' => __( 'Pagination Type', 'pods' ), + 'type' => 'pick', + 'data' => [ + 'advanced' => __( 'Basic links', 'pods' ), + 'simple' => __( 'Previous and Next Links only', 'pods' ), + 'list' => __( 'Use an unordered list with paginate_links() native functionality', 'pods' ), + 'paginate' => __( 'Use basic paginate_links() native functionality', 'pods' ), + ], + 'default' => 'advanced', + 'description' => __( 'Choose which kind of pagination to display.', 'pods' ), + ], + [ + 'name' => 'filters_enable', + 'label' => __( 'Enable Filters', 'pods' ), + 'type' => 'boolean', + 'description' => __( 'Whether to show filters for the list of items.', 'pods' ), + ], + [ + 'name' => 'filters', + 'label' => __( 'Filter Fields', 'pods' ), + 'type' => 'text', + 'description' => __( 'Comma-separated list of fields you want to allow filtering by. Default is to just show a text field to search with.', 'pods' ), + ], + [ + 'name' => 'filters_label', + 'label' => __( 'Custom Filters Label', 'pods' ), + 'type' => 'text', + 'description' => __( 'The label to show for the filters. Default is "Search".', 'pods' ), + ], + [ + 'name' => 'filters_location', + 'label' => __( 'Filters Location', 'pods' ), + 'type' => 'pick', + 'data' => [ + 'before' => __( 'Before list', 'pods' ), + 'after' => __( 'After list', 'pods' ), + ], + 'default' => 'before', + 'description' => __( 'The location to show the filters.', 'pods' ), + ], + [ + 'name' => 'cache_mode', + 'label' => __( 'Cache Mode', 'pods' ), + 'type' => 'pick', + 'data' => $cache_modes, + 'default' => $default_cache_mode, + 'description' => __( 'The mode to cache the output with.', 'pods' ), + ], + [ + 'name' => 'expires', + 'label' => __( 'Expires', 'pods' ), + 'type' => 'number', + 'default' => ( MINUTE_IN_SECONDS * 5 ), + 'description' => __( 'Set how long to cache the output for in seconds.', 'pods' ), + ], + ]; + } + + /** + * Since we are dealing with a Dynamic type of Block we need a PHP method to render it. + * + * @since 2.8.0 + * + * @param array $attributes The block attributes. + * @param string $content The block default content. + * @param WP_Block|null $block The block instance. + * + * @return string The block content to render. + */ + public function render( $attributes = [], $content = '', $block = null ) { + $attributes = $this->attributes( $attributes ); + $attributes = array_map( 'trim', $attributes ); + + if ( empty( $attributes['template'] ) && empty( $attributes['template_custom'] ) ) { + if ( wp_is_json_request() && did_action( 'rest_api_init' ) ) { + return $this->render_placeholder( + '' . esc_html__( 'Pods Item List', 'pods' ), + esc_html__( 'Please specify a "Template" or "Custom Template" under "More Settings" to configure this block.', 'pods' ) + ); + } + + return ''; + } + + // Detect post type / ID from context. + if ( empty( $attributes['name'] ) && $block instanceof WP_Block && ! empty( $block->context['postType'] ) ) { + $attributes['name'] = $block->context['postType']; + } + + if ( empty( $attributes['name'] ) ) { + if ( + ! empty( $_GET['post_id'] ) + && wp_is_json_request() + && did_action( 'rest_api_init' ) + ) { + $post_id = absint( $_GET['post_id'] ); + + $attributes['name'] = get_post_type( $post_id ); + } else { + $attributes['name'] = get_post_type(); + } + } + + if ( empty( $attributes['filters'] ) ) { + $attributes['filters'] = false; + } + + $content = pods_shortcode( $attributes, $attributes['template_custom'] ); + + if ( '' !== $content ) { + if ( ! empty( $attributes['content_before'] ) ) { + $content = $attributes['content_before'] . $content; + } + + if ( ! empty( $attributes['content_after'] ) ) { + $content .= $attributes['content_after']; + } + } + + return $content; + } +} diff --git a/src/Pods/Blocks/Types/Item_Single.php b/src/Pods/Blocks/Types/Item_Single.php new file mode 100644 index 0000000000..5a71456ea9 --- /dev/null +++ b/src/Pods/Blocks/Types/Item_Single.php @@ -0,0 +1,268 @@ + true, + 'label' => __( 'Pods Single Item', 'pods' ), + 'description' => __( 'Display a single Pod item.', 'pods' ), + 'namespace' => 'pods', + 'category' => 'pods', + 'icon' => 'pods', + 'renderType' => 'php', + 'render_callback' => [ $this, 'render' ], + 'keywords' => [ + 'pods', + 'single', + 'item', + 'field', + ], + 'uses_context' => [ + 'postType', + 'postId', + ], + 'transforms' => [ + 'from' => [ + [ + 'type' => 'shortcode', + 'tag' => 'pods', + 'attributes' => [ + 'name' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'name', + ], + 'slug' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'slug', + ], + 'template' => [ + 'type' => 'object', + 'source' => 'shortcode', + 'attribute' => 'template', + ], + 'template_custom' => [ + // Pull this from content or the attribute. + 'type' => 'content', + 'source' => 'shortcode', + 'attribute' => 'template_custom', + ], + ], + 'isMatchConfig' => [ + [ + 'name' => 'field', + 'excluded' => true, + ], + [ + 'name' => 'form', + 'excluded' => true, + ], + [ + 'name' => 'view', + 'excluded' => true, + ], + [ + 'name' => 'content_before', + 'excluded' => true, + ], + [ + 'name' => 'content_after', + 'excluded' => true, + ], + [ + 'name' => 'not_found', + 'excluded' => true, + ], + [ + 'name' => 'limit', + 'excluded' => true, + ], + [ + 'name' => 'orderby', + 'excluded' => true, + ], + [ + 'name' => 'where', + 'excluded' => true, + ], + [ + 'name' => 'pagination', + 'excluded' => true, + ], + [ + 'name' => 'pagination_location', + 'excluded' => true, + ], + [ + 'name' => 'pagination_type', + 'excluded' => true, + ], + [ + 'name' => 'filters', + 'excluded' => true, + ], + [ + 'name' => 'filters_label', + 'excluded' => true, + ], + [ + 'name' => 'filters_location', + 'excluded' => true, + ], + [ + 'name' => 'cache_mode', + 'excluded' => true, + ], + [ + 'name' => 'expires', + 'excluded' => true, + ], + ], + ], + ], + ], + ]; + } + + /** + * Get list of Field configurations to register with Pods for the block. + * + * @since 2.8.0 + * + * @return array List of Field configurations. + */ + public function fields() { + $api = pods_api(); + + $all_pods = $api->load_pods( [ 'names' => true ] ); + $all_pods = array_merge( [ + '' => '- ' . __( 'Use Current Pod', 'pods' ) . ' -', + ], $all_pods ); + + $all_templates = $api->load_templates( [ 'names' => true ] ); + $all_templates = array_merge( [ + '' => '- ' . __( 'Use Custom Template', 'pods' ) . ' -', + ], $all_templates ); + + return [ + [ + 'name' => 'name', + 'label' => __( 'Pod Name', 'pods' ), + 'type' => 'pick', + 'data' => $all_pods, + 'default' => '', + 'description' => __( 'Choose the pod to reference, or reference the Pod in the current context of this block.', 'pods' ), + ], + [ + 'name' => 'slug', + 'label' => __( 'Slug or ID', 'pods' ), + 'type' => 'text', + 'description' => __( 'Defaults to using the current pod item.', 'pods' ), + ], + [ + 'name' => 'template', + 'label' => __( 'Template', 'pods' ), + 'type' => 'pick', + 'data' => $all_templates, + 'default' => '', + 'description' => __( 'You can choose a previously saved Pods Template here. We recommend saving your Pods Templates with our Templates component so you can enjoy the full editing experience.', 'pods' ), + ], + [ + 'name' => 'template_custom', + 'label' => __( 'Custom Template', 'pods' ), + 'type' => 'paragraph', + 'description' => __( 'You can specify a custom template to use, it accepts HTML and magic tags. Any content here will override whatever Template you may have chosen above.', 'pods' ), + ], + ]; + } + + /** + * Since we are dealing with a Dynamic type of Block we need a PHP method to render it. + * + * @since 2.8.0 + * + * @param array $attributes The block attributes. + * @param string $content The block default content. + * @param WP_Block|null $block The block instance. + * + * @return string The block content to render. + */ + public function render( $attributes = [], $content = '', $block = null ) { + $attributes = $this->attributes( $attributes ); + $attributes = array_map( 'trim', $attributes ); + + if ( + empty( $attributes['template'] ) + && empty( $attributes['template_custom'] ) + ) { + if ( wp_is_json_request() && did_action( 'rest_api_init' ) ) { + return $this->render_placeholder( + '' . esc_html__( 'Pods Single Item', 'pods' ), + esc_html__( 'Please specify a "Template" or "Custom Template" under "More Settings" to configure this block.', 'pods' ) + ); + } + + return ''; + } + + // Use current if no pod name / slug provided. + if ( empty( $attributes['name'] ) || empty( $attributes['slug'] ) ) { + $attributes['use_current'] = true; + } elseif ( ! isset( $attributes['use_current'] ) ) { + $attributes['use_current'] = false; + } + + if ( $attributes['use_current'] && $block instanceof WP_Block && ! empty( $block->context['postType'] ) ) { + // Detect post type / ID from context. + $attributes['name'] = $block->context['postType']; + + if ( ! empty( $block->context['postId'] ) ) { + $attributes['slug'] = $block->context['postId']; + + unset( $attributes['use_current'] ); + } + } elseif ( + ! empty( $attributes['use_current'] ) + && ! empty( $_GET['post_id'] ) + && wp_is_json_request() + && did_action( 'rest_api_init' ) + ) { + $attributes['slug'] = absint( $_GET['post_id'] ); + + if ( empty( $attributes['name'] ) ) { + $attributes['name'] = get_post_type( $attributes['slug'] ); + } + + unset( $attributes['use_current'] ); + } + + return pods_shortcode( $attributes, $attributes['template_custom'] ); + } +} diff --git a/src/Pods/Blocks/Types/View.php b/src/Pods/Blocks/Types/View.php new file mode 100644 index 0000000000..5dce9ae4b8 --- /dev/null +++ b/src/Pods/Blocks/Types/View.php @@ -0,0 +1,165 @@ + true, + 'label' => __( 'Pods View', 'pods' ), + 'description' => __( 'Include a file from a theme, with caching options', 'pods' ), + 'namespace' => 'pods', + 'category' => 'pods', + 'icon' => 'pods', + 'renderType' => 'php', + 'render_callback' => [ $this, 'render' ], + 'keywords' => [ + 'pods', + 'view', + 'include', + ], + 'transforms' => [ + 'from' => [ + [ + 'type' => 'shortcode', + 'tag' => 'pods', + 'attributes' => [ + 'view' => [ + 'type' => 'string', + 'source' => 'shortcode', + 'attribute' => 'view', + ], + ], + 'isMatchConfig' => [ + [ + 'name' => 'view', + 'required' => true, + ], + ], + ], + ], + ], + ]; + } + + /** + * Get list of Field configurations to register with Pods for the block. + * + * @since 2.8.0 + * + * @return array List of Field configurations. + */ + public function fields() { + $cache_modes = [ + [ + 'label' => 'Disable Caching', + 'value' => 'none', + ], + [ + 'label' => 'Object Cache', + 'value' => 'cache', + ], + [ + 'label' => 'Transient', + 'value' => 'transient', + ], + [ + 'label' => 'Site Transient', + 'value' => 'site-transient', + ], + ]; + + /** + * Allow filtering of the default cache mode used for the Pods shortcode. + * + * @since 2.8.0 + * + * @param string $default_cache_mode Default cache mode. + */ + $default_cache_mode = apply_filters( 'pods_shortcode_default_cache_mode', 'none' ); + + return [ + [ + 'name' => 'view', + 'label' => __( 'File to include from theme', 'pods' ), + 'type' => 'text', + 'description' => __( 'This is the file location relative to your theme or child theme folder. For example: my-text.php or parts/ad-spot.php', 'pods' ), + ], + [ + 'name' => 'cache_mode', + 'label' => __( 'Cache Mode', 'pods' ), + 'type' => 'pick', + 'data' => $cache_modes, + 'default' => $default_cache_mode, + 'description' => __( 'The mode to cache the output with.', 'pods' ), + ], + [ + 'name' => 'expires', + 'label' => __( 'Expires', 'pods' ), + 'type' => 'number', + 'default' => ( MINUTE_IN_SECONDS * 5 ), + 'description' => __( 'Set how long to cache the output for in seconds.', 'pods' ), + ], + ]; + } + + /** + * Since we are dealing with a Dynamic type of Block we need a PHP method to render it + * + * @since 2.8.0 + * + * @param array $attributes + * + * @return string + */ + public function render( $attributes = [] ) { + $attributes = $this->attributes( $attributes ); + $attributes = array_map( 'trim', $attributes ); + + if ( empty( $attributes['view'] ) ) { + if ( wp_is_json_request() && did_action( 'rest_api_init' ) ) { + return $this->render_placeholder( + '' . esc_html__( 'Pods View', 'pods' ), + esc_html__( 'Please specify a "View" under "More Settings" to configure this block.', 'pods' ) + ); + } + + return ''; + } + + // Prevent any previews of this block. + if ( wp_is_json_request() && did_action( 'rest_api_init' ) ) { + return $this->render_placeholder( + esc_html__( 'View', 'pods' ), + esc_html__( 'No preview is available for this Pods View, you will see it when you view or preview this on the front of your site.', 'pods' ), + '' . esc_attr__( 'Generic placeholder image depicting a common view layout', 'pods' ) . '' + ); + } + + return pods_shortcode( $attributes ); + } +} diff --git a/src/Pods/CLI/Commands/Base.php b/src/Pods/CLI/Commands/Base.php new file mode 100644 index 0000000000..c09fc2ee64 --- /dev/null +++ b/src/Pods/CLI/Commands/Base.php @@ -0,0 +1,596 @@ +add_commands(); + } + + /** + * Add commands based on endpoint object. + * + * @since 2.8.0 + */ + public function add_commands() { + // Permissions are relaxed for WP-CLI context. + add_filter( 'pods_is_admin', '__return_true' ); + + if ( method_exists( $this->endpoint_archive, 'get' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'list' ); + + WP_CLI::add_command( $command, [ + $this, + 'list_items', + ], $this->build_command_args( 'list', $this->endpoint_archive ) ); + } + + if ( method_exists( $this->endpoint_archive, 'create' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'add' ); + + WP_CLI::add_command( $command, [ + $this, + 'add', + ], $this->build_command_args( 'add', $this->endpoint_archive ) ); + } + + if ( method_exists( $this->endpoint_single, 'get' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'get' ); + + WP_CLI::add_command( $command, [ + $this, + 'get', + ], $this->build_command_args( 'get', $this->endpoint_single ) ); + } + + if ( method_exists( $this->endpoint_single_slug, 'get' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'get-by-slug' ); + + WP_CLI::add_command( $command, [ + $this, + 'get_by_slug', + ], $this->build_command_args( 'get', $this->endpoint_single_slug ) ); + } + + if ( method_exists( $this->endpoint_single, 'update' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'update' ); + + WP_CLI::add_command( $command, [ + $this, + 'update', + ], $this->build_command_args( 'update', $this->endpoint_single ) ); + } + + if ( method_exists( $this->endpoint_single_slug, 'update' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'update-by-slug' ); + + WP_CLI::add_command( $command, [ + $this, + 'update_by_slug', + ], $this->build_command_args( 'update', $this->endpoint_single_slug ) ); + } + + if ( method_exists( $this->endpoint_single, 'delete' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'delete' ); + + WP_CLI::add_command( $command, [ + $this, + 'delete', + ], $this->build_command_args( 'delete', $this->endpoint_single ) ); + } + + if ( method_exists( $this->endpoint_single_slug, 'delete' ) ) { + $command = sprintf( '%1$s %2$s %3$s', $this->namespace, $this->command, 'delete-by-slug' ); + + WP_CLI::add_command( $command, [ + $this, + 'delete_by_slug', + ], $this->build_command_args( 'delete', $this->endpoint_single_slug ) ); + } + } + + /** + * List items. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function list_items( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'get', $this->endpoint_archive ); + } + + /** + * Add an item. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function add( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'create', $this->endpoint_archive ); + } + + /** + * Get an item by ID. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function get( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'get', $this->endpoint_single ); + } + + /** + * Get an item by slug. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function get_by_slug( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'get', $this->endpoint_single_slug ); + } + + /** + * Update an item by ID. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function update( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'update', $this->endpoint_single ); + } + + /** + * Update an item by slug. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function update_by_slug( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'update', $this->endpoint_single_slug ); + } + + /** + * Delete an item by ID. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function delete( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'delete', $this->endpoint_single ); + } + + /** + * Delete an item by slug. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * + * @throws WP_CLI\ExitException + */ + public function delete_by_slug( array $args, array $assoc_args ) { + return $this->run_endpoint_method( $args, $assoc_args, 'delete', $this->endpoint_single_slug ); + } + + /** + * Run endpoint method using args provided. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * @param string $method Method name. + * @param Base_Endpoint $endpoint Endpoint object. + * + * @throws WP_CLI\ExitException + */ + public function run_endpoint_method( array $args, array $assoc_args, $method, Base_Endpoint $endpoint ) { + if ( ! method_exists( $endpoint, $method ) ) { + return; + } + + $assoc_args = $this->json_or_args( $assoc_args ); + $assoc_args = $this->validate_args( $args, $assoc_args, $method, $endpoint ); + + if ( is_wp_error( $assoc_args ) ) { + return $this->output_error_response( $assoc_args ); + } + + $attributes = [ + 'args' => $assoc_args, + ]; + + $method_mapping = [ + 'list' => 'GET', + 'add' => 'POST', + 'get' => 'GET', + 'update' => 'POST', + 'delete' => 'DELETE', + ]; + + $rest_method = 'GET'; + + if ( isset( $method_mapping[ $method ] ) ) { + $rest_method = $method_mapping[ $method ]; + } + + $permissions_mapping = [ + 'list' => 'can_read', + 'add' => 'can_create', + 'get' => 'can_read', + 'update' => 'can_edit', + 'delete' => 'can_delete', + ]; + + if ( isset( $permissions_mapping[ $method ] ) ) { + $permissions_method = $permissions_mapping[ $method ]; + + if ( method_exists( $endpoint, $permissions_method ) && ! $endpoint->$permissions_method() ) { + \WP_CLI::error( __( 'The current user does not have access to this endpoint.', 'pods' ) ); + } + } + + $route = $endpoint->get_route(); + + // Add numeric args. + if ( ! empty( $args ) ) { + $route = sprintf( $route, ...$args ); + } + + $request = new WP_REST_Request( $rest_method, '/' . rest_get_url_prefix() . $route, $attributes ); + + if ( 'POST' === $rest_method ) { + $request->set_body_params( $assoc_args ); + } else { + $request->set_query_params( $assoc_args ); + } + + $response = $endpoint->$method( $request ); + + if ( is_wp_error( $response ) ) { + return $this->output_error_response( $response ); + } + + if ( null !== $response ) { + if ( is_object( $response ) || is_array( $response ) ) { + $response = wp_json_encode( $response, JSON_PRETTY_PRINT ); + } + + WP_CLI::line( $response ); + } + + WP_CLI::success( __( 'Command successful', 'pods' ) ); + } + + /** + * Get the list of arguments with JSON expanded if provided. + * + * @since 2.8.0 + * + * @param array $assoc_args List of associative arguments. + * + * @return array List of arguments with JSON expanded if provided. + */ + public function json_or_args( array $assoc_args ) { + if ( isset( $assoc_args['json'] ) ) { + $assoc_args = array_merge( $assoc_args, json_decode( $assoc_args['json'], true ) ); + + unset( $assoc_args['json'] ); + } + + return $assoc_args; + } + + /** + * Determine whether the args validated. + * + * @since 2.8.0 + * + * @param array $args List of positional arguments. + * @param array $assoc_args List of associative arguments. + * @param string $method Method name. + * @param Base_Endpoint $endpoint Endpoint object. + * + * @return array|WP_Error The associative args that validated or the WP_Error object with what failed. + */ + public function validate_args( array $args, array $assoc_args, $method, Base_Endpoint $endpoint ) { + $rest_args = $this->get_rest_args( $method, $endpoint ); + + if ( empty( $rest_args ) ) { + return $assoc_args; + } + + foreach ( $rest_args as $param => $arg ) { + // Handle path args. + if ( isset( $arg['in'] ) && 'path' === $arg['in'] ) { + if ( empty( $args ) ) { + if ( empty( $arg['required'] ) ) { + continue; + } + + return new WP_Error( 'cli-missing-positional-argument', sprintf( __( 'Missing positional argument: %s', 'pods' ), $param ) ); + } + + $value = array_shift( $args ); + + $value = $this->validate_arg( $value, $arg, $param ); + + if ( is_wp_error( $value ) ) { + return $value; + } + + $assoc_args[ $param ] = $value; + + continue; + } + + // Handle normal args. + $value = null; + + if ( isset( $assoc_args[ $param ] ) ) { + $value = $assoc_args[ $param ]; + } + + $value = $this->validate_arg( $value, $arg, $param ); + + if ( is_wp_error( $value ) ) { + return $value; + } + + if ( null !== $value ) { + $assoc_args[ $param ] = $value; + } + } + + return $assoc_args; + } + + /** + * Determine whether the arg validates. + * + * @since 2.8.0 + * + * @param mixed $value CLI value provided. + * @param array $arg REST API argument options. + * @param string $param Parameter name. + * + * @return mixed|WP_Error The argument value or the WP_Error object with what failed to validate. + */ + public function validate_arg( $value, array $arg, $param ) { + $is_required = ! empty( $arg['required'] ); + $is_null = null === $value; + + if ( $is_null ) { + if ( ! $is_required ) { + return $value; + } + + return new WP_Error( 'cli-argument-required', sprintf( __( 'Argument is required: %s', 'pods' ), $param ) ); + } + + if ( 'integer' === $arg['type'] ) { + $value = (int) $value; + } + + if ( ! empty( $arg['validate_callback'] ) && is_callable( $arg['validate_callback'] ) ) { + $valid = call_user_func( $arg['validate_callback'], $value ); + + if ( ! $valid ) { + $callable_name = null; + + if ( is_array( $arg['validate_callback'] ) ) { + $callable_name = ''; + + if ( is_object( $arg['validate_callback'][0] ) ) { + $callable_name = get_class( $arg['validate_callback'][0] ) . '::'; + } elseif ( is_string( $arg['validate_callback'][0] ) ) { + $callable_name = $arg['validate_callback'][0] . '::'; + } + + $callable_name .= $arg['validate_callback'][1]; + } elseif ( is_string( $arg['validate_callback'] ) ) { + $callable_name = $arg['validate_callback']; + } + + if ( empty( $callable_name ) ) { + return new WP_Error( 'cli-argument-not-valid', sprintf( __( 'Argument not provided as expected: %s', 'pods' ), $param ) ); + } + + return new WP_Error( 'cli-argument-not-valid-with-callback', sprintf( __( 'Argument not provided as expected (%1$s): %2$s', 'pods' ), $callable_name, $param ) ); + } + + if ( is_wp_error( $valid ) ) { + return $valid; + } + } + + $valid = rest_validate_value_from_schema( $value, $arg, $param ); + + if ( ! $valid ) { + return ''; + } + + if ( is_wp_error( $valid ) ) { + return $valid; + } + + return $value; + } + + /** + * Get list of REST API arguments from endpoint. + * + * @since 2.8.0 + * + * @param string $command Command name. + * @param Base_Endpoint $endpoint Endpoint object. + * + * @return array List of REST API arguments. + */ + public function get_rest_args( $command, Base_Endpoint $endpoint ) { + $command_mapping = [ + 'list' => 'READ_args', + 'add' => 'CREATE_args', + 'create' => 'CREATE_args', + 'get' => 'READ_args', + 'update' => 'EDIT_args', + 'delete' => 'DELETE_args', + ]; + + if ( ! isset( $command_mapping[ $command ] ) ) { + return []; + } + + $method = $command_mapping[ $command ]; + + if ( ! method_exists( $endpoint, $method ) ) { + return []; + } + + $rest_args = $endpoint->$method(); + + if ( empty( $rest_args ) ) { + return []; + } + + return $rest_args; + } + + /** + * Get list of properly formatted CLI command arguments. + * + * @since 2.8.0 + * + * @param string $command Command name. + * @param Base_Endpoint $endpoint Endpoint object. + * + * @return array List of properly formatted CLI command arguments. + */ + public function build_command_args( $command, Base_Endpoint $endpoint ) { + $rest_args = $this->get_rest_args( $command, $endpoint ); + + if ( empty( $rest_args ) ) { + return []; + } + + $cli_args = [ + 'synopsis' => [], + ]; + + foreach ( $rest_args as $param => $arg ) { + $cli_arg = [ + 'type' => 'assoc', + 'name' => $param, + 'optional' => empty( $arg['required'] ), + ]; + + if ( ! empty( $arg['description'] ) ) { + $cli_arg['description'] = $arg['description']; + } + + if ( ! empty( $arg['default'] ) ) { + $cli_arg['default'] = $arg['default']; + } + + if ( isset( $arg['in'] ) && 'path' === $arg['in'] ) { + // Handle path args. + $cli_arg['type'] = 'positional'; + } elseif ( isset( $arg['cli_boolean'] ) && $arg['cli_boolean'] ) { + // Handle flag args. + $cli_arg['type'] = 'flag'; + } elseif ( ! empty( $arg['enum'] ) ) { + // Handle enum options. + $cli_arg['options'] = $arg['enum']; + } + + $cli_args['synopsis'][] = $cli_arg; + } + + return $cli_args; + } + + /** + * Output the CLI error response from the WP_Error object. + * + * @since 2.8.0 + * + * @param WP_Error $error The error object. + * + * @throws WP_CLI\ExitException + */ + public function output_error_response( WP_Error $error ) { + $error_message = sprintf( '%1$s [%2$s]', $error->get_error_message(), $error->get_error_code() ); + + WP_CLI::error( $error_message ); + } +} diff --git a/src/Pods/CLI/Commands/Field.php b/src/Pods/CLI/Commands/Field.php new file mode 100644 index 0000000000..8dba178935 --- /dev/null +++ b/src/Pods/CLI/Commands/Field.php @@ -0,0 +1,27 @@ +endpoint_archive = tribe( 'pods.rest-v1.endpoints.fields' ); + $this->endpoint_single = tribe( 'pods.rest-v1.endpoints.field' ); + $this->endpoint_single_slug = tribe( 'pods.rest-v1.endpoints.field-slug' ); + } +} diff --git a/src/Pods/CLI/Commands/Group.php b/src/Pods/CLI/Commands/Group.php new file mode 100644 index 0000000000..639da4ca7f --- /dev/null +++ b/src/Pods/CLI/Commands/Group.php @@ -0,0 +1,27 @@ +endpoint_archive = tribe( 'pods.rest-v1.endpoints.groups' ); + $this->endpoint_single = tribe( 'pods.rest-v1.endpoints.group' ); + $this->endpoint_single_slug = tribe( 'pods.rest-v1.endpoints.group-slug' ); + } +} diff --git a/src/Pods/CLI/Commands/Pod.php b/src/Pods/CLI/Commands/Pod.php new file mode 100644 index 0000000000..60ffdc5d2f --- /dev/null +++ b/src/Pods/CLI/Commands/Pod.php @@ -0,0 +1,27 @@ +endpoint_archive = tribe( 'pods.rest-v1.endpoints.pods' ); + $this->endpoint_single = tribe( 'pods.rest-v1.endpoints.pod' ); + $this->endpoint_single_slug = tribe( 'pods.rest-v1.endpoints.pod-slug' ); + } +} diff --git a/src/Pods/CLI/Service_Provider.php b/src/Pods/CLI/Service_Provider.php new file mode 100644 index 0000000000..c53e9b0818 --- /dev/null +++ b/src/Pods/CLI/Service_Provider.php @@ -0,0 +1,46 @@ +container->singleton( 'pods.cli.commands.pods.pod', Pod::class, [ 'hook' ] ); + $this->container->singleton( 'pods.cli.commands.pods.group', Group::class, [ 'hook' ] ); + $this->container->singleton( 'pods.cli.commands.pods.field', Field::class, [ 'hook' ] ); + + $this->hooks(); + } + + /** + * Hooks all the methods and actions the class needs. + * + * @since 2.8.0 + */ + protected function hooks() { + tribe( 'pods.cli.commands.pods.pod' ); + tribe( 'pods.cli.commands.pods.group' ); + tribe( 'pods.cli.commands.pods.field' ); + } +} diff --git a/src/Pods/Data/Map_Field_Values.php b/src/Pods/Data/Map_Field_Values.php new file mode 100644 index 0000000000..d29ef8106b --- /dev/null +++ b/src/Pods/Data/Map_Field_Values.php @@ -0,0 +1,543 @@ +$method( $field, $traverse, $field_data, $obj ); + } + + // If no value was found, set $method to false. + if ( null === $value ) { + $method = false; + } + + /** + * Allow filtering the field mapping. + * + * @since 2.8.0 + * + * @param null|mixed $value The matching field value or null if there was no match. + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * @param string|false $method The matching mapping method or false if there was no match. + */ + return apply_filters( 'pods_data_map_field_values_map_value', $value, $field, $traverse, $field_data, $obj, $method ); + } + + /** + * Handle custom field mapping. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching field value or null if there was no match. + */ + public function custom( $field, $traverse, $field_data, $obj ) { + /** + * Allow filtering for a custom field mapping. + * + * @since 2.8.0 + * + * @param null|mixed $value The matching field value or null if there was no match. + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + */ + return apply_filters( 'pods_data_map_field_values_custom', null, $field, $traverse, $field_data, $obj ); + } + + /** + * Map the matching pod info value. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching pod info value or null if there was no match. + */ + public function pod_info( $field, $traverse, $field_data, $obj ) { + // Skip if the field exists. + if ( $field_data ) { + return null; + } + + // Skip if not the field we are looking for. + if ( '_pod' !== $field ) { + return null; + } + + $pod_option = ! empty( $traverse[0] ) ? $traverse[0] : 'name'; + + return $obj->pod_data->get_arg( $pod_option ); + } + + /** + * Map the matching field info value. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching field info value or null if there was no match. + */ + public function field_info( $field, $traverse, $field_data, $obj ) { + // Skip if the field exists. + if ( $field_data ) { + return null; + } + + // Skip if not the field we are looking for. + if ( '_field' !== $field ) { + return null; + } + + // Skip if no field was set. + if ( empty( $traverse[0] ) ) { + return null; + } + + $field_match = $traverse[0]; + $field_option = ! empty( $traverse[1] ) ? $traverse[1] : 'label'; + + return $obj->fields( $field_match, $field_option ); + } + + /** + * Map the matching context info value. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching context info value or null if there was no match. + */ + public function context_info( $field, $traverse, $field_data, $obj ) { + // Skip if the field exists. + if ( $field_data ) { + return null; + } + + // Skip if not the field we are looking for. + if ( '_context' !== $field ) { + return null; + } + + // Skip if no field was set. + if ( empty( $traverse[0] ) ) { + return null; + } + + $context_type = $traverse[0]; + + $supported_contexts = [ + 'get', + 'post', + 'request', + 'query', + 'url', + 'uri', + 'url-relative', + 'template-url', + 'stylesheet-url', + 'site-url', + 'home-url', + 'admin-url', + 'includes-url', + 'content-url', + 'plugins-url', + 'network-site-url', + 'network-home-url', + 'network-admin-url', + 'user-admin-url', + 'prefix', + 'session', + 'cookie', + 'user', + 'option', + 'site-option', + 'date', + 'pods', + 'pods_display', + 'post_id', + ]; + + if ( ! in_array( $context_type, $supported_contexts, true ) ) { + return null; + } + + $context_var = isset( $traverse[1] ) ? $traverse[1] : null; + + $raw = isset( $traverse[2] ) && 'raw' === $traverse[2]; + + if ( 'user' === $context_type && 'user_pass' === $context_var ) { + return null; + } + + $value = pods_v( $context_var, $context_type ); + + // Maybe return the raw value. + if ( $raw ) { + return $value; + } + + // Sanitize the field with some basic protections. + return sanitize_text_field( $value ); + } + + /** + * Map the matching calculation value. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching calculation value or null if there was no match. + */ + public function calculation( $field, $traverse, $field_data, $obj ) { + // Skip if the field exists. + if ( $field_data ) { + return null; + } + + $supported_calculations = [ + '_zebra', + '_position', + '_total', + '_total_found', + '_total_pages', + ]; + + // Skip if not the field we are looking for. + if ( ! in_array( $field, $supported_calculations, true ) ) { + return null; + } + + $value = null; + + switch ( $field ) { + case '_zebra': + $value = (int) $obj->zebra(); + + break; + case '_position': + $value = $obj->position(); + + break; + case '_total': + $value = $obj->total(); + + break; + case '_total_found': + $value = $obj->total_found(); + + break; + case '_total_pages': + $value = $obj->total_pages(); + + break; + } + + return $value; + } + + /** + * Map the matching image field value. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching image field value or null if there was no match. + */ + public function image_fields( $field, $traverse, $field_data, $obj ) { + // Skip if the field exists. + if ( $field_data ) { + return null; + } + + // Default image field handlers. + $image_fields = [ + 'image_attachment', + 'image_attachment_url', + 'image_attachment_src', + ]; + + $object_type = $obj->pod_data->get_type(); + + if ( 'post_type' === $object_type ) { + $image_fields[] = 'post_thumbnail'; + $image_fields[] = 'post_thumbnail_url'; + $image_fields[] = 'post_thumbnail_src'; + } elseif ( 'media' === $obj->pod_data->get_type() ) { + $image_fields[] = '_img'; + $image_fields[] = '_url'; + $image_fields[] = '_src'; + } + + // Handle special field tags. + if ( ! in_array( $field, $image_fields, true ) ) { + return null; + } + + $item_id = $obj->id(); + + // Copy for further modification. + $image_field = $field; + $traverse_params = $traverse; + + // Is it a URL request? + if ( '_url' === $image_field || '_src' === $image_field ) { + // This is a _url or _src field itself. + $url = true; + } else { + $url = '_url' === substr( $image_field, - 4 ) || '_src' === substr( $image_field, - 4 ); + + if ( $url ) { + // This is a image_field._url or a image_field._src field. + $image_field = substr( $image_field, 0, - 4 ); + } + } + + $attachment_id = 0; + + switch ( $image_field ) { + // Media pods. + case '_img': + case '_url': + case '_src': + $attachment_id = $item_id; + + break; + + // All other pods. + case 'post_thumbnail': + $attachment_id = get_post_thumbnail_id( $item_id ); + + break; + case 'image_attachment': + if ( isset( $traverse_params[0] ) ) { + $attachment_id = $traverse_params[0]; + + array_shift( $traverse_params ); + } + break; + } + + if ( ! $attachment_id ) { + return null; + } + + $is_image = wp_attachment_is_image( $attachment_id ); + + $size = 'thumbnail'; + + if ( isset( $traverse_params[0] ) ) { + $size = $traverse_params[0]; + + array_shift( $traverse_params ); + + if ( pods_is_image_size( $size ) ) { + // Force image request since a valid size parameter is passed. + $is_image = true; + } else { + // No valid image size found. + $size = false; + } + } + + if ( $url ) { + if ( $is_image ) { + return pods_image_url( $attachment_id, $size, 0, true ); + } + + return wp_get_attachment_url( $attachment_id ); + } + + if ( $size ) { + // Pods will auto-get the thumbnail ID if this isn't an attachment. + return pods_image( $attachment_id, $size, 0, null, true ); + } + + if ( 'media' !== $object_type ) { + // Fallback to attachment Post object to look for other image properties. + $media = pods( 'media', $attachment_id, false ); + + if ( $media && $media->valid() && $media->exists() ) { + return $media->field( implode( '.', $traverse_params ) ); + } + + // Fallback to default attachment object. + $attachment = get_post( $attachment_id ); + } else { + $attachment = $obj->row(); + } + + $value = pods_v( implode( '.', $traverse_params ), $attachment ); + + if ( null !== $value ) { + return $value; + } + + // Start traversal though object property or metadata. + $name_key = array_shift( $traverse_params ); + $value = pods_v( $name_key, $attachment ); + + if ( null !== $value ) { + return $value; + } + + $value = get_post_meta( $attachment_id, $name_key, true ); + + return pods_traverse( $traverse_params, $value ); + } + + /** + * Map the matching avatar field value. + * + * @since 2.8.0 + * + * @param string $field The first field name in the path. + * @param string[] $traverse The list of fields in the path excluding the first field name. + * @param null|Field|Object_Field $field_data The field data or null if not a field. + * @param Pods $obj The Pods object. + * + * @return null|mixed The matching avatar field value or null if there was no match. + */ + public function avatar( $field, $traverse, $field_data, $obj ) { + // Skip if not the field we are looking for. + if ( 'avatar' !== $field ) { + return null; + } + + global $wpdb; + + // Skip if not on the supported pod type. + if ( 'user' !== $obj->pod_data->get_type() && $wpdb->users !== $obj->pod_data->get_table_name() ) { + return null; + } + + $size = 0; + $item_id = $obj->id(); + + // Copy for further modification. + $image_field = $field; + $traverse_params = $traverse; + + $url = '_url' === substr( $image_field, - 4 ) || '_src' === substr( $image_field, - 4 ); + + if ( isset( $traverse_params[0] ) ) { + // Check if there is a numeric size, bail if not because it needs normal relationship traversal. + if ( $field_data && ! is_numeric( $traverse_params[0] ) ) { + return null; + } + + $size = absint( $traverse_params[0] ); + } + + if ( $url ) { + if ( 0 < $size ) { + $avatar_url = get_avatar_url( $item_id, $size ); + } else { + $avatar_url = get_avatar_url( $item_id ); + } + + if ( ! $avatar_url ) { + return ''; + } + } + + if ( 0 < $size ) { + $avatar = get_avatar( $item_id, $size ); + } else { + $avatar = get_avatar( $item_id ); + } + + if ( ! $avatar ) { + return ''; + } + + return $avatar; + } + +} diff --git a/src/Pods/Integration.php b/src/Pods/Integration.php new file mode 100644 index 0000000000..83eb9d857c --- /dev/null +++ b/src/Pods/Integration.php @@ -0,0 +1,82 @@ + [ + // 'name' => [ 'callback', 10, 2 ], + ], + 'filter' => [ + // 'name' => [ 'callback', 10, 2 ], + ], + ]; + + /** + * Whether the integration is active. + * + * @since 2.8.0 + * + * @return bool + */ + public static function is_active() { + return false; + } + + /** + * Add the class hooks. + * + * @since 2.8.0 + */ + public function hook() { + foreach ( $this->hooks as $type => $hooks ) { + foreach ( $hooks as $hook => $params ) { + if ( is_string( $params[0] ) && is_callable( [ $this, $params[0] ] ) ) { + $params[0] = [ $this, $params[0] ]; + } + array_unshift( $params, $hook ); + call_user_func_array( 'add_' . $type, $params ); + } + } + } + + /** + * Remove the class hooks. + * + * @since 2.8.0 + */ + public function unhook() { + foreach ( $this->hooks as $type => $hooks ) { + foreach ( $hooks as $hook => $params ) { + if ( is_string( $params[0] ) && is_callable( $this, $params[0] ) ) { + $params[0] = [ $this, $params[0] ]; + } + array_unshift( $params, $hook ); + call_user_func_array( 'remove_' . $type, $params ); + } + } + } + +} diff --git a/src/Pods/Integrations/Genesis.php b/src/Pods/Integrations/Genesis.php new file mode 100644 index 0000000000..4e32076b50 --- /dev/null +++ b/src/Pods/Integrations/Genesis.php @@ -0,0 +1,46 @@ + 'supports_genesis_seo', + 'label' => __( 'Genesis: SEO', 'pods' ), + 'type' => 'boolean', + ]; + + $supports['supports_genesis_layouts'] = [ + 'name' => 'supports_genesis_layouts', + 'label' => __( 'Genesis: Layouts', 'pods' ), + 'type' => 'boolean', + ]; + + $supports['supports_genesis_simple_sidebars'] = [ + 'name' => 'supports_genesis_simple_sidebars', + 'label' => __( 'Genesis: Simple Sidebars', 'pods' ), + 'type' => 'boolean', + ]; + + return $supports; + } +} diff --git a/src/Pods/Integrations/Jetpack.php b/src/Pods/Integrations/Jetpack.php new file mode 100644 index 0000000000..2f56ce108d --- /dev/null +++ b/src/Pods/Integrations/Jetpack.php @@ -0,0 +1,40 @@ + 'supports_jetpack_publicize', + 'label' => __( 'Jetpack Publicize Support', 'pods' ), + 'type' => 'boolean', + ]; + + $supports['supports_jetpack_markdown'] = [ + 'name' => 'supports_jetpack_markdown', + 'label' => __( 'Jetpack Markdown Support', 'pods' ), + 'type' => 'boolean', + ]; + + return $supports; + } +} diff --git a/src/Pods/Integrations/Polylang.php b/src/Pods/Integrations/Polylang.php new file mode 100644 index 0000000000..f0cf21bf9b --- /dev/null +++ b/src/Pods/Integrations/Polylang.php @@ -0,0 +1,407 @@ + [ + 'pods_meta_init' => [ 'pods_meta_init' ], + ], + 'filter' => [ + 'pods_get_current_language' => [ 'pods_get_current_language', 10, 2 ], + 'pods_api_get_table_info' => [ 'pods_api_get_table_info', 10, 7 ], + 'pods_data_traverse_recurse_ignore_aliases' => [ 'pods_data_traverse_recurse_ignore_aliases', 10 ], + 'pll_get_post_types' => [ 'pll_get_post_types', 10, 2 ], + 'pods_component_i18n_admin_data' => [ 'pods_component_i18n_admin_data' ], + 'pods_component_i18n_admin_ui_fields' => [ 'pods_component_i18n_admin_ui_fields', 10, 2 ], + ], + ]; + + /** + * @inheritDoc + */ + public static function is_active() { + return function_exists( 'PLL' ) || ! empty( $GLOBALS['polylang'] ); + } + + /** + * Add Pods templates to possible i18n enabled post-types (polylang settings). + * + * @since 2.7.0 + * @since 2.8.0 Moved from PodsI18n class. + * + * @param array $post_types + * @param bool $is_settings + * + * @return array mixed + */ + public function pll_get_post_types( $post_types, $is_settings = false ) { + + if ( $is_settings ) { + $post_types['_pods_template'] = '_pods_template'; + } + + return $post_types; + } + + /** + * @param \PodsMeta $pods_meta + * + * @since 2.8.0 + */ + public function pods_meta_init( $pods_meta ) { + + if ( function_exists( 'pll_current_language' ) ) { + add_action( 'init', array( $pods_meta, 'cache_pods' ), 101, 0 ); + } + } + + /** + * @since 2.8.0 + * + * @param array $ignore_aliases + * + * @return array + */ + public function pods_data_traverse_recurse_ignore_aliases( $ignore_aliases ) { + + $ignore_aliases[] = 'polylang_languages'; + + return $ignore_aliases; + } + + /** + * Get the current language. + * + * @since 2.8.0 + * + * @param string $current_language + * @param array $context + * + * @return string + */ + public function pods_get_current_language( $current_language, $context ) { + + if ( ! is_admin() ) { + // Get the global current language (if set). + return pll_current_language( 'slug' ); + } + + $defaults = [ + 'is_admin' => is_admin(), + 'is_ajax' => null, + 'is_pods_ajax' => null, + 'current_page' => '', + 'current_object_type' => '', + 'current_item_id' => '', + 'current_item_type' => '', + ]; + + $context = wp_parse_args( $context, $defaults ); + + $object_type = $context['current_object_type']; + $item_id = $context['current_item_id']; + $item_type = $context['current_item_type']; + + /** + * Get the current user's preferred language. + * This is a user meta setting that will overwrite the language returned from pll_current_language(). + * + * @see \PLL_Admin_Base::init_user() (polylang/admin/admin-base.php) + */ + $current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true ); + + if ( ! $item_type ) { + return $current_language; + } + + /** + * In polylang the preferred language could be anything. + */ + switch ( $object_type ) { + case 'post': + if ( $this->is_translated_post_type( $item_type ) ) { + + /** + * Polylang (1.5.4+). + * We only want the related objects if they are not translatable OR the same language as the current object. + */ + if ( $item_id && function_exists( 'pll_get_post_language' ) ) { + // Overwrite the current language if this is a translatable post_type. + $current_language = pll_get_post_language( $item_id ); + } + + /** + * Polylang (1.0.1+). + * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language. + */ + $current_language = pods_v( 'new_lang', 'request', $current_language ); + } + break; + + case 'term': + if ( $this->is_translated_taxonomy( $item_type ) ) { + + /** + * Polylang (1.5.4+). + * We only want the related objects if they are not translatable OR the same language as the current object. + */ + if ( $item_id && function_exists( 'pll_get_term_language' ) ) { + // Overwrite the current language if this is a translatable taxonomy + $current_language = pll_get_term_language( $item_id ); + } + + /** + * Polylang (1.0.1+). + * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language. + */ + $current_language = pods_v( 'new_lang', 'request', $current_language ); + } + break; + } + + return $current_language; + } + + /** + * Filter table info data. + * + * @since 2.8.0 + * + * @param array $info + * @param string $object_type + * @param string $object + * @param string $name + * @param array|\Pods $pod + * @param array $field + * @param \PodsAPI $pods_api + * + * @return array + */ + public function pods_api_get_table_info( $info, $object_type, $object, $name, $pod, $field, $pods_api ) { + global $wpdb; + $object_name = pods_sanitize( ( empty( $object ) ? $name : $object ) ); + + // Get current language data + $lang_data = $this->get_language_data(); + + $current_language_tt_id = 0; + $current_language_tl_tt_id = 0; + + if ( $lang_data ) { + if ( ! empty( $lang_data['tt_id'] ) ) { + $current_language_tt_id = $lang_data['tt_id']; + } + if ( ! empty( $lang_data['tl_tt_id'] ) ) { + $current_language_tl_tt_id = $lang_data['tl_tt_id']; + } + } + + switch ( $object_type ) { + + case 'post': + case 'post_type': + case 'media': + if ( $this->is_translated_post_type( $object_name ) ) { + $info['join']['polylang_languages'] = " + LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages` + ON `polylang_languages`.`object_id` = `t`.`ID` + AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id} + "; + + $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL"; + } + break; + + case 'taxonomy': + case 'term': + case 'nav_menu': + case 'post_format': + if ( $this->is_translated_taxonomy( $object_name ) ) { + $info['join']['polylang_languages'] = " + LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages` + ON `polylang_languages`.`object_id` = `t`.`term_id` + AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id} + "; + + $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL"; + } + break; + } + + return $info; + } + + /** + * @param array $data + * + * @return array + */ + public function pods_component_i18n_admin_data( $data ) { + + foreach ( $data as $lang => $field_data ) { + if ( in_array( $lang, $this->get_locales(), true ) ) { + $data[ $lang ]['polylang'] = true; + } else { + $data[ $lang ]['polylang'] = false; + } + } + + return $data; + } + + /** + * @param array $fields + * @param array $data + * + * @return array + */ + public function pods_component_i18n_admin_ui_fields( $fields, $data ) { + + $fields['manage']['polylang'] = array( + 'label' => __( 'Polylang', 'pods' ), + 'type' => 'boolean', + ); + + return $fields; + } + + /** + * Helper method for backwards compatibility. + * + * @since 2.8.0 + * + * @param string $object_name + * + * @return false|mixed|void + */ + public function is_translated_post_type( $object_name ) { + if ( function_exists( 'pll_is_translated_post_type' ) ) { + return pll_is_translated_post_type( $object_name ); + } + return false; + } + + /** + * Helper method for backwards compatibility. + * + * @since 2.8.0 + * + * @param string $object_name + * + * @return false|mixed|void + */ + public function is_translated_taxonomy( $object_name ) { + if ( function_exists( 'pll_is_translated_taxonomy' ) ) { + return pll_is_translated_taxonomy( $object_name ); + } + return false; + } + + /** + * Get the language taxonomy object for the current language. + * + * @since 2.8.0 + * + * @param string $locale + * + * @return array + */ + public function get_language_data( $locale = null ) { + static $lang_data = []; + + if ( ! $locale ) { + $locale = pods_i18n()->get_current_language(); + } + + if ( isset( $lang_data[ $locale ] ) ) { + return $lang_data[ $locale ]; + } + + // We need to return language data + $lang_data = array( + 'language' => $locale, + 't_id' => 0, + 'tt_id' => 0, + 'term' => null, + ); + + $language = $this->get_language( $locale ); + + // If the language object exists, add it! + if ( $language && ! empty( $language->term_id ) ) { + $lang_data['t_id'] = (int) $language->term_id; + $lang_data['tt_id'] = (int) $language->term_taxonomy_id; + $lang_data['tl_t_id'] = (int) $language->tl_term_id; + $lang_data['tl_tt_id'] = (int) $language->tl_term_taxonomy_id; + $lang_data['term'] = $language; + } + + $lang_data[ $locale ] = $lang_data; + + return $lang_data[ $locale ]; + } + + /** + * @param $locale + * + * @return false|\PLL_Language + */ + public function get_language( $locale ) { + $language = false; + + if ( ! $locale ) { + $locale = pods_i18n()->get_current_language(); + } + + // Get the language term object. + if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) { + // Polylang 1.8 and newer. + $language = PLL()->model->get_language( $locale ); + } else { + global $polylang; + if ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) { + // Polylang 1.2 - 1.7.x + $language = $polylang->model->get_language( $locale ); + } elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) { + // Polylang 1.1.x and older. + $language = $polylang->get_language( $locale ); + } + } + + return $language; + } + + /** + * @return string[] + */ + public function get_locales() { + $locales = []; + if ( function_exists( 'pll_languages_list' ) ) { + $locales = pll_languages_list( array( 'fields' => 'locale' ) ); + } + return $locales; + } + + /** + * @return array + */ + public function get_languages() { + $languages = []; + if ( function_exists( 'pll_languages_list' ) ) { + $languages = pll_languages_list( array( 'fields' => null ) ); + } + return $languages; + } +} diff --git a/src/Pods/Integrations/Service_Provider.php b/src/Pods/Integrations/Service_Provider.php new file mode 100644 index 0000000000..1f0729458c --- /dev/null +++ b/src/Pods/Integrations/Service_Provider.php @@ -0,0 +1,87 @@ +integrations = [ + 'polylang' => Polylang::class, + 'wpml' => WPML::class, + ]; + + foreach ( $this->integrations as $integration ) { + $this->container->singleton( $integration, $integration ); + } + + $this->container->singleton( 'pods.integration.genesis', Genesis::class ); + $this->container->singleton( 'pods.integration.yarpp', YARPP::class ); + $this->container->singleton( 'pods.integration.jetpack', Jetpack::class ); + + $this->hooks(); + } + + /** + * Hooks all the methods and actions the class needs. + * + * @since 2.8.0 + */ + protected function hooks() { + + add_filter( 'pods_admin_config_pod_fields_post_type_supported_features', $this->container->callback( 'pods.integration.genesis', 'add_post_type_supports' ) ); + add_filter( 'pods_admin_config_pod_fields_post_type_supported_features', $this->container->callback( 'pods.integration.yarpp', 'add_post_type_supports' ) ); + add_filter( 'pods_admin_config_pod_fields_post_type_supported_features', $this->container->callback( 'pods.integration.jetpack', 'add_post_type_supports' ) ); + + if ( ! did_action( 'plugins_loaded' ) ) { + add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ] ); + } else { + $this->plugins_loaded(); + } + } + + /** + * All plugins are loaded. + * + * @since 2.8.0 + */ + public function plugins_loaded() { + + /** + * Filter what integration classes should run on the plugins_loaded hook. + * + * @since 2.8.0 + * + * @param \Pods\Integration[] $integrations The list of integrations to run on plugins_loaded hook. + */ + $integrations = apply_filters( 'pods_integrations_on_plugins_loaded', $this->integrations ); + foreach ( $integrations as $class ) { + if ( is_string( $class ) ) { + $class = $this->container->make( $class ); + } + if ( $class instanceof Integration ) { + if ( $class->is_active() ) { + $class->hook(); + } + } + } + } +} diff --git a/src/Pods/Integrations/WPML.php b/src/Pods/Integrations/WPML.php new file mode 100644 index 0000000000..640d47cc7f --- /dev/null +++ b/src/Pods/Integrations/WPML.php @@ -0,0 +1,331 @@ + [], + 'filter' => [ + 'pods_get_current_language' => [ 'pods_get_current_language', 10, 2 ], + 'pods_api_get_table_info' => [ 'pods_api_get_table_info', 10, 7 ], + 'pods_data_traverse_recurse_ignore_aliases' => [ 'pods_data_traverse_recurse_ignore_aliases', 10 ], + 'pods_pods_field_get_metadata_object_id' => [ 'pods_pods_field_get_metadata_object_id', 10, 4 ], + 'pods_component_i18n_admin_data' => [ 'pods_component_i18n_admin_data' ], + 'pods_component_i18n_admin_ui_fields' => [ 'pods_component_i18n_admin_ui_fields', 10, 2 ], + ], + ]; + + /** + * @inheritDoc + */ + public static function is_active() { + return defined( 'ICL_SITEPRESS_VERSION' ) || ! empty( $GLOBALS['sitepress'] ); + } + + /** + * @since 2.8.0 + * + * @param array $ignore_aliases + * + * @return array + */ + public function pods_data_traverse_recurse_ignore_aliases( $ignore_aliases ) { + + $ignore_aliases[] = 'wpml_languages'; + + return $ignore_aliases; + } + + /** + * Get the current language. + * + * @since 2.8.0 + * + * @param string $current_language + * @param array $context + * + * @return string + */ + public function pods_get_current_language( $current_language, $context ) { + // Get the global current language (if set). + $wpml_language = apply_filters( 'wpml_current_language', null ); + $current_language = ( 'all' !== $wpml_language ) ? $wpml_language : ''; + + if ( ! is_admin() ) { + return $current_language; + } + + $defaults = [ + 'is_admin' => is_admin(), + 'is_ajax' => null, + 'is_pods_ajax' => null, + 'current_page' => '', + 'current_object_type' => '', + 'current_item_id' => '', + 'current_item_type' => '', + ]; + + $context = wp_parse_args( $context, $defaults ); + + $object_type = $context['current_object_type']; + $item_type = $context['current_item_type']; + + if ( ! $item_type ) { + return $current_language; + } + + /** + * In WPML the current language is always set to default on an edit screen. + * We need to overwrite this when the current object is not-translatable to enable relationships with different languages. + */ + switch ( $object_type ) { + case 'post': + if ( ! $this->is_translated_post_type( $item_type ) ) { + // Overwrite the current language to nothing if this is a NOT-translatable post_type. + $current_language = ''; + } + break; + + case 'term': + if ( ! $this->is_translated_taxonomy( $item_type ) ) { + // Overwrite the current language to nothing if this is a NOT-translatable taxonomy. + $current_language = ''; + } + break; + + case 'comment'; + // @todo Get comment post parent?? + //$current_language = ''; + break; + } + + return $current_language; + } + + /** + * Support for WPML 'duplicated' translation handling. + * + * @param int $id + * @param string $metadata_type + * @param array $params + * @param array|\Pods $pod + * + * @return int + */ + public function pods_pods_field_get_metadata_object_id( $id, $metadata_type, $params, $pod ) { + if ( ! did_action( 'wpml_loaded' ) ) { + return $id; + } + switch ( $metadata_type ) { + case 'post': + if ( $this->is_translated_post_type( $pod->pod_data['name'] ) ) { + $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $id ); + + if ( $master_post_id ) { + $id = $master_post_id; + } + } + break; + } + return $id; + } + + /** + * Filter table info data. + * + * @since 2.8.0 + * + * @param array $info + * @param string $object_type + * @param string $object + * @param string $name + * @param array|\Pods $pod + * @param array $field + * @param \PodsAPI $pods_api + * + * @return array + */ + public function pods_api_get_table_info( $info, $object_type, $object, $name, $pod, $field, $pods_api ) { + global $wpdb; + + if ( ! apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) { + return $info; + } + + $object_name = pods_sanitize( ( empty( $object ) ? $name : $object ) ); + + // Get current language + $current_language = pods_i18n()->get_current_language(); + + $db_prefix = $wpdb->get_blog_prefix(); + + $wpml_translations = false; + + switch ( $object_type ) { + + case 'post': + case 'post_type': + case 'media': + if ( $this->is_translated_post_type( $object_name ) ) { + $wpml_translations = " + LEFT JOIN `{$db_prefix}icl_translations` AS `wpml_translations` + ON `wpml_translations`.`element_id` = `t`.`ID` + AND `wpml_translations`.`element_type` = 'post_" . pods_sanitize( $object_name ) . "' + AND `wpml_translations`.`language_code` = '" . pods_sanitize( $current_language ) . "' + "; + } + break; + + case 'taxonomy': + case 'term': + case 'nav_menu': + case 'post_format': + if ( $this->is_translated_taxonomy( $object_name ) ) { + $wpml_translations = " + LEFT JOIN `{$db_prefix}icl_translations` AS `wpml_translations` + ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id` + AND `wpml_translations`.`element_type` = 'tax_" . pods_sanitize( $object_name ) . "' + AND `wpml_translations`.`language_code` = '" . pods_sanitize( $current_language ) . "' + "; + } + break; + } + + if ( $wpml_translations ) { + + $info['join']['wpml_translations'] = $wpml_translations; + + $info['join']['wpml_languages'] = " + LEFT JOIN `{$db_prefix}icl_languages` AS `wpml_languages` + ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1 + "; + + $info['where']['wpml_languages'] = "`wpml_languages`.`code` IS NOT NULL"; + } + + return $info; + } + + /** + * @param array $data + * + * @return array + */ + public function pods_component_i18n_admin_data( $data ) { + + foreach ( $data as $lang => $field_data ) { + if ( in_array( $lang, $this->get_locales(), true ) ) { + $data[ $lang ]['wpml'] = true; + } else { + $data[ $lang ]['wpml'] = false; + } + } + + return $data; + } + + /** + * @param array $fields + * @param array $data + * + * @return array + */ + public function pods_component_i18n_admin_ui_fields( $fields, $data ) { + + $fields['manage']['wpml'] = array( + 'label' => __( 'WPML', 'pods' ), + 'type' => 'boolean', + ); + + return $fields; + } + + /** + * Helper method for backwards compatibility. + * + * @since 2.8.0 + * + * @param string $object_name + * + * @return false|mixed|void + */ + public function is_translated_post_type( $object_name ) { + global $sitepress; + if ( has_filter( 'wpml_is_translated_post_type' ) ) { + return apply_filters( 'wpml_is_translated_post_type', false, $object_name ); + } elseif ( is_callable( [ $sitepress, 'is_translated_post_type' ] ) ) { + return $sitepress->is_translated_post_type( $object_name ); + } + return false; + } + + /** + * Helper method for backwards compatibility. + * + * @since 2.8.0 + * + * @param string $object_name + * + * @return false|mixed|void + */ + public function is_translated_taxonomy( $object_name ) { + global $sitepress; + if ( has_filter( 'wpml_is_translated_taxonomy' ) ) { + return apply_filters( 'wpml_is_translated_taxonomy', false, $object_name ); + } elseif ( is_callable( [ $sitepress, 'is_translated_taxonomy' ] ) ) { + return $sitepress->is_translated_taxonomy( $object_name ); + } + return false; + } + + /** + * @return array + */ + public function get_language( $locale ) { + $languages = $this->get_languages(); + $language = null; + if ( ! empty( $languages ) ) { + foreach ( $languages as $lang => $lang_data ) { + if ( isset( $lang_data['default_locale'] ) && $locale === $lang_data['default_locale'] ) { + $language = $lang_data; + break; + } + } + } + return $language; + } + + /** + * @return string[] + */ + public function get_locales() { + $languages = $this->get_languages(); + $locales = []; + if ( ! empty( $languages ) ) { + foreach ( $languages as $lang => $lang_data ) { + if ( isset( $lang_data['default_locale'] ) ) { + $locales[] = $lang_data['default_locale'];; + } + } + } + return $locales; + } + + /** + * @return array + */ + public function get_languages() { + return apply_filters( 'wpml_active_languages', array() ); + } +} diff --git a/src/Pods/Integrations/YARPP.php b/src/Pods/Integrations/YARPP.php new file mode 100644 index 0000000000..8aedbcb60b --- /dev/null +++ b/src/Pods/Integrations/YARPP.php @@ -0,0 +1,34 @@ + 'supports_yarpp_support', + 'label' => __( 'YARPP Support', 'pods' ), + 'type' => 'boolean', + ]; + + return $supports; + } +} diff --git a/src/Pods/Permissions.php b/src/Pods/Permissions.php new file mode 100644 index 0000000000..a438f19770 --- /dev/null +++ b/src/Pods/Permissions.php @@ -0,0 +1,399 @@ +exists() ){ + return false; + } + + return $user; + } + + /** + * Determine whether a user has permission to an object. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * @param null|int|WP_User $user The user ID or object (default: current user). + * + * @return bool Whether a user has permission to an object. + */ + public function user_has_permission( $object, $user = null ) { + $user = $this->get_user( $user ); + + // Merge config options if pre Pods 2.8 format provided. + if ( isset( $object['options'] ) ) { + $object = pods_config_merge_data( $object, $object['options'] ); + } + + if ( $this->is_input_disallowed( $object ) ) { + $user_has_permission = false; + } elseif ( $this->is_admin_only( $object ) ) { + $user_has_permission = $this->is_user_an_admin( null, $user ); + } else { + $user_has_permission = ( + ( + ! $this->is_logged_in_only( $object ) + || is_user_logged_in() + ) + && ! $this->are_roles_restricted_for_user( $object, $user ) + && ! $this->are_capabilities_restricted_for_user( $object, $user ) + ); + } + + /** + * Allow filtering whether a user has permission to an object. + * + * @since 2.8.0 + * + * @param bool $user_has_permission Whether a user has permission to an object. + * @param array|Whatsit $object The object data. + * @param null|int|WP_User $user The user ID or object (default: current user). + */ + return apply_filters( 'pods_permissions_user_has_permission', $user_has_permission, $object, $user ); + } + + /** + * Check if permissions are restricted for an object. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * + * @return bool Whether the permissions are restricted for an object. + */ + public function are_permissions_restricted( $object ) { + if ( isset( $object['options'] ) ) { + $object = pods_config_merge_data( $object, $object['options'] ); + } + + $are_permissions_restricted = ( + $this->is_input_disallowed( $object ) + || $this->is_logged_in_only( $object ) + || $this->is_admin_only( $object ) + || $this->get_restricted_roles( $object ) + || $this->get_restricted_capabilities( $object ) + ); + + /** + * Allow filtering whether permissions are restricted for an object. + * + * @since 2.8.0 + * + * @param bool $are_permissions_restricted Whether the permissions are restricted for an object. + * @param array|Whatsit $object The object data. + */ + return apply_filters( 'pods_permissions_are_permissions_restricted', $are_permissions_restricted, $object ); + } + + /** + * Determine whether roles are restricted for user on an object. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * @param null|int|WP_User $user The user ID or object (default: current user). + * + * @return bool Whether roles are restricted for user on an object. + */ + public function are_roles_restricted_for_user( $object, $user = null ) { + $restricted_roles = $this->get_restricted_roles( $object ); + + // Do not restrict if no restricted roles provided. + if ( ! $restricted_roles ) { + return false; + } + + $user = $this->get_user( $user ); + + // Restrict for invalid users. + if ( ! $user ) { + return true; + } + + $matching_roles = array_intersect( $restricted_roles, $user->roles ); + + // Restrict if we do not have any matching roles. + return empty( $matching_roles ); + } + + /** + * Get the list of restricted capabilities. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * + * @return array|false The list of restricted capabilities or false if not restricted. + */ + public function get_restricted_roles( $object ) { + if ( 0 === (int) pods_v( 'restrict_role', $object, 0 ) ) { + return false; + } + + $roles_allowed = pods_v( 'roles_allowed', $object, '' ); + + if ( '' !== $roles_allowed ) { + $roles_allowed = maybe_unserialize( $roles_allowed ); + + if ( ! is_array( $roles_allowed ) ) { + $roles_allowed = explode( ',', $roles_allowed ); + } + + $roles_allowed = array_unique( array_filter( $roles_allowed ) ); + } + + return ! empty( $roles_allowed ) ? $roles_allowed : false; + } + + /** + * Determine whether capabilities are restricted for user on an object. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * @param null|int|WP_User $user The user ID or object (default: current user). + * + * @return bool Whether capabilities are restricted for user on an object. + */ + public function are_capabilities_restricted_for_user( $object, $user = null ) { + $restricted_capabilities = $this->get_restricted_capabilities( $object ); + + // Do not restrict if no restricted capabilities provided. + if ( ! $restricted_capabilities ) { + return false; + } + + $user = $this->get_user( $user ); + + // Restrict for invalid users. + if ( ! $user ) { + return true; + } + + $is_restricted = true; + + // Check if user has ANY of the capabilities. + foreach ( $restricted_capabilities as $capabilities ) { + $is_set_restricted = false; + + // Check if user has ALL of the capabilities. + foreach ( $capabilities as $capability ) { + if ( ! $user->has_cap( $capability ) ) { + $is_set_restricted = true; + + break; + } + } + + if ( ! $is_set_restricted ) { + $is_restricted = false; + + break; + } + } + + return $is_restricted; + } + + /** + * Get the list of restricted capabilities. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * + * @return array[]|false The list of restricted sets of capabilities or false if not restricted. + */ + public function get_restricted_capabilities( $object ) { + if ( 0 === (int) pods_v( 'restrict_capability', $object, 0 ) ) { + return false; + } + + $capability_allowed = pods_v( 'capability_allowed', $object, '' ); + + if ( '' !== $capability_allowed ) { + $capability_allowed = maybe_unserialize( $capability_allowed ); + + if ( ! is_array( $capability_allowed ) ) { + $capability_allowed = explode( ',', $capability_allowed ); + } + + $capability_allowed = array_unique( $capability_allowed ); + + foreach ( $capability_allowed as $k => $capability ) { + if ( ! is_array( $capability ) ) { + $capability = explode( '&&', $capability ); + } + + $capability = array_unique( array_filter( $capability ) ); + + $capability_allowed[ $k ] = $capability; + } + + $capability_allowed = array_filter( $capability_allowed ); + } + + return ! empty( $capability_allowed ) ? $capability_allowed : false; + } + + /** + * Determine whether permissions are restricted to admins only. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * + * @return bool Whether permissions are restricted to admins only. + */ + public function is_logged_in_only( $object ) { + return 1 === (int) pods_v( 'logged_in_only', $object, 0 ); + } + + /** + * Determine whether permissions are restricted to admins only. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * + * @return bool Whether permissions are restricted to admins only. + */ + public function is_admin_only( $object ) { + return 1 === (int) pods_v( 'admin_only', $object, 0 ); + } + + /** + * Determine whether input is disallowed. + * + * @since 2.8.0 + * + * @param array|Whatsit $object The object data. + * + * @return bool Whether input is disallowed. + */ + public function is_input_disallowed( $object ) { + $non_input_field_types = PodsForm::non_input_field_types(); + + return in_array( pods_v( 'type', $object ), $non_input_field_types, true ); + } + + /** + * Determine whether a user is a Pods Admin. + * + * @since 2.8.0 + * + * @param string|array $additional_capabilities Additional capabilities to check. + * @param null|int|WP_User $user The user ID or object (default: current user). + * + * @return bool Whether a user is a Pods Admin. + */ + public function is_user_an_admin( $additional_capabilities = null, $user = null ) { + $user = $this->get_user( $user ); + + // Invalid user is not an admin. + if ( ! $user ) { + return false; + } + + $is_multisite = is_multisite(); + + if ( empty( $additional_capabilities ) ) { + $additional_capabilities = []; + } elseif ( ! is_array( $additional_capabilities ) ) { + $additional_capabilities = explode( ',', $additional_capabilities ); + } + + if ( $is_multisite && is_super_admin( $user->ID ) ) { + /** + * Allow filtering whether a user is a Pods Admin. + * + * @since 2.3.5 + * + * @param bool $is_admin Whether a user is a Pods Admin. + * @param array $additional_capabilities Additional capabilities to check. + * @param string $capability_match The matching capability. + * @param WP_User $user The user object. + */ + return apply_filters( 'pods_is_admin', true, $additional_capabilities, '_super_admin', $user ); + } + + $pods_admin_capabilities = []; + + if ( ! $is_multisite ) { + // Default is_super_admin() checks against this capability. + $pods_admin_capabilities[] = 'delete_users'; + } + + /** + * Allow filtering whether a user is a Pods Admin. + * + * @since 2.3.5 + * + * @param array $pods_admin_capabilities The list of capabilities to check for a Pods Admin. + * @param array $additional_capabilities Additional capabilities to check. + * @param WP_User $user The user object. + */ + $pods_admin_capabilities = apply_filters( 'pods_admin_capabilities', $pods_admin_capabilities, $additional_capabilities, $user ); + + $check_capabilities = array_unique( array_filter( array_merge( $pods_admin_capabilities, $additional_capabilities ) ) ); + + $match = false; + $capability_match = null; + + foreach ( $check_capabilities as $capability ) { + if ( $user->has_cap( $capability ) ) { + $match = true; + + $capability_match = $capability; + + break; + } + } + + /** + * Allow filtering whether a user is a Pods Admin. + * + * @since 2.3.5 + * + * @param bool $is_admin Whether a user is a Pods Admin. + * @param array $additional_capabilities Additional capabilities to check. + * @param string $capability_match The matching capability. + * @param WP_User $user The user object. + */ + return apply_filters( 'pods_is_admin', $match, $additional_capabilities, $capability_match ); + } + +} diff --git a/src/Pods/REST/Interfaces/Post_Repository.php b/src/Pods/REST/Interfaces/Post_Repository.php new file mode 100644 index 0000000000..21525fa89b --- /dev/null +++ b/src/Pods/REST/Interfaces/Post_Repository.php @@ -0,0 +1,14 @@ + 'object', + 'properties' => [ + 'id' => [ + 'type' => 'integer', + 'description' => __( 'The ticket WordPress post ID', 'pods' ), + ], + 'post_id' => [ + 'type' => 'integer', + 'description' => __( 'The ID of the post the ticket is associated to', 'pods' ), + ], + 'global_id' => [ + 'type' => 'string', + 'description' => __( 'The ticket global ID', 'pods' ), + ], + 'global_id_lineage' => [ + 'type' => 'array', + 'items' => [ + 'type' => 'string', + ], + 'description' => __( 'The ticket global ID lineage', 'pods' ), + ], + 'author' => [ + 'type' => 'integer', + 'description' => __( 'The ticket post author ID', 'pods' ), + ], + 'status' => [ + 'type' => 'string', + 'description' => __( 'The ticket post status', 'pods' ), + ], + 'date' => [ + 'type' => 'string', + 'format' => 'date', + 'description' => __( 'The ticket creation date', 'pods' ), + ], + 'date_utc' => [ + 'type' => 'string', + 'format' => 'date', + 'description' => __( 'The ticket creation UTC date', 'pods' ), + ], + 'modified' => [ + 'type' => 'string', + 'format' => 'date', + 'description' => __( 'The ticket modification date', 'pods' ), + ], + 'modified_utc' => [ + 'type' => 'string', + 'format' => 'date', + 'description' => __( 'The ticket modification UTC date', 'pods' ), + ], + 'rest_url' => [ + 'type' => 'string', + 'format' => 'uri', + 'description' => __( 'The ticket ET REST API URL', 'pods' ), + ], + 'provider' => [ + 'type' => 'string', + 'description' => __( 'The ticket commerce provider', 'pods' ), + 'enum' => [ 'rsvp', 'tribe-commerce', 'woo', 'edd' ], + ], + 'title' => [ + 'type' => 'string', + 'description' => __( 'The ticket title', 'pods' ), + ], + 'description' => [ + 'type' => 'string', + 'description' => __( 'The ticket description', 'pods' ), + ], + 'image' => [ + '$ref' => '#/components/schemas/Image', + ], + 'available_from' => [ + 'type' => 'string', + 'format' => 'date', + 'description' => __( 'The date the ticket will be available', 'pods' ), + ], + 'available_from_details' => [ + '$ref' => '#/components/schemas/DateDetails', + ], + 'available_until' => [ + 'type' => 'string', + 'format' => 'date', + 'description' => __( 'The date the ticket will be available', 'pods' ), + ], + 'available_until_details' => [ + '$ref' => '#/components/schemas/DateDetails', + ], + 'capacity' => [ + 'type' => 'integer', + 'description' => __( 'The formatted ticket current capacity', 'pods' ), + ], + 'capacity_details' => [ + '$ref' => '#/components/schemas/CapacityDetails', + ], + 'is_available' => [ + 'type' => 'boolean', + 'description' => __( 'Whether the ticket is currently available or not due to capacity or date constraints', 'pods' ), + ], + 'cost' => [ + 'type' => 'integer', + 'description' => __( 'The formatted cost string', 'pods' ), + ], + 'cost_details' => [ + '$ref' => '#/components/schemas/CostDetails', + ], + 'attendees' => [ + 'type' => 'array', + 'items' => [ + '$ref' => '#/components/schemas/Attendee', + ], + 'description' => __( 'A list of attendees for the ticket, ', 'pods' ), + ], + 'supports_attendee_information' => [ + 'type' => 'boolean', + 'description' => __( 'Whether the ticket supports at least one attendee information field, ET+ required', 'pods' ), + ], + 'requires_attendee_information' => [ + 'type' => 'boolean', + 'description' => __( 'Whether the ticket requires at least one attendee information field, ET+ required', 'pods' ), + ], + 'attendee_information_fields' => [ + 'type' => 'object', + 'description' => __( 'A list of attendee information fields supported/required by the ticket in the format [ : label, required, type, extra ]', 'pods' ), + ], + 'rsvp' => [ + '$ref' => '#/components/schemas/RSVPReport', + ], + 'checkin' => [ + '$ref' => '#/components/schemas/CheckinReport', + ], + ], + ]; + + /** + * Filters the Swagger documentation generated in the REST API. + * + * @since 2.8.0 + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'pods_rest_swagger_ticket_documentation', $documentation ); + + return $documentation; + } +} diff --git a/src/Pods/REST/V1/Endpoints/Base.php b/src/Pods/REST/V1/Endpoints/Base.php new file mode 100644 index 0000000000..1c47f57f8b --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Base.php @@ -0,0 +1,618 @@ +messages = $messages; + $this->post_repository = $post_repository; + $this->validator = $validator; + } + + /** + * Converts an array of arguments suitable for the WP REST API to the Swagger format. + * + * @since 2.8.0 + * + * @param array $args List of arguments to convert to Swagger format. + * @param array $defaults List of defaults to merge into the arguments. + * + * @return array The converted arguments. + */ + public function swaggerize_args( array $args = [], array $defaults = [] ) { + if ( empty( $args ) ) { + return $args; + } + + $no_description = __( 'No description provided.', 'pods' ); + + $defaults = array_merge( [ + 'in' => 'body', + 'schema' => [ + 'type' => 'string', + 'default' => '', + ], + 'description' => $no_description, + 'required' => false, + 'items' => [ + 'type' => 'integer', + ], + ], $defaults ); + + $swaggerized = []; + + foreach ( $args as $name => $info ) { + $type = false; + + if ( isset( $info['swagger_type'] ) ) { + $type = $info['swagger_type']; + } elseif ( isset( $info['type'] ) ) { + $type = $info['type']; + } + + if ( is_array( $type ) ) { + $type = $this->convert_type( $type ); + } + + $schema = null; + + if ( is_array( $type ) ) { + $schema = $type; + + unset( $info['swagger_type'] ); + } else { + $schema = [ + 'type' => $type, + 'default' => isset( $info['default'] ) ? $info['default'] : false, + ]; + } + + $read = [ + 'name' => $name, + 'description' => isset( $info['description'] ) ? $info['description'] : false, + 'in' => isset( $info['in'] ) ? $info['in'] : false, + 'collectionFormat' => isset( $info['collectionFormat'] ) ? $info['collectionFormat'] : false, + 'schema' => $schema, + 'items' => isset( $info['items'] ) ? $info['items'] : false, + 'required' => isset( $info['required'] ) ? $info['required'] : false, + ]; + + if ( isset( $info['swagger_type'] ) ) { + $read['schema']['type'] = $info['swagger_type']; + } + + if ( isset( $read['schema']['type'] ) && $read['schema']['type'] !== 'array' ) { + unset( $defaults['items'] ); + } + + $merged = array_merge( $defaults, array_filter( $read ) ); + + unset( $merged['type'], $merged['default'] ); + + $swaggerized[] = $merged; + } + + return $swaggerized; + } + + /** + * Converts REST format type argument to the corresponding Swagger.io definition. + * + * @since 2.8.0 + * + * @param string $type A type string or an array of types to define a `oneOf` type. + * + * @return string A converted type or the original types array. + */ + protected function convert_type( $type ) { + $rest_to_swagger_type_map = [ + 'int' => 'integer', + 'bool' => 'boolean', + ]; + + return Utils_Array::get( $rest_to_swagger_type_map, $type, $type ); + } + + /** + * Check whether a value is null or not. + * + * @since 2.8.0 + * + * @param mixed $value The value to check. + * + * @return bool Whether a value is null or not. + */ + public function is_not_null( $value ) { + return null !== $value; + } + + /** + * Get the route path for this endpoint. + * + * @since 2.8.0 + * + * @return string The route path. + */ + public function get_route() { + /** @var Main $main */ + $main = tribe( 'pods.rest-v1.main' ); + + $namespace = $main->get_pods_route_namespace(); + + return $namespace . $this->route; + } + + /** + * Handle getting the object archive. + * + * @since 2.8.0 + * + * @param WP_REST_Request $request The request object. + * + * @return array|WP_Error The response or an error. + * @throws Exception + */ + public function archive_by_args( WP_REST_Request $request ) { + $params = [ + 'return_type' => $request['return_type'], + ]; + + if ( in_array( $this->object, [ 'group', 'field' ], true ) && ! empty( $request['pod'] ) ) { + $params['pod'] = $request['pod']; + } + + if ( 'field' === $this->object && ! empty( $request['group'] ) ) { + $params['group'] = $request['group']; + } + + if ( ! empty( $request['types'] ) ) { + $params['type'] = Utils_Array::list_to_array( $request['types'] ); + } + + if ( ! empty( $request['ids'] ) ) { + $params['id'] = Utils_Array::list_to_array( $request['ids'] ); + } + + if ( ! empty( $request['args'] ) ) { + $params['args'] = $request['args']; + + // Attempt to convert from JSON to array if needed. + if ( is_string( $params['args'] ) ) { + $json = @json_decode( $params['args'], true ); + + if ( is_array( $json ) ) { + $params['args'] = $json; + } + } + } + + if ( ! empty( $request['return_type'] ) ) { + $params['return_type'] = $request['return_type']; + } + + $object_plural = $this->object . 's'; + $method = 'load_' . $object_plural; + + $api = pods_api(); + + $api->display_errors = 'wp_error'; + + $objects = $api->$method( $params ); + + if ( is_wp_error( $objects ) ) { + return $objects; + } + + if ( is_array( $objects ) ) { + // Prevent objects. + $objects = array_values( $objects ); + + // Handle parent details. + if ( in_array( $this->object, [ 'group', 'field' ], true ) && 1 === (int) $request['include_parent'] ) { + foreach ( $objects as $k => $object ) { + /** @var $object Whatsit\Field|Whatsit\Group */ + // Set temporary data so parent data gets exported. + $object->set_arg( 'parent_data', $object->get_parent_object() ); + } + } + } + + return [ + $object_plural => $objects, + ]; + } + + /** + * Handle creating the object using specific REST / Pods API arguments. + * + * @since 2.8.0 + * + * @param WP_REST_Request $request REST API Request object. + * @param bool $return_id Whether to return the object ID (off returns full response). + * + * @return array|WP_Error + * + * @throws Exception + */ + public function create_by_args( WP_REST_REQUEST $request, $return_id = false ) { + $params = $this->setup_params( $request ); + + $api = pods_api(); + + $api->display_errors = 'wp_error'; + + if ( empty( $params['name'] ) && empty( $params['label'] ) ) { + return new WP_Error( 'rest-object-not-added-fields-required', sprintf( __( '%s not added, name or label is required.', 'pods' ), ucwords( $this->object ) ) ); + } + + if ( empty( $params['name'] ) ) { + $params['name'] = pods_clean_name( $params['label'], true ); + } + + $load_method = 'load_' . $this->object; + + $load_params = [ + 'name' => $params['name'], + ]; + + if ( ! empty( $params['pod'] ) ) { + $load_params['pod'] = $params['pod']; + } + + if ( ! empty( $params['pod_id'] ) ) { + $load_params['pod_id'] = $params['pod_id']; + } + + $loaded_object = $api->$load_method( $load_params ); + + if ( $loaded_object && ! is_wp_error( $loaded_object ) ) { + return new WP_Error( 'rest-object-not-added-already-exists', sprintf( __( '%s not added, it already exists.', 'pods' ), ucwords( $this->object ) ) ); + } + + $method = 'save_' . $this->object; + + if ( in_array( $this->object, [ 'field', 'group' ], true ) ) { + $method = 'add_' . $this->object; + } + + $id = $api->$method( $params ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + if ( empty( $id ) ) { + return new WP_Error( 'rest-object-not-added', sprintf( __( '%s not added.', 'pods' ), ucwords( $this->object ) ) ); + } + + return $this->get_by_args( [ + 'id' => $id, + ], 'id', $request, $return_id ); + } + + /** + * Setup the parameters for saving. + * + * @param WP_REST_Request $request The request object. + * + * @return array Parameters for saving. + */ + protected function setup_params( WP_REST_Request $request ) { + $defaults = [ + 'id' => null, + 'name' => null, + 'label' => null, + 'args' => null, + ]; + + $params = wp_parse_args( $request->get_params(), $defaults ); + $params = array_filter( $params, [ $this->validator, 'is_not_null' ] ); + + if ( isset( $params['args'] ) ) { + $args = $params['args']; + + unset( $params['args'] ); + + // Attempt to convert from JSON to array if needed. + if ( is_string( $args ) ) { + $json = @json_decode( $args, true ); + + if ( is_array( $json ) ) { + $args = $json; + } + } + + if ( is_array( $args ) ) { + $params = array_merge( $params, $args ); + } + } + + return $params; + } + + /** + * Handle getting the object using specific REST / Pods API arguments. + * + * @since 2.8.0 + * + * @param string|array $rest_param REST API parameter name to look for OR arguments to pass to loader. + * @param string $api_arg Pods API argument name to use for lookups. + * @param WP_REST_Request|null $request The request object. + * @param bool $return_id Whether to return the object ID (off returns full response). + * + * @return array|WP_Error The response or an error. + * @throws Exception + */ + public function get_by_args( $rest_param, $api_arg, WP_REST_Request $request = null, $return_id = false ) { + if ( is_array( $rest_param ) ) { + $args = $rest_param; + } elseif ( $request ) { + $identifier = $request[ $rest_param ]; + + $args = [ + $api_arg => $identifier, + ]; + + if ( $rest_param !== $api_arg ) { + unset( $request[ $rest_param ] ); + } + + $args = array_merge( $request->get_params(), $args ); + } else { + return new WP_Error( 'rest-object-not-found', sprintf( __( '%s not found.', 'pods' ), ucwords( $this->object ) ) ); + } + + $api = pods_api(); + + $api->display_errors = 'wp_error'; + + $method = 'load_' . $this->object; + + $object = $api->$method( $args ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + if ( empty( $object ) ) { + return new WP_Error( 'rest-object-not-found', sprintf( __( '%s not found.', 'pods' ), ucwords( $this->object ) ), $args ); + } + + $include_parent = false; + $include_groups = false; + $include_group_fields = false; + $include_fields = false; + + // Set up flags based on request. + if ( $request ) { + $include_parent = in_array( $this->object, [ 'group', 'field' ], true ) && 1 === (int) $request['include_parent']; + + if ( 'pod' === $this->object ) { + $include_groups = 1 === (int) $request['include_groups']; + $include_group_fields = 1 === (int) $request['include_group_fields']; + } + + if ( in_array( $this->object, [ 'pod', 'group' ], true ) ) { + $include_fields = 1 === (int) $request['include_fields']; + } + } + + // Handle parent details. + if ( $include_parent ) { + // Set temporary data so parent data gets exported. + $object->set_arg( 'parent_data', $object->get_parent_data() ); + } + + /** @var Whatsit $object */ + return [ + $this->object => $object->export( [ + 'include_groups' => $include_groups, + 'include_group_fields' => $include_group_fields, + 'include_fields' => $include_fields, + ] ), + ]; + } + + /** + * Handle updating the object using specific REST / Pods API arguments. + * + * @since 2.8.0 + * + * @param string $rest_param REST API parameter name to look for. + * @param string $api_arg Pods API argument name to use for lookups. + * @param WP_REST_Request $request REST API Request object. + * + * @return array|WP_Error + * + * @throws Exception + */ + public function update_by_args( $rest_param, $api_arg, WP_REST_Request $request ) { + $api = pods_api(); + + $api->display_errors = 'wp_error'; + + $identifier = $request[ $rest_param ]; + + // Send proper identifier argument. + if ( $rest_param !== $api_arg ) { + $request[ $api_arg ] = $identifier; + + unset( $request[ $rest_param ] ); + } + + $method = 'load_' . $this->object; + + $object = $api->$method( [ + $api_arg => $identifier, + ] ); + + if ( is_wp_error( $object ) ) { + return $object; + } + + if ( ! $object instanceof Whatsit ) { + return new WP_Error( 'rest-object-not-found-cannot-update', sprintf( __( '%s was not found, cannot update.', 'pods' ), ucwords( $this->object ), $args ) ); + } + + $params = $this->setup_params( $request ); + + $params['id'] = $object['id']; + + // Pass the object for reuse. + $params[ $this->object ] = $object; + + if ( in_array( $this->object, [ 'group', 'field' ], true ) ) { + $params['pod'] = $object->get_parent_object(); + } + + $save_method = 'save_' . $this->object; + + // Handle save. + $saved = $api->$save_method( $params ); + + if ( is_wp_error( $saved ) ) { + return $saved; + } + + // Return the refreshed object data. + return $this->get_by_args( [ + $api_arg => $identifier, + 'bypass_cache' => true, + ], $api_arg ); + } + + /** + * Handle deleting the object using specific REST / Pods API arguments. + * + * @since 2.8.0 + * + * @param string|array $rest_param REST API parameter name to look for OR arguments to pass to loader. + * @param string $api_arg Pods API argument name to use for lookups. + * @param WP_REST_Request $request REST API Request object. + * + * @return array|WP_Error + * + * @throws Exception + */ + public function delete_by_args( $rest_param, $api_arg, WP_REST_Request $request ) { + if ( is_array( $rest_param ) ) { + $args = $rest_param; + } else { + $identifier = $request[ $rest_param ]; + + $args = [ + $api_arg => $identifier, + ]; + + if ( $rest_param !== $api_arg ) { + unset( $request[ $rest_param ] ); + } + } + + $args = array_merge( $request->get_params(), $args ); + + $api = pods_api(); + + $api->display_errors = 'wp_error'; + + $method = 'delete_' . $this->object; + + $deleted = $api->$method( $args ); + + if ( is_wp_error( $deleted ) ) { + return $deleted; + } + + if ( ! $deleted ) { + return new WP_Error( 'rest-object-not-deleted', sprintf( __( '%s not deleted.', 'pods' ), ucwords( $this->object ) ) ); + } + + return [ + 'status' => 'deleted', + ]; + } + + /** + * Parses the arguments populated parsing the request filling out with the defaults. + * + * @since 2.8.0 + * + * @param array $args List of arguments to fill out with defaults. + * @param array $defaults List of defaults to merge with arguments. + * + * @return array List of arguments populated from the request. + */ + protected function parse_args( array $args, array $defaults ) { + foreach ( $this->supported_query_vars as $request_key => $query_var ) { + if ( isset( $defaults[ $request_key ] ) ) { + $defaults[ $query_var ] = $defaults[ $request_key ]; + } + } + + $args = wp_parse_args( array_filter( $args, [ $this, 'is_not_null' ] ), $defaults ); + + return $args; + } +} diff --git a/src/Pods/REST/V1/Endpoints/Field.php b/src/Pods/REST/V1/Endpoints/Field.php new file mode 100644 index 0000000000..33e4fe323e --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Field.php @@ -0,0 +1,214 @@ + 'query', + 'default' => '', + 'type' => 'string', + ]; + + // @todo Handle get/post/delete + + return [ + 'get' => [ + 'summary' => __( 'Returns a single ticket data.', 'pods' ), + 'parameters' => $this->swaggerize_args( $this->READ_args(), $GET_defaults ), + 'responses' => [ + '200' => [ + 'description' => __( 'Returns the data of the ticket with the specified post ID.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + '$ref' => '#/components/schemas/Ticket', + ], + ], + ], + ], + '400' => [ + 'description' => __( 'The ticket post ID is invalid.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '401' => [ + 'description' => __( 'The ticket with the specified ID is not accessible.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '404' => [ + 'description' => __( 'A ticket with the specified ID does not exist.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function READ_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Field ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_field_id' ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->get_by_args( 'id', 'id', $request ); + } + + /** + * Determine whether access to READ is available. + * + * @since 2.8.0 + * + * @return bool Whether access to READ is available. + */ + public function can_read() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function EDIT_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Field ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_field_id' ], + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The new name of the Field.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Field.', 'pods' ), + ], + 'type' => [ + 'type' => 'string', + 'description' => __( 'The type of the Field.', 'pods' ), + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Field.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function update( WP_REST_Request $request ) { + return $this->update_by_args( 'id', 'id', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_edit() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function DELETE_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Field ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_field_id' ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function delete( WP_REST_Request $request ) { + return $this->delete_by_args( 'id', 'id', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_delete() { + return pods_is_admin( 'pods' ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Field_Slug.php b/src/Pods/REST/V1/Endpoints/Field_Slug.php new file mode 100644 index 0000000000..60ecac48f1 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Field_Slug.php @@ -0,0 +1,136 @@ + [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Field slug.', 'pods' ), + 'required' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->get_by_args( 'slug', 'name', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function EDIT_args() { + return [ + 'pod' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Field slug.', 'pods' ), + 'required' => true, + ], + 'new_name' => [ + 'type' => 'string', + 'description' => __( 'The new name of the Field.', 'pods' ), + ], + 'new_group' => [ + 'type' => 'string', + 'description' => __( 'The new Group to use for the Field.', 'pods' ), + ], + 'new_group_id' => [ + 'type' => 'string', + 'description' => __( 'The new Group ID to use for the Field.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Field.', 'pods' ), + ], + 'type' => [ + 'type' => 'string', + 'description' => __( 'The type of the Field.', 'pods' ), + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Field.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function update( WP_REST_Request $request ) { + return $this->update_by_args( 'slug', 'name', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function DELETE_args() { + return [ + 'pod' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Field slug.', 'pods' ), + 'required' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function delete( WP_REST_Request $request ) { + return $this->delete_by_args( 'slug', 'name', $request ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Fields.php b/src/Pods/REST/V1/Endpoints/Fields.php new file mode 100644 index 0000000000..b0f83801e3 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Fields.php @@ -0,0 +1,238 @@ + 'query', + 'default' => '', + ]; + + // @todo Handle get/post + + return [ + 'get' => [ + 'parameters' => $this->swaggerize_args( $this->READ_args(), $GET_defaults ), + 'responses' => [ + '200' => [ + 'description' => __( 'Returns all the tickets matching the search criteria.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + 'properties' => [ + 'rest_url' => [ + 'type' => 'string', + 'format' => 'uri', + 'description' => __( 'This results page REST URL.', 'pods' ), + ], + 'total' => [ + 'type' => 'integer', + 'description' => __( 'The total number of results across all pages.', 'pods' ), + ], + 'total_pages' => [ + 'type' => 'integer', + 'description' => __( 'The total number of result pages matching the search criteria.', 'pods' ), + ], + 'tickets' => [ + 'type' => 'array', + 'items' => [ '$ref' => '#/components/schemas/Ticket' ], + ], + ], + ], + ], + ], + ], + '400' => [ + 'description' => __( 'One or more of the specified query variables has a bad format.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '404' => [ + 'description' => __( 'The requested page was not found.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function READ_args() { + return [ + 'return_type' => [ + 'description' => __( 'The type of data to return.', 'pods' ), + 'type' => 'string', + 'default' => 'full', + 'required' => false, + 'enum' => [ + 'full', + 'names', + 'names_ids', + 'ids', + 'key_names', + 'count', + ], + ], + 'types' => [ + 'required' => false, + 'description' => __( 'A list of types to filter by.', 'pods' ), + 'swagger_type' => 'array', + 'items' => [ + 'type' => 'string', + ], + 'collectionFormat' => 'csv', + ], + 'ids' => [ + 'required' => false, + 'description' => __( 'A list of IDs to filter by.', 'pods' ), + 'swagger_type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'collectionFormat' => 'csv', + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of arguments to filter by.', 'pods' ), + 'swagger_type' => 'array', + ], + 'include_parent' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include the parent Pod details (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->archive_by_args( $request ); + } + + /** + * Determine whether access to READ is available. + * + * @since 2.8.0 + * + * @return bool Whether access to READ is available. + */ + public function can_read() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function CREATE_args() { + return [ + 'pod_id' => [ + 'type' => 'string', + 'description' => __( 'The Pod ID.', 'pods' ), + 'validate_callback' => [ $this->validator, 'is_pod_id' ], + ], + 'pod' => [ + 'type' => 'string', + 'description' => __( 'The Pod name.', 'pods' ), + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'group_id' => [ + 'type' => 'string', + 'description' => __( 'The Group ID.', 'pods' ), + 'validate_callback' => [ $this->validator, 'is_group_id' ], + ], + 'group' => [ + 'type' => 'string', + 'description' => __( 'The Group name.', 'pods' ), + 'validate_callback' => [ $this->validator, 'is_group_slug' ], + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The name of the Field.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Field.', 'pods' ), + 'required' => true, + ], + 'type' => [ + 'type' => 'string', + 'description' => __( 'The type of the Field.', 'pods' ), + 'enum' => PodsForm::field_types_list(), + 'required' => true, + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Field.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function create( WP_REST_REQUEST $request, $return_id = false ) { + return $this->create_by_args( $request, $return_id ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_create() { + return pods_is_admin( 'pods' ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Group.php b/src/Pods/REST/V1/Endpoints/Group.php new file mode 100644 index 0000000000..04abbef2c7 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Group.php @@ -0,0 +1,224 @@ + 'query', + 'default' => '', + 'type' => 'string', + ]; + + // @todo Handle get/post/delete + + return [ + 'get' => [ + 'summary' => __( 'Returns a single ticket data.', 'pods' ), + 'parameters' => $this->swaggerize_args( $this->READ_args(), $GET_defaults ), + 'responses' => [ + '200' => [ + 'description' => __( 'Returns the data of the ticket with the specified post ID.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + '$ref' => '#/components/schemas/Ticket', + ], + ], + ], + ], + '400' => [ + 'description' => __( 'The ticket post ID is invalid.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '401' => [ + 'description' => __( 'The ticket with the specified ID is not accessible.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '404' => [ + 'description' => __( 'A ticket with the specified ID does not exist.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function READ_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Group ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_group_id' ], + ], + 'include_fields' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include fields (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->get_by_args( 'id', 'id', $request ); + } + + /** + * Determine whether access to READ is available. + * + * @since 2.8.0 + * + * @return bool Whether access to READ is available. + */ + public function can_read() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function EDIT_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Group ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_group_id' ], + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The new name of the Group.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Group.', 'pods' ), + ], + 'type' => [ + 'type' => 'string', + 'description' => __( 'The type of the Group.', 'pods' ), + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Group.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function update( WP_REST_Request $request ) { + if ( ! empty( $request['fields'] ) ) { + $request->set_param( 'fields', null ); + } + + return $this->update_by_args( 'id', 'id', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_edit() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function DELETE_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Group ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_group_id' ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function delete( WP_REST_Request $request ) { + return $this->delete_by_args( 'id', 'id', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_delete() { + return pods_is_admin( 'pods' ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Group_Slug.php b/src/Pods/REST/V1/Endpoints/Group_Slug.php new file mode 100644 index 0000000000..2ee11c6790 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Group_Slug.php @@ -0,0 +1,134 @@ + [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Group slug.', 'pods' ), + 'required' => true, + ], + 'include_fields' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include fields (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->get_by_args( 'slug', 'name', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function EDIT_args() { + return [ + 'pod' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Field slug.', 'pods' ), + 'required' => true, + ], + 'new_name' => [ + 'type' => 'string', + 'description' => __( 'The new name of the Group.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Group.', 'pods' ), + ], + 'type' => [ + 'type' => 'string', + 'description' => __( 'The type of the Group.', 'pods' ), + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Group.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function update( WP_REST_Request $request ) { + return $this->update_by_args( 'slug', 'name', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function DELETE_args() { + return [ + 'pod' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Group slug.', 'pods' ), + 'required' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function delete( WP_REST_Request $request ) { + return $this->delete_by_args( 'slug', 'name', $request ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Groups.php b/src/Pods/REST/V1/Endpoints/Groups.php new file mode 100644 index 0000000000..1da5354fab --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Groups.php @@ -0,0 +1,215 @@ + 'query', + 'default' => '', + ]; + + // @todo Handle get/post + + return [ + 'get' => [ + 'parameters' => $this->swaggerize_args( $this->READ_args(), $GET_defaults ), + 'responses' => [ + '200' => [ + 'description' => __( 'Returns all the tickets matching the search criteria.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + 'properties' => [ + 'rest_url' => [ + 'type' => 'string', + 'format' => 'uri', + 'description' => __( 'This results page REST URL.', 'pods' ), + ], + 'total' => [ + 'type' => 'integer', + 'description' => __( 'The total number of results across all pages.', 'pods' ), + ], + 'total_pages' => [ + 'type' => 'integer', + 'description' => __( 'The total number of result pages matching the search criteria.', 'pods' ), + ], + 'tickets' => [ + 'type' => 'array', + 'items' => [ '$ref' => '#/components/schemas/Ticket' ], + ], + ], + ], + ], + ], + ], + '400' => [ + 'description' => __( 'One or more of the specified query variables has a bad format.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '404' => [ + 'description' => __( 'The requested page was not found.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function READ_args() { + return [ + 'return_type' => [ + 'description' => __( 'The type of data to return.', 'pods' ), + 'type' => 'string', + 'default' => 'full', + 'required' => false, + 'enum' => [ + 'full', + 'names', + 'names_ids', + 'ids', + 'key_names', + 'count', + ], + ], + 'types' => [ + 'required' => false, + 'description' => __( 'A list of types to filter by.', 'pods' ), + 'swagger_type' => 'array', + 'items' => [ + 'type' => 'string', + ], + 'collectionFormat' => 'csv', + ], + 'ids' => [ + 'required' => false, + 'description' => __( 'A list of IDs to filter by.', 'pods' ), + 'swagger_type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'collectionFormat' => 'csv', + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of arguments to filter by.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->archive_by_args( $request ); + } + + /** + * Determine whether access to READ is available. + * + * @since 2.8.0 + * + * @return bool Whether access to READ is available. + */ + public function can_read() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function CREATE_args() { + return [ + 'pod_id' => [ + 'type' => 'string', + 'description' => __( 'The Pod ID.', 'pods' ), + 'validate_callback' => [ $this->validator, 'is_pod_id' ], + ], + 'pod' => [ + 'type' => 'string', + 'description' => __( 'The Pod name.', 'pods' ), + 'validate_callback' => [ $this->validator, 'is_pod_slug' ], + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The name of the Group.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Group.', 'pods' ), + 'required' => true, + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Group.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function create( WP_REST_REQUEST $request, $return_id = false ) { + return $this->create_by_args( $request, $return_id ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_create() { + return pods_is_admin( 'pods' ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Pod.php b/src/Pods/REST/V1/Endpoints/Pod.php new file mode 100644 index 0000000000..c962063feb --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Pod.php @@ -0,0 +1,242 @@ + 'query', + 'default' => '', + 'type' => 'string', + ]; + + // @todo Handle get/post/delete + + return [ + 'get' => [ + 'summary' => __( 'Returns a single ticket data.', 'pods' ), + 'parameters' => $this->swaggerize_args( $this->READ_args(), $GET_defaults ), + 'responses' => [ + '200' => [ + 'description' => __( 'Returns the data of the ticket with the specified post ID.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + '$ref' => '#/components/schemas/Ticket', + ], + ], + ], + ], + '400' => [ + 'description' => __( 'The ticket post ID is invalid.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '401' => [ + 'description' => __( 'The ticket with the specified ID is not accessible.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + '404' => [ + 'description' => __( 'A ticket with the specified ID does not exist.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function READ_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Pod ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_id' ], + ], + 'include_fields' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include fields (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + 'include_groups' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include groups (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + 'include_group_fields' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include group fields (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->get_by_args( 'id', 'id', $request ); + } + + /** + * Determine whether access to READ is available. + * + * @since 2.8.0 + * + * @return bool Whether access to READ is available. + */ + public function can_read() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function EDIT_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Pod ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_id' ], + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The new name of the Pod.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Pod.', 'pods' ), + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Pod.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function update( WP_REST_Request $request ) { + if ( ! empty( $request['groups'] ) ) { + $request->set_param( 'groups', null ); + } + + if ( ! empty( $request['fields'] ) ) { + $request->set_param( 'fields', null ); + } + + return $this->update_by_args( 'id', 'id', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_edit() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function DELETE_args() { + return [ + 'id' => [ + 'type' => 'integer', + 'in' => 'path', + 'description' => __( 'The Pod ID.', 'pods' ), + 'required' => true, + 'validate_callback' => [ $this->validator, 'is_pod_id' ], + ], + 'delete_all' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to delete all content for Pod (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function delete( WP_REST_Request $request ) { + return $this->delete_by_args( 'id', 'id', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_delete() { + return pods_is_admin( 'pods' ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Pod_Slug.php b/src/Pods/REST/V1/Endpoints/Pod_Slug.php new file mode 100644 index 0000000000..4b1ca00e72 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Pod_Slug.php @@ -0,0 +1,121 @@ + [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + ], + 'include_fields' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include fields (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + 'include_groups' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to include groups (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->get_by_args( 'slug', 'name', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function EDIT_args() { + return [ + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + ], + 'new_name' => [ + 'type' => 'string', + 'description' => __( 'The new name of the Pod.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Pod.', 'pods' ), + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of additional options to save to the Pod.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function update( WP_REST_Request $request ) { + return $this->update_by_args( 'slug', 'name', $request ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function DELETE_args() { + return [ + 'slug' => [ + 'type' => 'string', + 'in' => 'path', + 'description' => __( 'The Pod slug.', 'pods' ), + 'required' => true, + ], + 'delete_all' => [ + 'type' => 'boolean', + 'description' => __( 'Whether to delete all content for Pod (default: off).', 'pods' ), + 'default' => false, + 'cli_boolean' => true, + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function delete( WP_REST_Request $request ) { + return $this->delete_by_args( 'slug', 'name', $request ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Pods.php b/src/Pods/REST/V1/Endpoints/Pods.php new file mode 100644 index 0000000000..d4de19dbe2 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Pods.php @@ -0,0 +1,274 @@ + 'query', + 'default' => '', + ]; + + // @todo Handle get/post + + return [ + 'get' => [ + 'parameters' => $this->swaggerize_args( $this->READ_args(), $GET_defaults ), + 'responses' => [ + '200' => [ + 'description' => __( 'Returns all the tickets matching the search criteria.', 'pods' ), + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + 'properties' => [ + 'pods' => [ + 'type' => 'array', + 'items' => [ '$ref' => '#/components/schemas/Pod' ], + ], + ], + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function READ_args() { + return [ + 'return_type' => [ + 'description' => __( 'The type of data to return.', 'pods' ), + 'type' => 'string', + 'default' => 'full', + 'required' => false, + 'enum' => [ + 'full', + 'names', + 'ids', + 'count', + ], + ], + 'types' => [ + 'required' => false, + 'description' => __( 'A list of types to filter by.', 'pods' ), + 'swagger_type' => 'array', + 'items' => [ + 'type' => 'string', + ], + 'collectionFormat' => 'csv', + ], + 'ids' => [ + 'required' => false, + 'description' => __( 'A list of IDs to filter by.', 'pods' ), + 'swagger_type' => 'array', + 'items' => [ + 'type' => 'integer', + ], + 'collectionFormat' => 'csv', + ], + 'args' => [ + 'required' => false, + 'description' => __( 'A list of arguments to filter by.', 'pods' ), + 'swagger_type' => 'array', + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function get( WP_REST_Request $request ) { + return $this->archive_by_args( $request ); + } + + /** + * Determine whether access to READ is available. + * + * @since 2.8.0 + * + * @return bool Whether access to READ is available. + */ + public function can_read() { + return pods_is_admin( 'pods' ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function CREATE_args() { + return [ + 'mode' => [ + 'type' => 'string', + 'description' => __( 'The mode for creating the Pod.', 'pods' ), + 'default' => 'create', + 'enum' => [ + 'create', + 'extend', + ], + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The name of the Pod.', 'pods' ), + ], + 'label' => [ + 'type' => 'string', + 'description' => __( 'The plural label of the Pod.', 'pods' ), + ], + 'type' => [ + 'type' => 'string', + 'description' => __( 'The type of the Pod.', 'pods' ), + 'enum' => PodsForm::pod_types_list(), + 'required' => true, + ], + 'storage' => [ + 'type' => 'string', + 'description' => __( 'The storage used for the Pod.', 'pods' ), + 'default' => 'meta', + 'enum' => [ + 'meta', + 'table', + 'none', + ], + ], + 'label_singular' => [ + 'type' => 'string', + 'description' => __( 'The singular label of the Pod.', 'pods' ), + ], + 'menu_name' => [ + 'type' => 'string', + 'description' => __( 'The menu label of the Pod.', 'pods' ), + ], + 'menu_location' => [ + 'type' => 'string', + 'description' => __( 'The menu location of the Pod.', 'pods' ), + ], + ]; + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function create( WP_REST_REQUEST $request, $return_id = false ) { + if ( ! empty( $request['groups'] ) ) { + $request->set_param( 'groups', null ); + } + + if ( ! empty( $request['fields'] ) ) { + $request->set_param( 'fields', null ); + } + + $mode = $request->get_param( 'mode' ); + $type = $request->get_param( 'type' ); + $storage = $request->get_param( 'storage' ); + + if ( 'extend' === $mode ) { + $params = [ + 'create_extend' => 'extend', + 'extend_pod_type' => $type, + 'extend_storage' => $storage, + ]; + + $name = $request->get_param( 'name' ); + + if ( 'post_type' === $params['extend_pod_type'] ) { + $params['extend_post_type'] = $name; + } elseif ( 'taxonomy' === $params['extend_pod_type'] ) { + $params['extend_taxonomy'] = $name; + } elseif ( 'table' === $params['extend_pod_type'] ) { + $params['extend_table'] = $name; + } elseif ( in_array( $params['extend_pod_type'], [ 'pod', 'settings' ], true ) ) { + return new WP_Error( 'rest-object-extend-type-not-supported', __( 'Pod type not supported for extending.', 'pods' ) ); + } + } else { + $params = [ + 'create_extend' => 'create', + 'create_pod_type' => $type, + 'create_storage' => $storage, + 'create_label_plural' => $request->get_param( 'label' ), + 'create_label_singular' => $request->get_param( 'label_singular' ), + 'create_label_menu' => $request->get_param( 'menu_name' ), + 'create_menu_location' => $request->get_param( 'menu_location' ), + ]; + + if ( 'settings' === $params['create_pod_type'] ) { + $params['create_label_title'] = $params['create_label_plural']; + } + + $name = $request->get_param( 'name' ); + + if ( 'settings' === $params['create_pod_type'] ) { + $params['create_setting_name'] = $name; + $params['create_storage'] = 'none'; + } else { + $params['create_name'] = $name; + } + } + + $api = pods_api(); + + $api->display_errors = 'wp_error'; + + $id = $api->add_pod( $params ); + + if ( is_wp_error( $id ) ) { + return $id; + } + + if ( empty( $id ) ) { + return new WP_Error( 'rest-object-not-added', sprintf( __( '%s not added.', 'pods' ), ucwords( $this->object ) ) ); + } + + return $this->get_by_args( [ + 'id' => $id, + ], 'id', null, $return_id ); + } + + /** + * {@inheritdoc} + * + * @since 2.8.0 + */ + public function can_create() { + return pods_is_admin( 'pods' ); + } +} diff --git a/src/Pods/REST/V1/Endpoints/Swagger_Documentation.php b/src/Pods/REST/V1/Endpoints/Swagger_Documentation.php new file mode 100644 index 0000000000..7c1d521d54 --- /dev/null +++ b/src/Pods/REST/V1/Endpoints/Swagger_Documentation.php @@ -0,0 +1,243 @@ +set_current_rest_api_version( $main->get_semantic_version() ); + } + + /** + * Set the current REST API version. + * + * @since 2.8.0 + * + * @param string $current_rest_api_version Current REST API version. + */ + public function set_current_rest_api_version( $current_rest_api_version ) { + $this->current_rest_api_version = $current_rest_api_version; + } + + /** + * Handles GET requests on the endpoint. + * + * @since 2.8.0 + * + * @param WP_REST_Request $request + * + * @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure. + */ + public function get( WP_REST_Request $request ) { + $data = $this->get_documentation(); + + return new WP_REST_Response( $data ); + } + + /** + * Returns an array in the format used by Swagger 2.0. + * + * @since 2.8.0 + * + * @return array An array description of a Swagger supported component. + * + * @link http://swagger.io/ + */ + public function get_documentation() { + /** @var Main $main */ + $main = tribe( 'pods.rest-v1.main' ); + + $documentation = [ + 'openapi' => $this->open_api_version, + 'info' => $this->get_api_info(), + 'servers' => [ + [ + 'url' => $main->get_url(), + ], + ], + 'paths' => $this->get_paths(), + 'components' => [ + 'schemas' => $this->get_definitions(), + ], + ]; + + /** + * Filters the Swagger documentation generated for the REST API. + * + * @since 2.8.0 + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * @param Swagger_Documentation $this This documentation endpoint instance. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'pods_rest_swagger_documentation', $documentation, $this ); + + return $documentation; + } + + /** + * Get the REST API info. + * + * @since 2.8.0 + * + * @return array The REST API info. + */ + protected function get_api_info() { + return [ + 'title' => __( 'Pods REST API', 'pods' ), + 'description' => __( 'Pods REST API allows administration of Pods configurations easily and conveniently.', 'pods' ), + 'version' => $this->current_rest_api_version, + ]; + } + + /** + * Get the REST API paths. + * + * @since 2.8.0 + * + * @return array The REST API paths. + */ + protected function get_paths() { + $paths = []; + + foreach ( $this->documentation_providers as $path => $endpoint ) { + if ( $this === $endpoint ) { + continue; + } + + $paths[ $path ] = $endpoint->get_documentation(); + } + + return $paths; + } + + /** + * Get the list of REST API definitions. + * + * @since 2.8.0 + * + * @return array List of REST API definitions. + */ + protected function get_definitions() { + $definitions = []; + + foreach ( $this->definition_providers as $type => $provider ) { + $definitions[ $type ] = $provider->get_documentation(); + } + + return $definitions; + } + + /** + * Registers a documentation provider for a path. + * + * @since 2.8.0 + * + * @param string $path Documentation path. + * @param Provider_Interface $endpoint Docuemntation endpoint object. + */ + public function register_documentation_provider( $path, Provider_Interface $endpoint ) { + $this->documentation_providers[ $path ] = $endpoint; + } + + /** + * Get list of documentation providers. + * + * @since 2.8.0 + * + * @return Provider_Interface[] List of documentation providers. + */ + public function get_registered_documentation_providers() { + return $this->documentation_providers; + } + + /** + * Registers a documentation provider for a definition. + * + * @since 2.8.0 + * + * @param string $type The documentation provider type. + * @param Provider_Interface $provider The provider interface object. + */ + public function register_definition_provider( $type, Provider_Interface $provider ) { + $this->definition_providers[ $type ] = $provider; + } + + /** + * Get list of definition providers. + * + * @since 2.8.0 + * + * @return Provider_Interface[] List of definition providers. + */ + public function get_registered_definition_providers() { + return $this->definition_providers; + } + + /** + * Returns the content of the `args` array that should be used to register the endpoint + * with the `register_rest_route` function. + * + * @since 2.8.0 + * + * @return array Args to use for READ requests. + */ + public function READ_args() { + return []; + } + + /** + * Get REST API Documentation for the Swagger endpoint. + * + * @since 2.8.0 + * + * @return array REST API Documentation for the Swagger endpoint. + */ + protected function get_own_documentation() { + return [ + 'get' => [ + 'responses' => [ + '200' => [ + 'description' => __( 'Returns the documentation for the Pods REST API in Swagger consumable format.', 'pods' ), + ], + ], + ], + ]; + } +} diff --git a/src/Pods/REST/V1/Main.php b/src/Pods/REST/V1/Main.php new file mode 100644 index 0000000000..13eb6bdd6e --- /dev/null +++ b/src/Pods/REST/V1/Main.php @@ -0,0 +1,96 @@ +get_namespace() . '/' . $this->get_version(); + } + + /** + * Returns the REST API URL prefix that will be appended to the namespace. + * + * The prefix should be in the `/some/path` format. + * + * @since 2.8.0 + * + * @return string + */ + protected function url_prefix() { + return $this->url_prefix; + } + + /** + * {@inheritDoc} + * + * @since 2.8.0 + */ + public function get_reference_url() { + return esc_url( 'https://docs.pods.io/' ); + } + +} diff --git a/src/Pods/REST/V1/Messages.php b/src/Pods/REST/V1/Messages.php new file mode 100644 index 0000000000..804236542e --- /dev/null +++ b/src/Pods/REST/V1/Messages.php @@ -0,0 +1,85 @@ +messages = [ + 'missing-attendee-id' => __( 'The attendee ID is missing from the request', 'pods' ), + 'attendee-not-found' => __( 'The requested post ID does not exist or is not an attendee', 'pods' ), + 'attendee-not-accessible' => __( 'The requested attendee is not accessible', 'pods' ), + 'attendee-check-in-not-found' => __( 'The requested attendee check in is not available', 'pods' ), + 'ticket-not-found' => __( 'The requested ticket post could not be found', 'pods' ), + 'ticket-provider-not-found' => __( 'The ticket provider for the requested ticket is not available', 'pods' ), + 'ticket-post-not-found' => __( 'The post associated with the requested ticket was not found', 'pods' ), + 'ticket-object-not-found' => __( 'The requested ticket object could not be built or found', 'pods' ), + 'ticket-not-accessible' => __( 'The requested ticket is not accessible', 'pods' ), + 'error-global-id-generation' => __( 'The ticket global id could not be generated', 'pods' ), + // this is an internal error, not same as the `ticket-not-found` one + 'error-ticket-post' => __( 'There was a problem while fetching the requested ticket post', 'pods' ), + 'error-attendee-post' => __( 'There was a problem while fetching the requested attendee post', 'pods' ), + // same as WordPress REST API + 'invalid-page-number' => __( 'The page number requested is larger than the number of pages available.', 'default' ), + ]; + } + + /** + * Returns the localized message associated with the slug. + * + * @since 2.8.0 + * + * @param string $message_slug + * + * @return string + */ + public function get_message( $message_slug ) { + if ( isset( $this->messages[ $message_slug ] ) ) { + return $this->messages[ $message_slug ]; + } + + return ''; + } + + /** + * Returns the associative array of all the messages handled by the class. + * + * @since 2.8.0 + * + * @return array An associative array in the `[ => ]` format. + */ + public function get_messages() { + return $this->messages; + } + + /** + * Prefixes a message slug with a common root. + * + * @since 2.8.0 + * + * @param string $message_slug + * + * @return string The prefixed message slug. + */ + public function prefix_message_slug( $message_slug ) { + return $this->message_prefix . $message_slug; + } + +} diff --git a/src/Pods/REST/V1/Post_Repository.php b/src/Pods/REST/V1/Post_Repository.php new file mode 100644 index 0000000000..308977d410 --- /dev/null +++ b/src/Pods/REST/V1/Post_Repository.php @@ -0,0 +1,150 @@ +types_get_map = [ + '_pods_pod' => [ $this, 'get_pod_data' ], + '_pods_group' => [ $this, 'get_group_data' ], + '_pods_field' => [ $this, 'get_field_data' ], + ]; + + $this->messages = $messages ? $messages : tribe( 'pods.rest-v1.messages' ); + } + + /** + * Retrieves an array representation of the object. + * + * @since 2.8.0 + * + * @param int $id The ID. + * @param string $type The type of content. + * @param string $context Context of data. + * + * @return array|WP_Error An array representation of the object or an WP_Error with the error message. + */ + public function get_data( $id, $type = '', $context = 'default' ) { + $object = null; + + if ( empty( $type ) ) { + $object = get_post( $id ); + + if ( ! $object instanceof WP_Post ) { + return []; + } + + $type = $object->post_type; + } + + if ( ! isset( $this->types_get_map[ $type ] ) ) { + return (array) $object; + } + + return call_user_func( $this->types_get_map[ $type ], $id, $object, $context ); + } + + /** + * Get pod data. + * + * @since 2.8.0 + * + * @param int $id The ID. + * @param WP_Post|object $object The object. + * @param string $context The context. + * + * @return array|WP_Error + */ + public function get_pod_data( $id, $object = null, $context = 'default' ) { + if ( null === $object ) { + $object = get_post( $id ); + + if ( ! $object instanceof WP_Post ) { + return new WP_Error( 'pod-not-found', $this->messages->get_message( 'pod-not-found' ), [ 'status' => 404 ] ); + } + } + + // @todo Fill this out. + + return []; + } + + /** + * Get group data. + * + * @since 2.8.0 + * + * @param int $id The ID. + * @param WP_Post|object $object The object. + * @param string $context The context. + * + * @return array|WP_Error + */ + public function get_group_data( $id, $object = null, $context = 'default' ) { + if ( null === $object ) { + $object = get_post( $id ); + + if ( ! $object instanceof WP_Post ) { + return new WP_Error( 'group-not-found', $this->messages->get_message( 'group-not-found' ), [ 'status' => 404 ] ); + } + } + + // @todo Fill this out. + + return []; + } + + /** + * Get field data. + * + * @since 2.8.0 + * + * @param int $id The ID. + * @param WP_Post|object $object The object. + * @param string $context The context. + * + * @return array|WP_Error + */ + public function get_field_data( $id, $object = null, $context = 'default' ) { + if ( null === $object ) { + $object = get_post( $id ); + + if ( ! $object instanceof WP_Post ) { + return new WP_Error( 'group-not-found', $this->messages->get_message( 'group-not-found' ), [ 'status' => 404 ] ); + } + } + + // @todo Fill this out. + + return []; + } +} diff --git a/src/Pods/REST/V1/Service_Provider.php b/src/Pods/REST/V1/Service_Provider.php new file mode 100644 index 0000000000..9c6ddbff2c --- /dev/null +++ b/src/Pods/REST/V1/Service_Provider.php @@ -0,0 +1,433 @@ +container->singleton( 'pods.rest-v1.main', Main::class ); + $this->container->singleton( 'pods.rest-v1.messages', Messages::class ); + $this->container->singleton( 'pods.rest-v1.validator', Base_Validator::class ); + $this->container->singleton( 'pods.rest-v1.repository', Post_Repository::class ); + $this->container->singleton( 'pods.rest-v1.endpoints.documentation', Swagger_Documentation::class, [ 'hook' ] ); + + $messages = tribe( 'pods.rest-v1.messages' ); + $post_repository = tribe( 'pods.rest-v1.repository' ); + $validator = tribe( 'pods.rest-v1.validator' ); + + $this->container->singleton( 'pods.rest-v1.endpoints.pods', new Pods( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.pod', new Pod( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.pod-slug', new Pod_Slug( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.fields', new Fields( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.field', new Field( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.field-slug', new Field_Slug( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.groups', new Groups( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.group', new Group( $messages, $post_repository, $validator ) ); + $this->container->singleton( 'pods.rest-v1.endpoints.group-slug', new Group_Slug( $messages, $post_repository, $validator ) ); + + $this->hooks(); + } + + /** + * Registers the REST API endpoints. + * + * @since 2.8.0 + */ + public function register_endpoints() { + /** @var Main $main */ + $main = tribe( 'pods.rest-v1.main' ); + + $this->namespace = $main->get_pods_route_namespace(); + + $this->register_endpoint_documentation(); + + $this->register_endpoint_pods(); + $this->register_endpoint_pod(); + $this->register_endpoint_pod_slug(); + $this->register_endpoint_fields(); + $this->register_endpoint_field(); + $this->register_endpoint_field_slug(); + $this->register_endpoint_groups(); + $this->register_endpoint_group(); + $this->register_endpoint_group_slug(); + } + + /** + * Builds, registers and returns the Swagger.io documentation provider endpoint. + * + * @since 2.8.0 + * + * @return Swagger_Builder_Interface + */ + protected function register_endpoint_documentation() { + /** @var Swagger_Builder_Interface $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.documentation' ); + + register_rest_route( $this->namespace, '/doc', [ + 'methods' => WP_REST_Server::READABLE, + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => '__return_true', + ] ); + + //$endpoint->register_definition_provider( 'Attendee', new Tribe__Tickets__REST__V1__Documentation__Attendee_Definition_Provider() ); + + $endpoint->register_documentation_provider( '/doc', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Pods + */ + protected function register_endpoint_pods() { + /** @var Pods $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.pods' ); + + register_rest_route( $this->namespace, $endpoint->route, [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::CREATABLE, + 'args' => $endpoint->CREATE_args(), + 'callback' => [ $endpoint, 'create' ], + 'permission_callback' => [ $endpoint, 'can_create' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/pods', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Pod + */ + protected function register_endpoint_pod() { + /** @var Pod $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.pod' ); + + register_rest_route( $this->namespace, sprintf( str_replace( '$d', '$s', $endpoint->route ), '(?P\\d+)' ), [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::EDITABLE, + 'args' => $endpoint->EDIT_args(), + 'callback' => [ $endpoint, 'update' ], + 'permission_callback' => [ $endpoint, 'can_edit' ], + ], + [ + 'methods' => WP_REST_Server::DELETABLE, + 'args' => $endpoint->DELETE_args(), + 'callback' => [ $endpoint, 'delete' ], + 'permission_callback' => [ $endpoint, 'can_delete' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/pods/{id}', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Pod_Slug + */ + protected function register_endpoint_pod_slug() { + /** @var Pod_Slug $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.pod-slug' ); + + register_rest_route( $this->namespace, sprintf( $endpoint->route, '(?P[\w\_\-]+)' ), [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::EDITABLE, + 'args' => $endpoint->EDIT_args(), + 'callback' => [ $endpoint, 'update' ], + 'permission_callback' => [ $endpoint, 'can_edit' ], + ], + [ + 'methods' => WP_REST_Server::DELETABLE, + 'args' => $endpoint->DELETE_args(), + 'callback' => [ $endpoint, 'delete' ], + 'permission_callback' => [ $endpoint, 'can_delete' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/pods/{slug}', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Fields + */ + protected function register_endpoint_fields() { + /** @var Fields $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.fields' ); + + register_rest_route( $this->namespace, $endpoint->route, [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::CREATABLE, + 'args' => $endpoint->CREATE_args(), + 'callback' => [ $endpoint, 'create' ], + 'permission_callback' => [ $endpoint, 'can_create' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/fields', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Field + */ + protected function register_endpoint_field() { + /** @var Field $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.field' ); + + register_rest_route( $this->namespace, sprintf( str_replace( '$d', '$s', $endpoint->route ), '(?P\\d+)' ), [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::EDITABLE, + 'args' => $endpoint->EDIT_args(), + 'callback' => [ $endpoint, 'update' ], + 'permission_callback' => [ $endpoint, 'can_edit' ], + ], + [ + 'methods' => WP_REST_Server::DELETABLE, + 'args' => $endpoint->DELETE_args(), + 'callback' => [ $endpoint, 'delete' ], + 'permission_callback' => [ $endpoint, 'can_delete' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/fields/{id}', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Field_Slug + */ + protected function register_endpoint_field_slug() { + /** @var Field_Slug $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.field-slug' ); + + register_rest_route( $this->namespace, sprintf( $endpoint->route, '(?P[\w\_\-]+)', '(?P[\w\_\-]+)' ), [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::EDITABLE, + 'args' => $endpoint->EDIT_args(), + 'callback' => [ $endpoint, 'update' ], + 'permission_callback' => [ $endpoint, 'can_edit' ], + ], + [ + 'methods' => WP_REST_Server::DELETABLE, + 'args' => $endpoint->DELETE_args(), + 'callback' => [ $endpoint, 'delete' ], + 'permission_callback' => [ $endpoint, 'can_delete' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/fields/{slug}', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Groups + */ + protected function register_endpoint_groups() { + /** @var Groups $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.groups' ); + + register_rest_route( $this->namespace, $endpoint->route, [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::CREATABLE, + 'args' => $endpoint->CREATE_args(), + 'callback' => [ $endpoint, 'create' ], + 'permission_callback' => [ $endpoint, 'can_create' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/groups', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Group + */ + protected function register_endpoint_group() { + /** @var Group $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.group' ); + + register_rest_route( $this->namespace, sprintf( str_replace( '$d', '$s', $endpoint->route ), '(?P\\d+)' ), [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::EDITABLE, + 'args' => $endpoint->EDIT_args(), + 'callback' => [ $endpoint, 'update' ], + 'permission_callback' => [ $endpoint, 'can_edit' ], + ], + [ + 'methods' => WP_REST_Server::DELETABLE, + 'args' => $endpoint->DELETE_args(), + 'callback' => [ $endpoint, 'delete' ], + 'permission_callback' => [ $endpoint, 'can_delete' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/groups/{id}', $endpoint ); + + return $endpoint; + } + + /** + * Registers the REST API endpoint that will handle requests. + * + * @since 2.8.0 + * + * @return Group_Slug + */ + protected function register_endpoint_group_slug() { + /** @var Group_Slug $endpoint */ + $endpoint = tribe( 'pods.rest-v1.endpoints.group-slug' ); + + register_rest_route( $this->namespace, sprintf( $endpoint->route, '(?P[\w\_\-]+)', '(?P[\w\_\-]+)' ), [ + [ + 'methods' => WP_REST_Server::READABLE, + 'args' => $endpoint->READ_args(), + 'callback' => [ $endpoint, 'get' ], + 'permission_callback' => [ $endpoint, 'can_read' ], + ], + [ + 'methods' => WP_REST_Server::EDITABLE, + 'args' => $endpoint->EDIT_args(), + 'callback' => [ $endpoint, 'update' ], + 'permission_callback' => [ $endpoint, 'can_edit' ], + ], + [ + 'methods' => WP_REST_Server::DELETABLE, + 'args' => $endpoint->DELETE_args(), + 'callback' => [ $endpoint, 'delete' ], + 'permission_callback' => [ $endpoint, 'can_delete' ], + ], + ] ); + + tribe( 'pods.rest-v1.endpoints.documentation' )->register_documentation_provider( '/groups/{slug}', $endpoint ); + + return $endpoint; + } + + /** + * Hooks all the methods and actions the class needs. + * + * @since 2.8.0 + */ + protected function hooks() { + add_action( 'rest_api_init', [ $this, 'register_endpoints' ] ); + } +} diff --git a/src/Pods/REST/V1/Validator/Base.php b/src/Pods/REST/V1/Validator/Base.php new file mode 100644 index 0000000000..9e9e13c48d --- /dev/null +++ b/src/Pods/REST/V1/Validator/Base.php @@ -0,0 +1,116 @@ +container->singleton( Permissions::class, Permissions::class ); + $this->container->singleton( Map_Field_Values::class, Map_Field_Values::class ); + $this->container->singleton( WP_Query_Integration::class, WP_Query_Integration::class ); + $this->container->singleton( Static_Cache::class, Static_Cache::class ); + + $this->hooks(); + } + + /** + * Hooks all the methods and actions the class needs. + * + * @since 2.8.0 + */ + protected function hooks() { + add_action( 'init', $this->container->callback( WP_Query_Integration::class, 'hook' ), 20 ); + } +} diff --git a/src/Pods/Static_Cache.php b/src/Pods/Static_Cache.php new file mode 100644 index 0000000000..0b623c82ec --- /dev/null +++ b/src/Pods/Static_Cache.php @@ -0,0 +1,106 @@ +query_vars['suppress_filters'] ) + || ! $query->is_main_query() + || ( + ! $query->is_category() + && ! $query->is_tag() + ) + ) { + return; + } + + $taxonomy = $query->get_queried_object()->taxonomy; + + // Find all CPT that have this taxonomy set. + $api = pods_api(); + + try { + $post_types_to_show = $api->load_pods( [ + 'args' => [ + 'archive_show_in_taxonomies_' . $taxonomy => 1, + ], + 'names' => true, + ] ); + } catch ( Exception $exception ) { + return; + } + + $post_types_to_show = array_keys( $post_types_to_show ); + + $existing_post_types = $query->get( 'post_type' ); + + if ( empty( $existing_post_types ) ) { + $existing_post_types = [ + 'post', + ]; + } elseif ( ! is_array( $existing_post_types ) ) { + $existing_post_types = (array) $existing_post_types; + } + + $post_types_to_show = array_unique( array_merge( $existing_post_types, $post_types_to_show ) ); + + $query->set( 'post_type', $post_types_to_show ); + } + +} diff --git a/src/Pods/Whatsit.php b/src/Pods/Whatsit.php new file mode 100644 index 0000000000..a30a3c8897 --- /dev/null +++ b/src/Pods/Whatsit.php @@ -0,0 +1,1508 @@ + '', + 'storage_type' => 'collection', + 'name' => '', + 'id' => '', + 'parent' => '', + 'group' => '', + 'label' => '', + 'description' => '', + ]; + + /** + * @var Field[]|null + */ + protected $_fields; + + /** + * @var Object_Field[]|null + */ + protected $_object_fields; + + /** + * @var Group[]|null + */ + protected $_groups; + + /** + * @var array|null + */ + protected $_table_info; + + /** + * Whatsit constructor. + * + * @param array $args { + * Object arguments. + * + * @type string $name Object name. + * @type string|int $id Object ID. + * @type string $label Object label. + * @type string $description Object description. + * @type string|int $parent Object parent name or ID. + * @type string|int $group Object group name or ID. + * } + * @todo Define storage per Whatsit. + * + */ + public function __construct( array $args = [] ) { + $this->args['object_type'] = static::$type; + + // Setup the object. + $this->setup( $args ); + } + + /** + * Setup object from a serialized string. + * + * @param string $serialized Serialized representation of the object. + * @param boolean $to_args Return as arguments array. + * + * @return Whatsit|array|null + */ + public static function from_serialized( $serialized, $to_args = false ) { + $object = maybe_unserialize( $serialized ); + + if ( $object instanceof self ) { + if ( $to_args ) { + return $object->get_args(); + } + + return $object; + } + + if ( is_array( $object ) ) { + $called_class = get_called_class(); + + /** @var Whatsit $object */ + $object = new $called_class( $object ); + + if ( $to_args ) { + return $object->get_args(); + } + + return $object; + } + + return null; + } + + /** + * Setup object from a JSON string. + * + * @param string $json JSON representation of the object. + * @param boolean $to_args Return as arguments array. + * + * @return Whatsit|array|null + */ + public static function from_json( $json, $to_args = false ) { + /** @noinspection PhpUsageOfSilenceOperatorInspection */ + $args = @json_decode( $json, true ); + + if ( is_array( $args ) ) { + if ( ! empty( $args['id'] ) ) { + // Check if we already have an object registered and available. + $object = Store::get_instance()->get_object( $args['id'] ); + + if ( $object ) { + if ( $to_args ) { + return $object->get_args(); + } + + return $object; + } + } + + $called_class = get_called_class(); + + /** @var Whatsit $object */ + $object = new $called_class( $args ); + + if ( $to_args ) { + return $object->get_args(); + } + + return $object; + }//end if + + return null; + } + + /** + * Setup object from an array configuration. + * + * @param array $array Array configuration. + * @param boolean $to_args Return as arguments array. + * + * @return Whatsit|array|null + */ + public static function from_array( array $array, $to_args = false ) { + if ( ! empty( $array['id'] ) ) { + // Check if we already have an object registered and available. + $object = Store::get_instance()->get_object( $array['id'] ); + + if ( $object ) { + if ( $to_args ) { + return $object->get_args(); + } + + return $object; + } + } + + $called_class = get_called_class(); + + /** @var Whatsit $object */ + $object = new $called_class( $array ); + + if ( $to_args ) { + return $object->get_args(); + } + + return $object; + } + + /** + * Override var_dump data that is used for debugging with. + * + * @return array Data for debugging with. + */ + public function __debugInfo() { + return [ + 'args' => $this->args, + ]; + } + + /** + * Override __set_state handling to limit it to passing in only $args. + * + * @return self Object with state set. + */ + public static function __set_state( $data ) { + $args = []; + + if ( ! empty( $data['args'] ) ) { + $args = $data['args']; + } + + return new static( $args ); + } + + /** + * On serialization of this object, only include _args. + * + * @return array List of properties to serialize. + */ + public function __sleep() { + // @todo If DB based config, return only name, id, parent, group + // @todo Maybe set up a variable with the custom array and implement Serializable::serialize/unserialize + /* + $this->args = array( + 'object_type' => $this->args['object_type'], + 'name' => $this->args['name'], + 'id' => $this->args['id'], + 'parent' => $this->args['parent'], + 'group' => $this->args['group'], + ); + */ + return [ + 'args', + ]; + } + + /** + * On unserialization of this object, setup the object. + */ + public function __wakeup() { + // Setup the object. + $this->setup(); + } + + /** + * Handle JSON encoding for object. + * + * @return array Object arguments. + */ + public function jsonSerialize() { + return $this->get_args(); + } + + /** + * {@inheritdoc} + */ + public function getArrayCopy() { + return array_values( $this->args ); + } + + /** + * {@inheritdoc} + */ + public function rewind() { + $this->position = 0; + } + + /** + * {@inheritdoc} + */ + public function current() { + $args = $this->getArrayCopy(); + + return $args[ $this->position ]; + } + + /** + * {@inheritdoc} + */ + public function key() { + return $this->position; + } + + /** + * {@inheritdoc} + */ + public function next() { + $this->position ++; + } + + /** + * {@inheritdoc} + */ + public function valid() { + $args = $this->getArrayCopy(); + + return isset( $args[ $this->position ] ); + } + + /** + * On cast to string, return object identifier. + * + * @return string Object identifier. + */ + public function __toString() { + return $this->get_identifier(); + } + + /** + * Check if offset exists. + * + * @param mixed $offset Offset name. + * + * @return bool Whether the offset exists. + */ + public function offsetExists( $offset ) { + return $this->__isset( $offset ); + } + + /** + * Get offset value. + * + * @param mixed $offset Offset name. + * + * @return mixed|null Offset value, or null if not set. + */ + public function &offsetGet( $offset ) { + // We fake the pass by reference to avoid PHP errors for backcompat. + $value = $this->__get( $offset ); + + return $value; + } + + /** + * Set offset value. + * + * @param mixed $offset Offset name. + * @param mixed $value Offset value. + */ + public function offsetSet( $offset, $value ) { + if ( null === $offset ) { + // Do not allow $object[] additions. + return; + } + + $this->__set( $offset, $value ); + } + + /** + * Unset offset value. + * + * @param mixed $offset Offset name. + */ + public function offsetUnset( $offset ) { + $this->__unset( $offset ); + } + + /** + * Check if offset exists. + * + * @param mixed $offset Offset name. + * + * @return bool Whether the offset exists. + */ + public function __isset( $offset ) { + if ( is_int( $offset ) ) { + $args = $this->getArrayCopy(); + + return isset( $args[ $offset ] ); + } + + $special_args = [ + 'fields' => 'get_fields', + 'object_fields' => 'get_object_fields', + 'groups' => 'get_groups', + 'table_info' => 'get_table_info', + 'options' => 'get_args', + ]; + + if ( isset( $special_args[ $offset ] ) ) { + return true; + } + + $value = $this->get_arg( $offset, null ); + + return ( null !== $value ); + } + + /** + * Get offset value. + * + * @param mixed $offset Offset name. + * + * @return mixed|null Offset value, or null if not set. + */ + public function __get( $offset ) { + if ( is_int( $offset ) ) { + $args = $this->getArrayCopy(); + + return isset( $args[ $offset ] ); + } + + return $this->get_arg( $offset ); + } + + /** + * Set offset value. + * + * @param mixed $offset Offset name. + * @param mixed $value Offset value. + */ + public function __set( $offset, $value ) { + $this->set_arg( $offset, $value ); + } + + /** + * Unset offset value. + * + * @param mixed $offset Offset name. + */ + public function __unset( $offset ) { + $this->set_arg( $offset, null ); + } + + /** + * Setup object. + * + * @param array $args { + * Object arguments. + * + * @type string $name Object name. + * @type string|int $id Object ID. + * @type string $label Object label. + * @type string $description Object description. + * @type string|int $parent Object parent name or ID. + * @type string|int $group Object group name or ID. + * } + */ + public function setup( array $args = [] ) { + if ( empty( $args ) ) { + $args = $this->get_args(); + } + + $this->_fields = null; + $this->_object_fields = null; + $this->_groups = null; + $this->_table_info = null; + + $defaults = [ + 'object_type' => $this->get_arg( 'object_type' ), + 'storage_type' => $this->get_arg( 'storage_type', 'collection' ), + 'name' => '', + 'id' => '', + 'parent' => '', + 'group' => '', + 'label' => '', + 'description' => '', + ]; + + $args = array_merge( $defaults, $args ); + + // Reset arguments. + $this->args = $defaults; + + foreach ( $args as $arg => $value ) { + $this->set_arg( $arg, $value ); + } + } + + /** + * Set the arguments for the object. + * + * @param array|Whatsit $args List of object arguments to set. + * @param bool $replace Whether to replace the argument if it was already set. + * + * @return self The object. + */ + public function set_args( $args, $replace = true ) { + if ( $args instanceof self ) { + $args = $args->get_args(); + } + + // Invalid arguments received. + if ( ! is_array( $args ) ) { + return $this; + } + + // Set up the options if they were provided. + if ( isset( $args['options'] ) ) { + $args = array_merge( $args['options'], $args ); + + unset( $args['options'] ); + } + + foreach ( $args as $arg => $value ) { + // Skip arguments if we are not replacing them but they are already set. + if ( + ! $replace + && ! empty( $this->args[ $arg ] ) + && '' !== $this->args[ $arg ] + ) { + continue; + } + + $this->set_arg( $arg, $value ); + } + + return $this; + } + + /** + * Get object argument value. + * + * @param string $arg Argument name. + * @param mixed|null $default Default to use if not set. + * @param bool $strict Whether to check only normal arguments and not special arguments. + * + * @return null|mixed Argument value, or null if not set. + */ + public function get_arg( $arg, $default = null, $strict = false ) { + $arg = (string) $arg; + + $special_args = [ + 'identifier' => 'get_identifier', + 'label' => 'get_label', + 'description' => 'get_description', + 'fields' => 'get_fields', + 'object_fields' => 'get_object_fields', + 'all_fields' => 'get_all_fields', + 'groups' => 'get_groups', + 'table_info' => 'get_table_info', + 'options' => 'get_args', + ]; + + if ( isset( $special_args[ $arg ] ) ) { + return $this->{$special_args[ $arg ]}(); + } + + // Enforce lowercase 'id' argument usage. + if ( 'ID' === $arg ) { + $arg = 'id'; + } + + if ( ! isset( $this->args[ $arg ] ) ) { + // Maybe only return the default if we need a strict argument. + if ( $strict ) { + return $default; + } + + $table_info_fields = [ + 'object_name', + 'object_hierarchical', + 'table', + 'meta_table', + 'pod_table', + 'field_id', + 'field_index', + 'field_slug', + 'field_type', + 'field_parent', + 'field_parent_select', + 'meta_field_id', + 'meta_field_index', + 'meta_field_value', + 'pod_field_id', + 'pod_field_index', + 'pod_field_slug', + 'pod_field_parent', + 'join', + 'where', + 'where_default', + 'orderby', + 'recurse', + ]; + + if ( in_array( $arg, $table_info_fields, true ) ) { + $table_info = $this->get_table_info(); + + if ( isset( $table_info[ $arg ] ) ) { + return $table_info[ $arg ]; + } + } + + return $default; + }//end if + + return $this->args[ $arg ]; + } + + /** + * Set object argument. + * + * @param string $arg Argument name. + * @param mixed $value Argument value. + */ + public function set_arg( $arg, $value ) { + $arg = (string) $arg; + + $reserved = [ + 'object_type', + 'storage_type', + 'fields', + 'object_fields', + 'groups', + 'table_info', + 'name', + 'id', + 'parent', + 'group', + 'label', + 'description', + ]; + + $read_only = [ + 'object_type', + 'fields', + 'object_fields', + 'groups', + 'table_info', + ]; + + if ( 'options' === $arg && is_array( $value ) ) { + foreach ( $value as $real_arg => $real_value ) { + $this->set_arg( $real_arg, $real_value ); + } + + return; + } + + if ( in_array( $arg, $reserved, true ) ) { + if ( in_array( $arg, $read_only, true ) ) { + return; + } + + if ( is_string( $value ) ) { + $value = trim( $value ); + } + + $empty_values = [ + null, + 0, + '0', + ]; + + if ( in_array( $value, $empty_values, true ) ) { + $value = ''; + } + } + + $this->args[ $arg ] = $value; + } + + /** + * Override table info when it needs to be set, for fields for example. + * + * @since 2.8.0 + * + * @param array $table_info The table information to be referenced by this object. + */ + public function set_table_info( $table_info ) { + $this->_table_info = $table_info; + } + + /** + * Check whether the object is valid. + * + * @return bool Whether the object is valid. + */ + public function is_valid() { + if ( $this->get_name() ) { + return true; + } + + return false; + } + + /** + * Get object identifier from arguments. + * + * @param array $args Object arguments. + * + * @return string|null Object identifier or if invalid object. + */ + public static function get_identifier_from_args( array $args ) { + if ( empty( $args['object_type'] ) ) { + return null; + } + + $parts = [ + $args['object_type'], + ]; + + if ( isset( $args['parent'] ) && 0 < strlen( $args['parent'] ) ) { + $parts[] = $args['parent']; + } + + if ( isset( $args['name'] ) && 0 < strlen( $args['name'] ) ) { + $parts[] = $args['name']; + } + + return implode( '/', $parts ); + } + + /** + * Get object identifier. + * + * @return string Object identifier. + */ + public function get_identifier() { + return self::get_identifier_from_args( $this->get_args() ); + } + + /** + * Get object label. + * + * @return string Object label. + */ + public function get_label() { + $label = ''; + + if ( isset( $this->args['label'] ) ) { + $label = $this->args['label']; + } + + /** + * Allow filtering the object label. + * + * @since 2.8.0 + * + * @param string $label The object label. + * @param Whatsit $object The object. + */ + return apply_filters( 'pods_whatsit_get_label', $label, $this ); + } + + /** + * Get object description. + * + * @return string Object description. + */ + public function get_description() { + $description = ''; + + if ( isset( $this->args['description'] ) ) { + $description = $this->args['description']; + } + + /** + * Allow filtering the object description. + * + * @since 2.8.0 + * + * @param string $description The object description. + * @param Whatsit $object The object. + */ + return apply_filters( 'pods_whatsit_get_description', $description, $this ); + } + + /** + * Get list of object arguments. + * + * @return arra List of object arguments. + */ + public function get_args() { + return $this->args; + } + + /** + * Get list of clean object arguments. + * + * @return array List of clean object arguments. + */ + public function get_clean_args() { + $args = $this->args; + + $excluded_args = [ + 'object_type', + 'storage_type', + 'parent', + 'group', + ]; + + foreach ( $excluded_args as $excluded_arg ) { + if ( isset( $args[ $excluded_arg ] ) ) { + unset( $args[ $excluded_arg ] ); + } + } + + return $args; + } + + /** + * Get object parent. + * + * @return Whatsit|null Object parent, or null if not set. + */ + public function get_parent_object() { + $parent = $this->get_parent(); + + if ( $parent ) { + $parent = Store::get_instance()->get_object( $parent ); + } + + return $parent; + } + + /** + * Get object group. + * + * @return Whatsit|null Object group, or null if not set. + */ + public function get_group_object() { + $group = $this->get_group(); + + if ( $group ) { + $group = Store::get_instance()->get_object( $group ); + + if ( $group ) { + $this->set_arg( 'group', $group->get_identifier() ); + } + } + + return $group; + } + + /** + * Fetch field from object with no traversal support. + * + * @param string $field_name Field name. + * @param bool $load_all Whether to load all fields when getting this field. + * + * @return Field|null Field object, or null if object not found. + */ + public function fetch_field( $field_name, $load_all = true ) { + $get_fields_args = []; + + if ( ! $load_all ) { + $get_fields_args = [ + 'name' => $field_name, + ]; + } + + $fields = $this->get_fields( $get_fields_args ); + + $field = null; + + if ( isset( $fields[ $field_name ] ) ) { + $field = $fields[ $field_name ]; + } else { + $object_fields = $this->get_object_fields(); + + if ( isset( $object_fields[ $field_name ] ) ) { + $field = $object_fields[ $field_name ]; + } else { + foreach ( $fields as $the_field ) { + if ( ! empty( $the_field['alias'] ) && in_array( $field_name, $the_field['alias'], true ) ) { + $field = $the_field; + + break; + } + } + + if ( ! $field && isset( $object_fields ) ) { + foreach ( $object_fields as $the_field ) { + if ( ! empty( $the_field['alias'] ) && in_array( $field_name, $the_field['alias'], true ) ) { + $field = $the_field; + + break; + } + } + } + } + } + + if ( ! $field instanceof Field ) { + return null; + } + + return $field; + } + + /** + * Get field from object with traversal support. + * + * @param string $field_name Field name. + * @param null|string $arg Argument name. + * @param bool $load_all Whether to load all fields when getting this field. + * + * @return Field|mixed|null Field object, argument value, or null if object not found. + */ + public function get_field( $field_name, $arg = null, $load_all = true ) { + $fields_to_traverse = explode( '.', $field_name ); + $fields_to_traverse = array_filter( $fields_to_traverse ); + + $total_fields_to_traverse = count( $fields_to_traverse ); + + $field = null; + + /** @var Whatsit $whatsit */ + $whatsit = $this; + + for ( $f = 0; $f < $total_fields_to_traverse; $f ++ ) { + $field_to_traverse = $fields_to_traverse[ $f ]; + + $field = $whatsit->fetch_field( $field_to_traverse, $load_all ); + + // Check if there are more fields to traverse. + if ( ( $f + 1 ) === $total_fields_to_traverse ) { + break; + } + + // Check if the field is traversable. + if ( ! $field instanceof Field ) { + $field = null; + + break; + } + + // Fill in the next object data. + $whatsit = $field->get_related_object(); + + // Check if the related object exists. + if ( ! $whatsit instanceof Whatsit ) { + $field = null; + + break; + } + } + + if ( ! $field instanceof Field ) { + return null; + } + + if ( null !== $arg ) { + return $field->get_arg( $arg ); + } + + return $field; + } + + /** + * Get fields for object. + * + * @param array $args List of arguments to filter by. + * + * @return Field[] List of field objects. + */ + public function get_fields( array $args = [] ) { + if ( [] === $this->_fields ) { + return []; + } + + $object_collection = Store::get_instance(); + + $has_custom_args = ! empty( $args ); + + if ( null !== $this->_fields && ! $has_custom_args ) { + $objects = array_map( [ $object_collection, 'get_object' ], $this->_fields ); + $objects = array_filter( $objects ); + + $names = wp_list_pluck( $objects, 'name' ); + + return array_combine( $names, $objects ); + } + + $filtered_args = [ + 'parent' => $this->get_id(), + 'parent_id' => $this->get_id(), + 'parent_name' => $this->get_name(), + 'parent_identifier' => $this->get_identifier(), + ]; + + if ( empty( $filtered_args['parent_id'] ) ) { + $filtered_args['bypass_post_type_find'] = true; + } + + $filtered_args = array_filter( $filtered_args ); + + $args = array_merge( [ + 'orderby' => 'menu_order title', + 'order' => 'ASC', + ], $filtered_args, $args ); + + try { + $api = pods_api(); + + if ( ! empty( $args['object_type'] ) ) { + $objects = $api->_load_objects( $args ); + } else { + $objects = $api->load_fields( $args ); + } + } catch ( Exception $exception ) { + $objects = []; + } + + if ( ! $has_custom_args ) { + $this->_fields = wp_list_pluck( $objects, 'identifier' ); + } + + return $objects; + } + + /** + * Get object fields for object. + * + * @return Object_Field[] List of object field objects. + */ + public function get_object_fields() { + return []; + } + + /** + * Get all fields for object. + * + * @return Field[] List of field objects. + */ + public function get_all_fields() { + return array_merge( $this->get_fields(), $this->get_object_fields() ); + } + + /** + * Determine whether the object has fields. + * + * @param array $args List of arguments to filter by. + * + * @return bool Whether the object has fields. + */ + public function has_fields( array $args = [] ) { + $count = $this->count_fields( $args ); + + return 0 < $count; + } + + /** + * Count the number of fields the object has. + * + * @param array $args List of arguments to filter by. + * + * @return int The number of fields the object has. + */ + public function count_fields( array $args = [] ) { + if ( [] === $this->_fields ) { + return 0; + } + + $has_custom_args = ! empty( $args ); + + if ( null !== $this->_fields && ! $has_custom_args ) { + return count( $this->_fields ); + } + + $filtered_args = [ + 'parent' => $this->get_id(), + 'parent_id' => $this->get_id(), + 'parent_name' => $this->get_name(), + 'parent_identifier' => $this->get_identifier(), + ]; + + if ( empty( $filtered_args['parent_id'] ) ) { + $filtered_args['bypass_post_type_find'] = true; + } + + $filtered_args = array_filter( $filtered_args ); + + $args = array_merge( $filtered_args, $args ); + + // Enforce argument. + $args['count'] = true; + + try { + $api = pods_api(); + + if ( ! empty( $args['object_type'] ) ) { + $total_objects = $api->_load_objects( $args ); + } else { + $total_objects = $api->load_fields( $args ); + } + } catch ( Exception $exception ) { + $total_objects = 0; + } + + return $total_objects; + } + + /** + * Determine whether the object has object fields. + * + * @return bool Whether the object has object fields. + */ + public function has_object_fields() { + $count = $this->count_object_fields(); + + return 0 < $count; + } + + /** + * Count the number of object fields the object has. + * + * @return int The number of object fields the object has. + */ + public function count_object_fields() { + return 0; + } + + /** + * Get groups for object. + * + * @param array $args List of arguments to filter by. + * + * @return Group[] List of group objects. + */ + public function get_groups( array $args = [] ) { + if ( [] === $this->_groups ) { + return []; + } + + $object_collection = Store::get_instance(); + + $has_custom_args = ! empty( $args ); + + if ( null !== $this->_groups && ! $has_custom_args ) { + $objects = array_map( [ $object_collection, 'get_object' ], $this->_groups ); + $objects = array_filter( $objects ); + + $names = wp_list_pluck( $objects, 'name' ); + + return array_combine( $names, $objects ); + } + + $filtered_args = [ + 'parent' => $this->get_id(), + 'parent_id' => $this->get_id(), + 'parent_name' => $this->get_name(), + 'parent_identifier' => $this->get_identifier(), + ]; + + if ( empty( $filtered_args['parent_id'] ) ) { + $filtered_args['bypass_post_type_find'] = true; + } + + $filtered_args = array_filter( $filtered_args ); + + $args = array_merge( [ + 'orderby' => 'menu_order title', + 'order' => 'ASC', + ], $filtered_args, $args ); + + try { + $api = pods_api(); + + if ( ! empty( $args['object_type'] ) ) { + $objects = $api->_load_objects( $args ); + } else { + $objects = $api->load_groups( $args ); + } + } catch ( Exception $exception ) { + $objects = []; + } + + if ( ! $has_custom_args ) { + $this->_groups = wp_list_pluck( $objects, 'identifier' ); + } + + return $objects; + } + + /** + * Determine whether the object has groups. + * + * @param array $args List of arguments to filter by. + * + * @return bool Whether the object has groups. + */ + public function has_groups( array $args = [] ) { + $count = $this->count_groups( $args ); + + return 0 < $count; + } + + /** + * Count the number of groups the object has. + * + * @param array $args List of arguments to filter by. + * + * @return int The number of groups the object has. + */ + public function count_groups( array $args = [] ) { + if ( [] === $this->_groups ) { + return 0; + } + + $has_custom_args = ! empty( $args ); + + if ( null !== $this->_groups && ! $has_custom_args ) { + return $this->_groups; + } + + $filtered_args = [ + 'parent' => $this->get_id(), + 'parent_id' => $this->get_id(), + 'parent_name' => $this->get_name(), + 'parent_identifier' => $this->get_identifier(), + ]; + + if ( empty( $filtered_args['parent_id'] ) ) { + $filtered_args['bypass_post_type_find'] = true; + } + + $filtered_args = array_filter( $filtered_args ); + + $args = array_merge( $filtered_args, $args ); + + // Enforce argument. + $args['count'] = true; + + try { + $api = pods_api(); + + if ( ! empty( $args['object_type'] ) ) { + $total_objects = $api->_load_objects( $args ); + } else { + $total_objects = $api->load_groups( $args ); + } + } catch ( Exception $exception ) { + $total_objects = 0; + } + + return $total_objects; + } + + /** + * Get table information for object. + * + * @return array Table information for object. + */ + public function get_table_info() { + if ( null !== $this->_table_info ) { + return $this->_table_info; + } + + return []; + } + + /** + * Get table name for object. + * + * @return string|null Table name for object or null if not set. + */ + public function get_table_name() { + $table_info = $this->get_table_info(); + + if ( ! empty( $table_info['table'] ) ) { + return $table_info['table']; + } + + return null; + } + + /** + * Get the full data from the object. + * + * @param array $args List of arguments. + * + * @return array Full data from the object. + */ + public function export( array $args = [] ) { + $defaults = [ + 'include_groups' => true, + 'include_group_fields' => true, + 'include_fields' => true, + 'include_field_data' => false, + 'include_object_fields' => false, + 'include_table_info' => false, + 'build_default_group' => false, + 'assoc_keys' => false, + ]; + + $args = array_merge( $defaults, $args ); + + $data = $this->get_args(); + + if ( $args['include_groups'] ) { + $data['groups'] = $this->get_export_for_items( $this->get_groups(), [ + 'include_groups' => false, + 'include_fields' => $args['include_group_fields'], + 'include_field_data' => $args['include_field_data'], + 'assoc_keys' => $args['assoc_keys'], + ] ); + + // If there are no groups, see if we need to build the default one. + if ( $args['build_default_group'] && empty( $data['groups'] ) ) { + $fields = []; + + if ( $args['include_group_fields'] ) { + $fields = $this->get_args_for_items( $this->get_fields(), [ + 'include_field_data' => $args['include_field_data'], + ] ); + + if ( ! $args['assoc_keys'] ) { + $fields = array_values( $fields ); + } + } + + /** + * Filter the title of the Pods Metabox used in the post editor. + * + * @since unknown + * + * @param string $title The title to use, default is 'More Fields'. + * @param Whatsit $pod Current Pods Object. + * @param array $fields Array of fields that will go in the metabox. + * @param string $type The type of Pod. + * @param string $name Name of the Pod. + */ + $group_title = apply_filters( 'pods_meta_default_box_title', __( 'More Fields', 'pods' ), $this, $fields, $this->get_type(), $this->get_name() ); + + $group_name = sanitize_key( pods_js_name( sanitize_title( $group_title ) ) ); + + $data['groups'][ $group_name ] = [ + 'name' => $group_name, + 'label' => $group_title, + 'fields' => $fields, + ]; + } + + if ( ! $args['assoc_keys'] ) { + $data['groups'] = array_values( $data['groups'] ); + } + } + + if ( $args['include_fields'] ) { + $data['fields'] = $this->get_args_for_items( $this->get_fields(), [ + 'include_field_data' => $args['include_field_data'], + ] ); + + if ( ! $args['assoc_keys'] ) { + $data['fields'] = array_values( $data['fields'] ); + } + } + + if ( $args['include_object_fields'] ) { + $data['object_fields'] = $this->get_args_for_items( $this->get_object_fields() ); + + if ( ! $args['assoc_keys'] ) { + $data['object_fields'] = array_values( $data['object_fields'] ); + } + } + + if ( $args['include_table_info'] ) { + $data['table_info'] = $this->get_table_info(); + } + + return $data; + } + + /** + * Get args for items in an array. + * + * @since 2.8.0 + * + * @param Whatsit[] $items List of items. + * @param array $args List of arguments to customize what is returned. + * + * @return array List of item args. + */ + protected function get_args_for_items( array $items, array $args = [] ) { + return array_map( static function ( $object ) use ( $args ) { + /** @var Whatsit $object */ + $item_args = $object->get_args(); + + // Include related field data if needed. + if ( ! empty( $args['include_field_data'] ) ) { + /** @var Whatsit\Field $object */ + $related_data = $object->get_related_object_data(); + + if ( is_array( $related_data ) ) { + $item_args['data'] = $related_data; + } + } + + return $item_args; + }, $items ); + } + + /** + * Get export for items in an array. + * + * @since 2.8.0 + * + * @param Whatsit[] $items List of items. + * @param array $args List of export arguments. + * + * @return array List of item exports. + */ + protected function get_export_for_items( array $items, array $args = [] ) { + return array_map( static function ( $object ) use ( $args ) { + /** @var Whatsit $object */ + return $object->export( $args ); + }, $items ); + } + + /** + * Call magic methods. + * + * @param string $name Method name. + * @param array $arguments Method arguments. + * + * @return mixed|null + */ + public function __call( $name, $arguments ) { + $object = null; + $method = null; + + // Handle parent method calls. + if ( 0 === strpos( $name, 'get_parent_' ) ) { + $object = $this->get_parent_object(); + + $method = explode( 'get_parent_', $name ); + $method = 'get_' . $method[1]; + } + + // Handle group method calls. + if ( 0 === strpos( $name, 'get_group_' ) ) { + $object = $this->get_group_object(); + + $method = explode( 'get_group_', $name ); + $method = 'get_' . $method[1]; + } + + if ( $object && $method ) { + return call_user_func_array( [ $object, $method ], $arguments ); + } + + // Handle arg method calls. + if ( 0 === strpos( $name, 'get_' ) ) { + $arg = explode( 'get_', $name ); + $arg = $arg[1]; + + $supported_args = [ + 'object_type', + 'storage_type', + 'name', + 'id', + 'parent', + 'group', + 'label', + 'description', + 'type', + ]; + + $value = $this->get_arg( $arg ); + + if ( ! empty( $value ) && in_array( $arg, $supported_args, true ) ) { + return $value; + } + + return null; + }//end if + + return null; + } + + /** + * Flush object of cached child data. + */ + public function flush() { + $this->_fields = null; + $this->_groups = null; + $this->_object_fields = null; + $this->_table_info = null; + } + +} diff --git a/src/Pods/Whatsit/Block.php b/src/Pods/Whatsit/Block.php new file mode 100644 index 0000000000..bb37f7ba26 --- /dev/null +++ b/src/Pods/Whatsit/Block.php @@ -0,0 +1,333 @@ +get_arg( 'namespace', 'pods' ); + $name = $this->get_arg( 'slug', $this->get_arg( 'name' ) ); + $category = $this->get_arg( 'category', 'layout' ); + + // Blocks are only allowed A-Z0-9- characters, no underscores. + $namespace = str_replace( '_', '-', sanitize_title_with_dashes( $namespace ) ); + $name = str_replace( '_', '-', sanitize_title_with_dashes( $name ) ); + $category = str_replace( '_', '-', sanitize_title_with_dashes( $category ) ); + + $block_args = [ + 'blockName' => $namespace . '/' . $name, + 'blockGroupLabel' => $this->get_arg( 'group_label', __( 'Options', 'pods' ) ), + 'title' => $this->get_arg( 'title', $this->get_arg( 'label' ) ), + 'description' => $this->get_arg( 'description' ), + 'renderType' => $this->get_arg( 'renderType', $this->get_arg( 'render_type', 'js' ) ), + 'category' => $category, + 'icon' => $this->get_arg( 'icon', 'align-right' ), + 'keywords' => Tribe__Utils__Array::list_to_array( $this->get_arg( 'keywords', 'pods' ) ), + 'supports' => $this->get_arg( 'supports', [] ), + 'editor_script' => $this->get_arg( 'editor_script', 'pods-blocks-api' ), + 'editor_style' => $this->get_arg( 'editor_style' ), + 'script' => $this->get_arg( 'script' ), + 'style' => $this->get_arg( 'style' ), + 'enqueue_script' => $this->get_arg( 'enqueue_script' ), + 'enqueue_style' => $this->get_arg( 'enqueue_style' ), + 'enqueue_assets' => $this->get_arg( 'enqueue_assets' ), + 'uses_context' => $this->get_arg( 'usesContext', $this->get_arg( 'uses_context', [] ) ), + 'provides_context' => $this->get_arg( 'providesContext', $this->get_arg( 'provides_context', [] ) ), + 'fields' => $this->get_block_fields(), + 'attributes' => $this->get_arg( 'attributes', [] ), + 'transforms' => $this->get_arg( 'transforms', [] ), + ]; + + $default_supports = [ + 'html' => false, + // Extra block controls. + 'align' => true, + 'alignWide' => true, + 'anchor' => true, + 'customClassName' => true, + // Block functionality. + 'inserter' => true, + 'multiple' => true, + 'reusable' => true, + // Experimental options. + '__experimentalColor' => true, + '__experimentalFontSize' => true, + // Experimental options not yet confirmed working. + '__experimentalPadding' => true, + '__experimentalLineHeight' => true, + // Custom Pods functionality. + 'jsx' => false, + ]; + + $block_args['supports'] = array_merge( $default_supports, $block_args['supports'] ); + + // Custom supports handling for attributes. + $custom_supports = [ + 'className' => 'string', + 'align' => 'string', + 'anchor' => 'string', + ]; + + // Experimental supports handling for attributes. + $experimental_supports = [ + '__experimentalColor' => [ + 'textColor' => 'string', + 'backgroundColor' => 'string', + ], + '__experimentalFontSize' => [ + 'fontSize' => 'string', + ], + '__experimentalPadding' => [ + 'style' => 'string', + ], + ]; + + foreach ( $custom_supports as $support => $attribute_type ) { + if ( empty( $block_args['supports'][ $support ] ) ) { + continue; + } + + $block_args['attributes'][ $support ] = [ + 'type' => $attribute_type, + ]; + } + + foreach ( $experimental_supports as $support => $support_attributes ) { + if ( empty( $block_args['supports'][ $support ] ) ) { + continue; + } + + foreach ( $support_attributes as $attribute_key => $attribute_type ) { + $block_args['attributes'][ $attribute_key ] = [ + 'type' => $attribute_type, + ]; + } + } + + // @todo Look into supporting example. + // @todo Look into supporting variations. + + foreach ( $block_args['fields'] as $field ) { + if ( ! isset( $field['attributeOptions'] ) ) { + continue; + } + + $block_args['attributes'][ $field['name'] ] = $field['attributeOptions']; + } + + if ( 'js' === $block_args['renderType'] ) { + $block_args['renderTemplate'] = $this->get_arg( 'render_template', $this->get_arg( 'renderTemplate', __( 'No block preview is available', 'pods' ) ) ); + } elseif ( 'php' === $block_args['renderType'] ) { + $block_args['render_callback'] = [ $this, 'render' ]; + $block_args['render_custom_callback'] = $this->get_arg( 'render_callback' ); + $block_args['render_template_path'] = $this->get_arg( 'render_template', $this->get_arg( 'render_template_path' ) ); + } + + $other_args = (array) $this->get_arg( 'raw_args', [] ); + + if ( $other_args ) { + $block_args = array_merge( $block_args, $other_args ); + } + + return $block_args; + } + + /** + * Render the template for the block. + * + * @since 2.8.0 + * + * @param array $attributes The block instance argument values. + * @param string $content The block inner content. + * @param WP_Block|null $block_obj The block object. + * + * @return string The HTML render for the block. + */ + public function render( $attributes, $content, $block_obj = null ) { + $block_config = $block_obj ? $block_obj->block_type : []; + $block_name = pods_v( 'name', $block_config, wp_generate_password( 12, false ), true ); + $enqueue_style = pods_v( 'enqueue_style', $block_config ); + $enqueue_script = pods_v( 'enqueue_script', $block_config ); + $enqueue_assets_callback = pods_v( 'enqueue_assets', $block_config ); + $template_path = pods_v( 'render_template_path', $block_config ); + $render_callback = pods_v( 'render_custom_callback', $block_config ); + + $handle = 'block-' . pods_create_slug( $block_name ); + + // Maybe enqueue the style. + if ( $enqueue_style ) { + wp_enqueue_style( $handle, $enqueue_style ); + } + + // Maybe enqueue the script. + if ( $enqueue_script ) { + wp_enqueue_script( $handle, $enqueue_script, [], false, true ); + } + + // Maybe run the enqueue assets callback. + if ( $enqueue_assets_callback && is_callable( $enqueue_assets_callback ) ) { + $enqueue_assets_callback( $block_config ); + } + + // Handle custom context overrides from editor. + if ( + ! empty( $_GET['post_id'] ) + && ! empty( $_GET['podsContext'] ) + && wp_is_json_request() + && did_action( 'rest_api_init' ) + ) { + $block_obj->context = array_merge( $block_obj->context, (array) $_GET['podsContext'] ); + } + + // Render block from callback. + if ( $render_callback && is_callable( $render_callback ) ) { + return $render_callback( $attributes, $content, $block_obj ); + } + + // Render block from template. + if ( $template_path ) { + return $this->render_template( $template_path, $attributes, $content, $block_obj ); + } + + return ''; + } + + /** + * Render the template for the block. + * + * @since 2.8.0 + * + * @param string $template_path The block render template path. + * @param array $attributes The block instance argument values. + * @param string $content The block inner content. + * @param WP_Block|null $block_obj The block object. + * + * @return string The HTML render for the block. + */ + public function render_template( $template_path, $attributes, $content, $block_obj = null ) { + /** + * Allow filtering of the block render template path. + * + * @since 2.8.0 + * + * @param string $template_path The block render template path. + * @param array $attributes The block instance argument values. + * @param string $content The block inner content. + * @param WP_Block|null $block_obj The block object. + */ + $template_path = apply_filters( 'pods_block_render_template_path', $template_path, $attributes, $content, $block_obj ); + + if ( empty( $template_path ) ) { + return ''; + } + + $render = pods_view( $template_path, compact( 'attributes', 'content', 'block_obj' ), false, 'cache', true ); + + // Avoid regex issues with $ capture groups. + $content = str_replace( '$', '\$', $content ); + + // Replace the placeholder with the real deal. + $render = preg_replace( '//', $content, $render ); + + /** + * Allow filtering of the block render HTML. + * + * @since 2.8.0 + * + * @param string $render The HTML render for the block. + * @param string $template_path The block render template path. + * @param array $attributes The block instance argument values. + * @param string $content The block inner content. + * @param WP_Block|null $block_obj The block object. + */ + return apply_filters( 'pods_block_render_html', $render, $attributes, $content, $block_obj ); + } + + /** + * Get list of Block API fields for the block. + * + * @since 2.8.0 + * + * @return array List of Block API fields. + */ + public function get_block_fields() { + /** @var Block_Field[] $fields */ + $fields = $this->get_fields(); + + $fields = array_map( static function ( $field ) { + return $field->get_block_args(); + }, $fields ); + + // Ensure the response is an array with no empty values. + $fields = array_values( array_filter( $fields ) ); + + return $fields; + } + + /** + * {@inheritdoc} + */ + public function get_args() { + $args = Whatsit::get_args(); + + // Pods generally have no parent, group, or order. + unset( $args['parent'], $args['group'] ); + + return $args; + } + + /** + * {@inheritdoc} + */ + public function get_fields( array $args = [] ) { + if ( [] === $this->_fields ) { + return []; + } + + $object_collection = Store::get_instance(); + + $has_custom_args = ! empty( $args ); + + if ( null === $this->_fields || $has_custom_args ) { + $args = array_merge( [ + 'object_type' => 'block-field', + ], $args ); + + $objects = parent::get_fields( $args ); + + if ( ! $has_custom_args ) { + $this->_fields = wp_list_pluck( $objects, 'identifier' ); + } + + return $objects; + } + + $objects = array_map( [ $object_collection, 'get_object' ], $this->_fields ); + $objects = array_filter( $objects ); + + $names = wp_list_pluck( $objects, 'name' ); + + return array_combine( $names, $objects ); + } +} diff --git a/src/Pods/Whatsit/Block_Collection.php b/src/Pods/Whatsit/Block_Collection.php new file mode 100644 index 0000000000..7e048897e1 --- /dev/null +++ b/src/Pods/Whatsit/Block_Collection.php @@ -0,0 +1,64 @@ +get_arg( 'namespace', 'pods' ); + + // Block collections are only allowed A-Z0-9- characters, no underscores. + $namespace = str_replace( '_', '-', sanitize_title_with_dashes( $namespace ) ); + + return [ + 'namespace' => $namespace, + 'title' => $this->get_arg( 'title', $this->get_arg( 'label' ) ), + 'icon' => $this->get_arg( 'icon', '' ), + ]; + } + + /** + * {@inheritdoc} + */ + public function get_args() { + $args = Whatsit::get_args(); + + // Pods generally have no parent, group, or order. + unset( $args['parent'], $args['group'] ); + + return $args; + } + + /** + * {@inheritdoc} + */ + public function get_fields( array $args = [] ) { + return []; + } + + /** + * {@inheritdoc} + */ + public function get_table_info() { + return []; + } +} diff --git a/src/Pods/Whatsit/Block_Field.php b/src/Pods/Whatsit/Block_Field.php new file mode 100644 index 0000000000..d257451583 --- /dev/null +++ b/src/Pods/Whatsit/Block_Field.php @@ -0,0 +1,335 @@ + [ + 'type' => 'TextControl', + 'fieldOptions' => [ + 'className' => 'text__container', + 'type' => 'text', + ], + 'attributeOptions' => [ + 'type' => 'string', + ], + ], + 'paragraph' => [ + 'type' => 'TextareaControl', + 'fieldOptions' => [ + 'className' => 'textarea__container', + 'auto_p' => true, + ], + 'attributeOptions' => [ + 'type' => 'string', + ], + ], + // @todo Add support for RichText at a later time. + // [ + // 'type' => 'RichText', + // 'name' => 'richTextField', + // 'fieldOptions' => [ + // 'tagName' => 'p', + // 'className' => 'custom__container', + // 'label' => 'Label for the richtext field', + // ], + // 'attributeOptions' => [ + // 'type' => 'string', + // ], + // ], + 'datetime' => [ + 'type' => 'DateTimePicker', + 'fieldOptions' => [ + 'is12Hour' => true, + ], + 'attributeOptions' => [ + 'type' => 'string', + ], + ], + 'number' => [ + 'type' => 'NumberControl', + 'fieldOptions' => [ + 'isShiftStepEnabled' => false, + 'shiftStep' => false, + 'step' => 1, + ], + 'attributeOptions' => [ + 'type' => 'number', + ], + ], + 'file' => [ + 'type' => 'MediaUpload', + 'fieldOptions' => [], + 'attributeOptions' => [ + 'type' => 'object', + ], + ], + 'color' => [ + 'type' => 'ColorPicker', + 'fieldOptions' => [], + 'attributeOptions' => [ + 'type' => 'string', + ], + ], + ]; + } + + /** + * Get list of Block API arguments to use. + * + * @since 2.8.0 + * + * @return array|null List of Block API arguments or null if not valid. + */ + public function get_block_args() { + $field_mapping = $this->get_block_arg_mapping(); + + $type = $this->get_arg( 'type' ); + + if ( 'pick' === $type ) { + $field_mapping[ $type ] = $this->get_pick_block_args(); + } elseif ( 'boolean' === $type ) { + $field_mapping[ $type ] = $this->get_boolean_block_args(); + } + + if ( ! isset( $field_mapping[ $type ] ) ) { + return null; + } + + if ( 'file' === $type && 'multi' === $this->get_arg( 'file__format_type' ) ) { + return null; + } + + $block_args = $field_mapping[ $type ]; + + // Handle setting name/label/help. + $name = $this->get_arg( 'name' ); + + $block_args['name'] = $name; + + $block_args['fieldOptions']['help'] = $this->get_arg( 'description' ); + + if ( 'boolean' !== $type ) { + $block_args['fieldOptions']['label'] = $this->get_arg( 'label' ); + + $default_value = $this->get_arg( 'default' ); + + if ( 'pick' !== $type && ! in_array( $default_value, [ '', null ], true ) ) { + $block_args['attributeOptions']['default'] = $default_value; + } + } + + return $block_args; + } + + /** + * Get block args for a pick field type. + * + * @return array Block args. + */ + public function get_pick_block_args() { + $format_type = $this->get_arg( 'pick_format_type', 'single' ); + $format_single = $this->get_arg( 'pick_format_single', 'dropdown' ); + $format_multi = $this->get_arg( 'pick_format_multi', 'checkbox' ); + + // Support raw data for now. + $raw_data = (array) $this->get_arg( 'data', [] ); + $data = []; + + foreach ( $raw_data as $key => $item ) { + if ( ! is_array( $item ) ) { + $item = [ + 'label' => $item, + 'value' => $key, + ]; + } + + if ( ! isset( $item['label'], $item['value'] ) ) { + continue; + } + + $data[] = $item; + } + + $label = $this->get_arg( 'label' ); + $default = $this->get_arg( 'default', '' ); + + if ( 'single' === $format_type ) { + if ( 'radio' === $format_single ) { + return [ + 'type' => 'RadioControl', + 'fieldOptions' => [ + 'heading' => $label, + 'options' => $data, + ], + 'attributeOptions' => [ + 'type' => 'string', + 'default' => $default, + ], + ]; + } + + foreach ( $data as $data_value ) { + if ( $default === $data_value['value'] ) { + $default = $data_value; + + break; + } + } + + return [ + 'type' => 'SelectControl', + 'fieldOptions' => [ + 'heading' => $label, + 'options' => $data, + ], + 'attributeOptions' => [ + 'type' => 'object', + 'default' => $default, + ], + ]; + } + + if ( in_array( $format_multi, [ 'multiselect', 'autocomplete' ], true ) ) { + return [ + 'type' => 'SelectControl', + 'fieldOptions' => [ + 'multiple' => true, + 'heading' => $label, + 'options' => $data, + ], + 'attributeOptions' => [ + 'type' => 'array', + ], + ]; + } + + return [ + 'type' => 'CheckboxGroup', + 'name' => 'checkboxGroup', + 'fieldOptions' => [ + 'heading' => $label, + 'options' => $data, + ], + 'attributeOptions' => [ + 'type' => 'array', + ], + ]; + } + + /** + * Get block args for a boolean field type. + * + * @return array Block args. + */ + public function get_boolean_block_args() { + $format_type = $this->get_arg( 'boolean_format_type', 'checkbox' ); + + $data = [ + [ + 'label' => $this->get_arg( 'boolean_yes_label', __( 'Yes', 'pods' ) ), + 'value' => 1, + ], + [ + 'label' => $this->get_arg( 'boolean_no_label', __( 'No', 'pods' ) ), + 'value' => 0, + ], + ]; + + $label = $this->get_arg( 'label' ); + $default = (boolean) $this->get_arg( 'default', 0 ); + + if ( 'radio' === $format_type ) { + return [ + 'type' => 'RadioControl', + 'fieldOptions' => [ + 'heading' => $label, + 'options' => $data, + ], + 'attributeOptions' => [ + 'type' => 'string', + 'default' => $default, + ], + ]; + } + + if ( 'dropdown' === $format_type ) { + return [ + 'type' => 'SelectControl', + 'fieldOptions' => [ + 'heading' => $label, + 'options' => $data, + ], + 'attributeOptions' => [ + 'type' => 'object', + 'default' => $default, + ], + ]; + } + + return [ + 'type' => 'CheckboxControl', + 'fieldOptions' => [ + 'heading' => $label, + 'label' => $data[0]['label'], + ], + 'attributeOptions' => [ + 'type' => 'boolean', + 'default' => $default, + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function get_table_info() { + return []; + } + + /** + * {@inheritdoc} + */ + public function get_arg( $arg, $default = null, $strict = false ) { + if ( 'block' === $arg ) { + return $this->get_parent_name(); + } + + return Whatsit::get_arg( $arg, $default ); + } + + /** + * {@inheritdoc} + */ + public function get_related_object_type() { + return null; + } + + /** + * {@inheritdoc} + */ + public function get_related_object_name() { + return null; + } +} diff --git a/src/Pods/Whatsit/Field.php b/src/Pods/Whatsit/Field.php new file mode 100644 index 0000000000..7e8d1a1f51 --- /dev/null +++ b/src/Pods/Whatsit/Field.php @@ -0,0 +1,253 @@ +_table_info ) { + return $this->_table_info; + } + + $related_type = $this->get_related_object_type(); + $related_name = $this->get_related_object_name(); + + if ( null === $related_type || null === $related_name ) { + return []; + } + + $api = pods_api(); + + $table_info = $api->get_table_info( $related_type, $related_name ); + + if ( ! $table_info ) { + $table_info = []; + } + + $this->_table_info = $table_info; + + return $table_info; + } + + /** + * {@inheritdoc} + */ + public function get_arg( $arg, $default = null, $strict = false ) { + $arg = (string) $arg; + + $special_args = [ + // Pod args. + 'pod_id' => 'get_parent_id', + 'pod' => 'get_parent_name', + 'pod_name' => 'get_parent_name', + 'pod_identifier' => 'get_parent_identifier', + 'pod_label' => 'get_parent_label', + 'pod_description' => 'get_parent_description', + 'pod_object' => 'get_parent_object', + 'pod_object_type' => 'get_parent_object_type', + 'pod_storage_type' => 'get_parent_storage_type', + 'pod_type' => 'get_parent_type', + // Group args. + 'group_id' => 'get_group_id', + 'group_name' => 'get_group_name', + 'group_identifier' => 'get_group_identifier', + 'group_label' => 'get_group_label', + 'group_description' => 'get_group_description', + 'group_object' => 'get_group_object', + 'group_object_type' => 'get_group_object_type', + 'group_storage_type' => 'get_group_storage_type', + 'group_type' => 'get_group_type', + ]; + + if ( isset( $special_args[ $arg ] ) ) { + return $this->{$special_args[ $arg ]}(); + } + + // Backwards compatibility with previous Pods 2.8 pre-releases. + if ( 'sister_id' === $arg && isset( $this->args[ $arg ] ) ) { + $invalid_options = [ + 0, + '0', + '', + '-- Select One --', + __( '-- Select One --', 'pods' ), + null, + ]; + + if ( in_array( $this->args[ $arg ], $invalid_options, true ) ) { + return $default; + } + + return (int) $this->args[ $arg ]; + } + + return parent::get_arg( $arg, $default ); + } + + /** + * Get related object type from field. + * + * @since 2.8.0 + * + * @return string|null The related object type, or null if not found. + */ + public function get_related_object_type() { + $type = $this->get_type(); + + $simple_tableless_objects = PodsForm::simple_tableless_objects(); + + // File field types are always related to the media object type. + if ( 'file' === $type ) { + return 'media'; + } + + $related_type = $this->get_arg( $type . '_object', $this->get_arg( 'pick_object' ) ); + + if ( '__current__' === $related_type ) { + $related_type = $this->get_object_type(); + } + + if ( empty( $related_type ) && 'avatar' === $type ) { + $related_type = 'media'; + } + + if ( empty( $related_type ) || in_array( $related_type, $simple_tableless_objects, true ) ) { + return null; + } + + return $related_type; + } + + /** + * Get related object name from field. + * + * @since 2.8.0 + * + * @return string|null The related object name, or null if not found. + */ + public function get_related_object_name() { + $type = $this->get_type(); + + $related_type = $this->get_related_object_type(); + + if ( null === $related_type ) { + return null; + } + + $related_name = $this->get_arg( $type . '_val', $this->get_arg( 'pick_val', $related_type ) ); + + if ( '__current__' === $related_name ) { + $related_name = $this->get_name(); + } + + if ( 'table' === $related_type ) { + $related_name = $this->get_arg( 'related_table', $related_name ); + } elseif ( in_array( $related_type, [ 'user', 'media', 'comment' ], true ) ) { + $related_name = $related_type; + } + + return $related_name; + } + + /** + * Get related object data from field. + * + * @since 2.8.0 + * + * @return array|null The related object data, or null if not found. + */ + public function get_related_object_data() { + return PodsForm::field_method( $this->args['type'], 'data', $this->args['name'], null, $this->args, null, null, true ); + } + + /** + * Get the related Pod object if it exists. + * + * @since 2.8.0 + * + * @return Whatsit|array|null The related object, or null if not found. + */ + public function get_related_object() { + $table_info = $this->get_table_info(); + + // Check if the pod was found. + if ( ! $table_info || empty( $table_info['pod'] ) ) { + return null; + } + + return $table_info['pod']; + } + + /** + * Get the bi-directional field if it is set. + * + * @since 2.8.0 + * + * @return Whatsit|null The bi-directional field if it is set. + */ + public function get_bidirectional_field() { + $sister_id = $this->get_arg( 'sister_id' ); + + if ( ! $sister_id ) { + return null; + } + + $related_field = Store::get_instance()->get_object( $sister_id ); + + // Only return if it is a valid field. + if ( ! $related_field instanceof Field ) { + return null; + } + + return $related_field; + } + + /** + * Get field value limit from field. + * + * @since 2.8.0 + * + * @return int The field value limit. + */ + public function get_limit() { + $type = $this->get_type(); + $format = $this->get_arg( $type .'_format_type', 'single' ); + + if ( 'multi' === $format ) { + return (int) $this->get_arg( $type . '_limit', 0 ); + } + + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_fields( array $args = [] ) { + return []; + } + + /** + * {@inheritdoc} + */ + public function get_groups( array $args = [] ) { + return []; + } + +} diff --git a/src/Pods/Whatsit/Group.php b/src/Pods/Whatsit/Group.php new file mode 100644 index 0000000000..bc1d62b15c --- /dev/null +++ b/src/Pods/Whatsit/Group.php @@ -0,0 +1,128 @@ +_fields ) { + return []; + } + + $object_collection = Store::get_instance(); + + $has_custom_args = ! empty( $args ); + + if ( null === $this->_fields || $has_custom_args ) { + $filtered_args = [ + 'parent' => $this->get_parent_id(), + 'parent_id' => $this->get_parent_id(), + 'parent_name' => $this->get_parent_name(), + 'parent_identifier' => $this->get_parent_identifier(), + 'group' => $this->get_name(), + 'group_id' => $this->get_id(), + 'group_name' => $this->get_name(), + 'group_identifier' => $this->get_identifier(), + ]; + + if ( empty( $filtered_args['parent_id'] ) || empty( $filtered_args['group_id'] ) ) { + $filtered_args['bypass_post_type_find'] = true; + } + + $filtered_args = array_filter( $filtered_args ); + + $args = array_merge( [ + 'orderby' => 'menu_order title', + 'order' => 'ASC', + ], $filtered_args, $args ); + + try { + $api = pods_api(); + + if ( ! empty( $args['object_type'] ) ) { + $objects = $api->_load_objects( $args ); + } else { + $objects = $api->load_fields( $args ); + } + } catch ( \Exception $exception ) { + $objects = []; + } + + if ( ! $has_custom_args ) { + $this->_fields = wp_list_pluck( $objects, 'identifier' ); + } + + return $objects; + } + + $objects = array_map( [ $object_collection, 'get_object' ], $this->_fields ); + $objects = array_filter( $objects ); + + $names = wp_list_pluck( $objects, 'name' ); + + return array_combine( $names, $objects ); + } + + /** + * {@inheritdoc} + */ + public function get_groups( array $args = [] ) { + // Groups do not support groups. + return []; + } + + /** + * {@inheritdoc} + */ + public function get_arg( $arg, $default = null, $strict = false ) { + $arg = (string) $arg; + + $special_args = [ + // Pod args. + 'pod_id' => 'get_parent_id', + 'pod' => 'get_parent_name', + 'pod_name' => 'get_parent_name', + 'pod_identifier' => 'get_parent_identifier', + 'pod_label' => 'get_parent_label', + 'pod_description' => 'get_parent_description', + 'pod_object' => 'get_parent_object', + 'pod_object_type' => 'get_parent_object_type', + 'pod_storage_type' => 'get_parent_storage_type', + 'pod_type' => 'get_parent_type', + ]; + + if ( isset( $special_args[ $arg ] ) ) { + return $this->{$special_args[ $arg ]}(); + } + + return parent::get_arg( $arg, $default ); + } + +} diff --git a/src/Pods/Whatsit/Legacy_Object.php b/src/Pods/Whatsit/Legacy_Object.php new file mode 100644 index 0000000000..62fab88e43 --- /dev/null +++ b/src/Pods/Whatsit/Legacy_Object.php @@ -0,0 +1,70 @@ + 'label', + 'slug' => 'name', + 'code' => 'description', + ]; + + $new_args = []; + + foreach ( $old_mapping as $old_arg => $new_arg ) { + $new_args[ $old_arg ] = ''; + + if ( isset( $args[ $new_arg ] ) ) { + $new_args[ $old_arg ] = $args[ $new_arg ]; + + unset( $args[ $new_arg ] ); + } + } + + return array_merge( $new_args, $args ); + } + + /** + * {@inheritdoc} + */ + public function get_arg( $arg, $default = null, $strict = false ) { + $old_mapping = [ + 'name' => 'label', + 'slug' => 'name', + 'code' => 'description', + ]; + + if ( isset( $old_mapping[ $arg ] ) ) { + $arg = $old_mapping[ $arg ]; + } + + return parent::get_arg( $arg, $default ); + } + + /** + * {@inheritdoc} + */ + public function get_name() { + // Map get_name() to the real name, so we have a way to still get to it intentionally. + if ( isset( $this->args['name'] ) ) { + return $this->args['name']; + } + + return null; + } + +} diff --git a/src/Pods/Whatsit/Object_Field.php b/src/Pods/Whatsit/Object_Field.php new file mode 100644 index 0000000000..a70c3ab7ee --- /dev/null +++ b/src/Pods/Whatsit/Object_Field.php @@ -0,0 +1,17 @@ +_object_fields ) { + return []; + } + + $api = pods_api(); + + $object_fields = $api->get_wp_object_fields( $this->get_type(), $this ); + + $object_collection = Store::get_instance(); + + $objects = []; + + foreach ( $object_fields as $object_field ) { + $object_field['object_type'] = 'object-field'; + $object_field['storage_type'] = 'collection'; + $object_field['parent'] = $this->get_id(); + + $object = $object_collection->get_object( $object_field ); + + if ( $object ) { + $objects[ $object->get_name() ] = $object; + } + } + + $this->_object_fields = $objects; + + return $objects; + } + + /** + * {@inheritdoc} + */ + public function count_object_fields() { + if ( [] === $this->_object_fields ) { + return 0; + } + + $api = pods_api(); + + $object_fields = $api->get_wp_object_fields( $this->get_type(), $this ); + + return count( $object_fields ); + } + + /** + * {@inheritdoc} + */ + public function get_table_info() { + if ( null !== $this->_table_info ) { + return $this->_table_info; + } + + $api = pods_api(); + + $table_info = $api->get_table_info( $this->get_type(), $this->get_name(), null, $this ); + + if ( empty( $table_info ) ) { + $table_info = []; + } + + $this->_table_info = $table_info; + + return $table_info; + } + +} diff --git a/src/Pods/Whatsit/Storage.php b/src/Pods/Whatsit/Storage.php new file mode 100644 index 0000000000..132b157151 --- /dev/null +++ b/src/Pods/Whatsit/Storage.php @@ -0,0 +1,428 @@ +get_identifier(); + $args[ $arg . '_id' ] = (array) $args[ $arg ]->get_id(); + $args[ $arg . '_name' ] = (array) $args[ $arg ]->get_name(); + $args[ $arg ] = (array) $args[ $arg ]->get_name(); + } + + return $args; + } + + /** + * Get arg value. + * + * @param array $args List of arguments. + * @param string $arg Argument to get values for. + * + * @return array|string|int|null Arg value(s). + */ + public function get_arg_value( $args, $arg ) { + $arg_value = []; + + if ( array_key_exists( $arg, $args ) ) { + $arg_value[] = is_array( $args[ $arg ] ) ? $args[ $arg ] : [ $args[ $arg ] ]; + } + + $secondary_variations = [ + 'identifier', + 'id', + 'name', + ]; + + foreach ( $secondary_variations as $variation ) { + if ( ! array_key_exists( $arg . '_' . $variation, $args ) ) { + continue; + } + + $arg_value[] = is_array( $args[ $arg . '_' . $variation ] ) ? $args[ $arg . '_' . $variation ] : [ $args[ $arg . '_' . $variation ] ]; + } + + if ( empty( $arg_value ) ) { + return '_null'; + } + + $arg_value = array_merge( ...$arg_value ); + $arg_value = array_unique( $arg_value ); + + if ( 1 === count( $arg_value ) ) { + $arg_value = current( $arg_value ); + } + + return $arg_value; + } + + /** + * Add an object. + * + * @param Whatsit $object Object to add. + * + * @return string|int|false Object name, object ID, or false if not added. + */ + protected function add_object( Whatsit $object ) { + return $this->save_object( $object ); + } + + /** + * Add an object. + * + * @param Whatsit $object Object to add. + * + * @return string|int|false Object name, object ID, or false if not added. + */ + public function add( Whatsit $object ) { + /** + * Hook into the storage adding of an object. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_save', $object, $this ); + + /** + * Hook into the storage adding of an object based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_save_' . $object->get_object_type(), $object, $this ); + + $added = $this->add_object( $object ); + + if ( $added && ! is_wp_error( $added ) ) { + /** + * Hook into the storage adding of an object after adding. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_added', $object, $this ); + + /** + * Hook into the storage adding of an object after adding based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_added_' . $object->get_object_type(), $object, $this ); + + if ( true === $added ) { + $added = (int) $object->get_id(); + + if ( empty( $added ) ) { + $added = $object->get_name(); + } + } + }//end if + + return $added; + } + + /** + * Save an object. + * + * @param Whatsit $object Object to save. + * + * @return string|int|false Object name, object ID, or false if not saved. + */ + protected function save_object( Whatsit $object ) { + return false; + } + + /** + * Save an object. + * + * @param Whatsit $object Object to save. + * + * @return string|int|false Object name, object ID, or false if not saved. + */ + public function save( Whatsit $object ) { + /** + * Hook into the storage saving of an object. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_save', $object, $this ); + + /** + * Hook into the storage saving of an object based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_save_' . $object->get_object_type(), $object, $this ); + + $saved = $this->save_object( $object ); + + if ( $saved && ! is_wp_error( $saved ) ) { + /** + * Hook into the storage saving of an object after saving. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_saved', $object, $this ); + + /** + * Hook into the storage saving of an object after saving based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_saved_' . $object->get_object_type(), $object, $this ); + + if ( true === $saved ) { + $saved = (int) $object->get_id(); + + if ( empty( $saved ) ) { + $saved = $object->get_name(); + } + } + }//end if + + return $saved; + } + + /** + * Duplicate an object. + * + * @param Whatsit $object Object to duplicate. + * + * @return string|int|false Duplicated object name, duplicated object ID, or false if not duplicated. + */ + public function duplicate( Whatsit $object ) { + $duplicated_object = clone $object; + + $duplicated_object->set_arg( 'id', null ); + $duplicated_object->set_arg( 'name', $duplicated_object->get_name() . '_copy' ); + + $added = $this->add( $duplicated_object ); + + if ( $added && ! is_wp_error( $added ) ) { + /** + * Hook into the storage duplication of an object after duplication. + * + * @param Whatsit $object Original pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_duplicated', $object, $this ); + + /** + * Hook into the storage duplication of an object after duplication based on object type. + * + * @param Whatsit $object Original pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_duplicated_' . $object->get_object_type(), $object, $this ); + }//end if + + return $added; + } + + /** + * Delete an object. + * + * @param Whatsit $object Object to delete. + * + * @return bool + */ + protected function delete_object( Whatsit $object ) { + return false; + } + + /** + * Delete an object. + * + * @param Whatsit $object Object to delete. + * + * @return bool + */ + public function delete( Whatsit $object ) { + /** + * Hook into the storage deletion of an object. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_delete', $object, $this ); + + /** + * Hook into the storage deletion of an object based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_delete_' . $object->get_object_type(), $object, $this ); + + $deleted = $this->delete_object( $object ); + + if ( $deleted ) { + /** + * Hook into the storage deletion of an object after deletion based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_deleted', $object, $this ); + + /** + * Hook into the storage deletion of an object after deletion based on object type. + * + * @param Whatsit $object Pod object. + * @param Storage $storage Storage object. + * + * @since 2.8.0 + */ + do_action( 'pods_whatsit_storage_deleted_' . $object->get_object_type(), $object, $this ); + }//end if + + return $deleted; + } + + /** + * Reset an object's item data. + * + * @param Whatsit $object Object of items to reset. + * + * @return bool + */ + public function reset( Whatsit $object ) { + return false; + } + + /** + * Get object argument data. + * + * @param Whatsit $object Object with arguments to save. + * + * @return array + */ + public function get_args( Whatsit $object ) { + return $object->get_args(); + } + + /** + * Save object argument data. + * + * @param Whatsit $object Object with arguments to save. + * + * @return bool + */ + public function save_args( Whatsit $object ) { + return false; + } + + /** + * Whether to enable fallback mode for falling back to parent storage options. + * + * @param bool $enabled Whether to enable fallback mode. + */ + public function fallback_mode( $enabled = true ) { + $this->fallback_mode = (boolean) $enabled; + } + +} diff --git a/src/Pods/Whatsit/Storage/Collection.php b/src/Pods/Whatsit/Storage/Collection.php new file mode 100644 index 0000000000..8821cdaed4 --- /dev/null +++ b/src/Pods/Whatsit/Storage/Collection.php @@ -0,0 +1,295 @@ + $args['object_type'], + 'name' => $args['name'], + 'limit' => 1, + ]; + + $objects = $this->find( $find_args ); + + if ( $objects ) { + return reset( $objects ); + } + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function find( array $args = [] ) { + // Object type OR parent is required. + if ( empty( $args['object_type'] ) && empty( $args['parent'] ) ) { + return []; + } + + /** + * Filter the maximum number of posts to get for post type storage. + * + * @since 2.8.0 + * + * @param int $limit + * + */ + $limit = apply_filters( 'pods_whatsit_storage_post_type_find_limit', 300 ); + + if ( empty( $args['limit'] ) ) { + $args['limit'] = $limit; + } + + $object_collection = Store::get_instance(); + + $objects = $object_collection->get_objects(); + + foreach ( $objects as $k => $object ) { + if ( self::$type === $object->get_storage_type() ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + + if ( ! empty( $args['object_type'] ) ) { + $object_types = (array) $args['object_type']; + + foreach ( $objects as $k => $object ) { + if ( in_array( $object->get_object_type(), $object_types, true ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + } + + if ( ! isset( $args['args'] ) ) { + $args['args'] = []; + } + + $args['args'] = (array) $args['args']; + + + $secondary_object_args = [ + 'parent', + 'group', + ]; + + foreach ( $secondary_object_args as $arg ) { + $args = $this->setup_arg( $args, $arg ); + $arg_value = $this->get_arg_value( $args, $arg ); + + if ( '_null' === $arg_value ) { + continue; + } + + $args['args'][ $arg ] = $arg_value; + } + + foreach ( $this->secondary_args as $arg ) { + if ( ! isset( $args[ $arg ] ) ) { + continue; + } + + $args['args'][ $arg ] = $args[ $arg ]; + } + + foreach ( $args['args'] as $arg => $value ) { + if ( null === $value ) { + foreach ( $objects as $k => $object ) { + if ( $value === $object->get_arg( $arg ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + + continue; + } + + if ( ! is_array( $value ) ) { + $value = trim( $value ); + + foreach ( $objects as $k => $object ) { + if ( $value === (string) $object->get_arg( $arg ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + + continue; + } + + $value = (array) $value; + $value = array_map( 'trim', $value ); + $value = array_unique( $value ); + $value = array_filter( $value ); + + if ( $value ) { + foreach ( $objects as $k => $object ) { + if ( in_array( (string) $object->get_arg( $arg ), $value, true ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + } + }//end foreach + + if ( ! empty( $args['id'] ) ) { + $args['id'] = (array) $args['id']; + $args['id'] = array_map( 'absint', $args['id'] ); + $args['id'] = array_unique( $args['id'] ); + $args['id'] = array_filter( $args['id'] ); + + if ( $args['id'] ) { + foreach ( $objects as $k => $object ) { + if ( in_array( $object->get_id(), $args['id'], true ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + } + } + + if ( ! empty( $args['name'] ) ) { + $args['name'] = (array) $args['name']; + $args['name'] = array_map( 'trim', $args['name'] ); + $args['name'] = array_unique( $args['name'] ); + $args['name'] = array_filter( $args['name'] ); + + if ( $args['name'] ) { + foreach ( $objects as $k => $object ) { + if ( in_array( $object->get_name(), $args['name'], true ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + + if ( empty( $objects ) ) { + return $objects; + } + } + } + + if ( isset( $args['internal'] ) ) { + foreach ( $objects as $k => $object ) { + if ( $args['internal'] === (boolean) $object->get_arg( 'internal' ) ) { + continue; + } + + unset( $objects[ $k ] ); + } + } + + if ( ! empty( $args['limit'] ) ) { + $objects = array_slice( $objects, 0, $args['limit'], true ); + } + + $names = wp_list_pluck( $objects, 'name' ); + + return array_combine( $names, $objects ); + } + + /** + * {@inheritdoc} + */ + protected function save_object( Whatsit $object ) { + $storage_type = $object->get_storage_type(); + + if ( empty( $storage_type ) ) { + $object->set_arg( 'storage_type', static::$type ); + } + + $object_collection = Store::get_instance(); + $object_collection->register_object( $object ); + + return true; + } + + /** + * {@inheritdoc} + */ + protected function delete_object( Whatsit $object ) { + // If this object has fields or groups, delete them. + $objects = array_merge( $object->get_all_fields(), $object->get_groups() ); + + // Delete child objects. + array_map( [ $this, 'delete' ], $objects ); + + $object_collection = Store::get_instance(); + $object_collection->unregister_object( $object ); + + $object->set_arg( 'id', null ); + + return true; + } + + /** + * {@inheritdoc} + */ + public function save_args( Whatsit $object ) { + return true; + } + +} diff --git a/src/Pods/Whatsit/Storage/Post_Type.php b/src/Pods/Whatsit/Storage/Post_Type.php new file mode 100644 index 0000000000..54d6354aa2 --- /dev/null +++ b/src/Pods/Whatsit/Storage/Post_Type.php @@ -0,0 +1,684 @@ + 'id', + 'post_name' => 'name', + 'post_title' => 'label', + 'post_content' => 'description', + 'post_parent' => 'parent', + 'menu_order' => 'weight', + ]; + + /** + * @var array + */ + protected $secondary_args = [ + 'type', + 'object', + ]; + + /** + * {@inheritdoc} + */ + public function get( array $args = [] ) { + // Object type is required. + if ( empty( $args['object_type'] ) ) { + return null; + } + + if ( ! empty( $args['id'] ) ) { + return $this->to_object( $args['id'] ); + } + + if ( ! empty( $args['post'] ) ) { + return $this->to_object( $args['post'] ); + } + + if ( ! empty( $args['name'] ) ) { + $find_args = [ + 'object_type' => $args['object_type'], + 'name' => $args['name'], + 'limit' => 1, + ]; + + $objects = $this->find( $find_args ); + + if ( $objects ) { + return reset( $objects ); + } + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function find( array $args = [] ) { + // Object type OR parent is required. + if ( empty( $args['object_type'] ) && empty( $args['parent'] ) ) { + return []; + } + + if ( ! isset( $args['bypass_cache'] ) ) { + $api_cache = pods_api_cache(); + + if ( ! $api_cache ) { + $args['bypass_cache'] = true; + } + } + + if ( ! isset( $args['bypass_post_type_find'] ) ) { + $args['bypass_post_type_find'] = false; + } + + $fallback_mode = $this->fallback_mode; + + if ( isset( $args['fallback_mode'] ) ) { + $fallback_mode = (boolean) $args['fallback_mode']; + } + + /** + * Filter the maximum number of posts to get for post type storage. + * + * @since 2.8.0 + * + * @param int $limit + * + */ + $limit = apply_filters( 'pods_whatsit_storage_post_type_find_limit', 300 ); + + $post_args = [ + 'order' => 'ASC', + 'orderby' => 'title', + 'posts_per_page' => $limit, + 'meta_query' => [], + 'post_type' => 'any', + 'post_status' => [ + 'publish', + 'draft', + ], + 'suppress_filters' => false, + ]; + + if ( ! empty( $args['object_type'] ) ) { + $post_args['post_type'] = []; + + $object_types = (array) $args['object_type']; + + foreach ( $object_types as $object_type ) { + $post_args['post_type'][] = '_pods_' . $object_type; + } + + // There is some sort of bug when you pass a single value array for post_type that causes no results. + if ( 1 === count( $post_args['post_type'] ) ) { + $post_args['post_type'] = current( $post_args['post_type'] ); + } + } + + if ( ! isset( $args['args'] ) ) { + $args['args'] = []; + } + + $args['args'] = (array) $args['args']; + + $secondary_object_args = [ + 'parent', + 'group', + ]; + + foreach ( $secondary_object_args as $arg ) { + $args = $this->setup_arg( $args, $arg ); + $arg_value = $this->get_arg_value( $args, $arg ); + + if ( '_null' === $arg_value ) { + continue; + } + + $args['args'][ $arg ] = $arg_value; + } + + foreach ( $this->secondary_args as $arg ) { + if ( ! array_key_exists( $arg, $args ) ) { + continue; + } + + $args['args'][ $arg ] = $args[ $arg ]; + } + + foreach ( $args['args'] as $arg => $value ) { + if ( 'parent' === $arg ) { + continue; + } + + if ( null === $value ) { + $post_args['meta_query'][] = [ + 'key' => $arg, + 'compare' => 'NOT EXISTS', + ]; + + continue; + } + + if ( ! is_array( $value ) ) { + $value = trim( $value ); + + $post_args['meta_query'][] = [ + 'key' => $arg, + 'value' => $value, + ]; + + continue; + } + + $value = (array) $value; + $value = array_map( 'trim', $value ); + $value = array_unique( $value ); + $value = array_filter( $value, static function( $v ) { + return null !== $v; + } ); + + if ( $value ) { + sort( $value ); + + $post_args['meta_query'][] = [ + 'key' => $arg, + 'value' => $value, + 'compare' => 'IN', + ]; + } + }//end foreach + + if ( ! empty( $args['id'] ) ) { + $args['id'] = (array) $args['id']; + $args['id'] = array_map( 'absint', $args['id'] ); + $args['id'] = array_unique( $args['id'] ); + $args['id'] = array_filter( $args['id'] ); + + if ( $args['id'] ) { + $post_args['post__in'] = $args['id']; + } else { + // Bypass WP_Query if we know there are things that won't match. + $args['bypass_post_type_find'] = true; + } + } + + if ( ! empty( $args['name'] ) ) { + $args['name'] = (array) $args['name']; + $args['name'] = array_map( 'trim', $args['name'] ); + $args['name'] = array_unique( $args['name'] ); + $args['name'] = array_filter( $args['name'] ); + + if ( $args['name'] ) { + $post_args['post_name__in'] = $args['name']; + } else { + // Bypass WP_Query if we know there are things that won't match. + $args['bypass_post_type_find'] = true; + } + } + + if ( ! empty( $args['args']['parent'] ) ) { + $post_args['post_parent__in'] = (array) $args['args']['parent']; + $post_args['post_parent__in'] = array_map( 'absint', $post_args['post_parent__in'] ); + $post_args['post_parent__in'] = array_unique( $post_args['post_parent__in'] ); + $post_args['post_parent__in'] = array_filter( $post_args['post_parent__in'] ); + + if ( ! $post_args['post_parent__in'] ) { + unset( $post_args['post_parent__in'] ); + + // Bypass WP_Query if we know there are things that won't match. + $args['bypass_post_type_find'] = true; + } + } + + if ( ! empty( $args['status'] ) ) { + $args['status'] = (array) $args['status']; + $args['status'] = array_map( 'trim', $args['status'] ); + $args['status'] = array_unique( $args['status'] ); + $args['status'] = array_filter( $args['status'] ); + + if ( $args['status'] ) { + sort( $args['status'] ); + + if ( 1 === count( $args['status'] ) ) { + $args['status'] = current( $args['status'] ); + } + + $post_args['post_status'] = $args['status']; + } else { + // Bypass WP_Query if we know there are things that won't match. + $args['bypass_post_type_find'] = true; + } + } + + if ( ! empty( $args['order'] ) ) { + $post_args['order'] = $args['order']; + } + + if ( ! empty( $args['orderby'] ) ) { + $post_args['orderby'] = $args['orderby']; + } + + if ( ! empty( $args['count'] ) ) { + $args['limit'] = 1; + } + + if ( ! empty( $args['limit'] ) ) { + $post_args['posts_per_page'] = (int) $args['limit']; + } + + /** + * Filter the get_posts() arguments used for finding the objects for post type storage. + * + * @since 2.8.0 + * + * @param array $args Arguments to use. + * + * @param array $post_args Post arguments to use in get_posts() call. + */ + $post_args = apply_filters( 'pods_whatsit_storage_post_type_find_args', $post_args, $args ); + + $post_args['fields'] = 'ids'; + + if ( empty( $post_args['meta_query'] ) ) { + unset( $post_args['meta_query'] ); + } + + asort( $post_args ); + + $current_language = pods_i18n()->get_current_language(); + + $cache_key = null; + $posts = false; + $post_objects = false; + + if ( empty( $args['bypass_cache'] ) && empty( $args['bypass_post_type_find'] ) ) { + $cache_key_parts = [ + 'pods_whatsit_storage_post_type_find', + ]; + + if ( ! empty( $args['count'] ) ) { + $cache_key_parts[] = '_count'; + } + + if ( ! empty( $args['names'] ) ) { + $cache_key_parts[] = '_names'; + } + + if ( ! empty( $args['names_ids'] ) ) { + $cache_key_parts[] = '_namesids'; + } + + if ( ! empty( $args['ids'] ) ) { + $cache_key_parts[] = '_ids'; + } + + $cache_key_parts[] = $current_language; + $cache_key_parts[] = wp_json_encode( $post_args ); + + /** + * Filter cache key parts used for generating the cache key. + * + * @since 2.8.0 + * + * @param array $post_args Post arguments to use in get_posts() call. + * @param array $args Arguments to use. + * + * @param array $cache_key_parts Cache key parts used to build cache key. + */ + $cache_key_parts = apply_filters( 'pods_whatsit_storage_post_type_cache_key_parts', $cache_key_parts, $post_args, $args ); + + $cache_key_parts = array_filter( $cache_key_parts ); + + $cache_key = implode( '_', $cache_key_parts ); + + if ( empty( $args['refresh'] ) ) { + $posts = pods_transient_get( $cache_key ); + $post_objects = pods_cache_get( $cache_key . '_objects', 'pods_post_type_storage' ); + } + }//end if + + if ( ! is_array( $posts ) ) { + $posts = []; + $post_objects = false; + + if ( empty( $args['bypass_post_type_find'] ) ) { + $query = new WP_Query( $post_args ); + + $posts = $query->get_posts(); + + // We only receive the first post, so let's just override the posts with the count. + if ( ! empty( $args['count'] ) ) { + $posts = array_fill( 0, $query->found_posts, 'temp_count_holder' ); + } + + if ( empty( $args['bypass_cache'] ) ) { + pods_transient_set( $cache_key, $posts, WEEK_IN_SECONDS ); + } + } + } + + // Return the list of posts as they are if we are counting. + if ( ! empty( $args['count'] ) ) { + if ( $fallback_mode && ( empty( $args['status'] ) || in_array( 'publish', (array) $args['status'], true ) ) ) { + $posts = array_merge( $posts, parent::find( $args ) ); + } + + return $posts; + } + + if ( ! is_array( $post_objects ) ) { + $post_objects = []; + + if ( ! empty( $posts ) ) { + if ( ! empty( $args['ids'] ) ) { + // Get a list of the post IDs in basic array form. + $post_objects = array_map( static function ( $post_id ) { + return (object) [ + 'id' => (int) $post_id, + 'ID' => (int) $post_id, + ]; + }, $posts ); + } else { + // Get the post objects. + $post_objects = array_map( 'get_post', $posts ); + } + } + + if ( empty( $args['bypass_post_type_find'] ) && empty( $args['bypass_cache'] ) ) { + pods_cache_set( $cache_key . '_objects', $post_objects, 'pods_post_type_storage', WEEK_IN_SECONDS ); + } + } + + // Use the objects as they are if we only need the IDs. + if ( ! empty( $args['ids'] ) ) { + // We set $post_objects as id => $post_id above already. + $posts = $post_objects; + } else { + if ( ! empty( $args['names'] ) || ! empty( $args['names_ids'] ) ) { + // Just do a quick setup of the data we need for names and names+ids return. + $posts = array_map( static function( $post ) { + return (object) [ + 'id' => $post->ID, + 'name' => $post->post_name, + 'label' => $post->post_title, + ]; + }, $post_objects ); + } else { + // Handle normal Whatsit object setup. + $posts = array_map( [ $this, 'to_object' ], $post_objects ); + $posts = array_filter( $posts ); + } + + $names = wp_list_pluck( $posts, 'name' ); + $posts = array_combine( $names, $posts ); + } + + if ( $fallback_mode && ( empty( $args['status'] ) || in_array( 'publish', (array) $args['status'], true ) ) ) { + $posts = array_merge( $posts, parent::find( $args ) ); + } + + if ( ! empty( $args['limit'] ) ) { + $posts = array_slice( $posts, 0, $args['limit'], true ); + } + + return $posts; + } + + /** + * {@inheritdoc} + */ + protected function add_object( Whatsit $object ) { + $post_data = [ + 'post_title' => $object->get_label(), + 'post_name' => $object->get_name(), + 'post_content' => $object->get_description(), + 'post_parent' => $object->get_parent_id(), + 'post_type' => '_pods_' . $object->get_object_type(), + 'post_status' => 'publish', + ]; + + if ( '' === $post_data['post_title'] ) { + $post_data['post_title'] = $post_data['post_name']; + } + + $added = wp_insert_post( $post_data ); + + if ( is_int( $added ) && 0 < $added ) { + // Remove any other references. + $object_collection = Store::get_instance(); + $object_collection->unregister_object( $object ); + + $object->set_arg( 'id', $added ); + + $this->save_args( $object ); + + return parent::add_object( $object ); + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function save_object( Whatsit $object ) { + $id = $object->get_id(); + + if ( empty( $id ) ) { + return parent::save_object( $object ); + } + + $post_data = [ + 'ID' => $id, + 'post_title' => $object->get_label(), + 'post_name' => $object->get_name(), + 'post_content' => $object->get_description(), + 'post_parent' => $object->get_parent_id(), + 'post_type' => '_pods_' . $object->get_object_type(), + 'post_status' => 'publish', + ]; + + $saved = wp_update_post( $post_data ); + + if ( is_int( $saved ) && 0 < $saved ) { + // Remove any other references. + $object_collection = Store::get_instance(); + $object_collection->unregister_object( $object ); + + $object->set_arg( 'id', $saved ); + + $this->save_args( $object ); + + return parent::save_object( $object ); + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function get_args( Whatsit $object ) { + $id = $object->get_id(); + + if ( empty( $id ) ) { + return parent::get_args( $object ); + } + + $meta = get_post_meta( $id ); + + $args = []; + + foreach ( $meta as $meta_key => $meta_value ) { + if ( in_array( $meta_key, $this->primary_args, true ) ) { + continue; + } + + $meta_value = array_map( 'maybe_unserialize', $meta_value ); + + if ( 1 === count( $meta_value ) ) { + $meta_value = reset( $meta_value ); + } + + // Skip empties. + if ( in_array( $meta_value, [ '', [] ], true ) ) { + continue; + } + + $args[ $meta_key ] = $meta_value; + + $object->set_arg( $meta_key, $meta_value ); + } + + return $args; + } + + /** + * {@inheritdoc} + */ + public function save_args( Whatsit $object ) { + $id = $object->get_id(); + + if ( empty( $id ) ) { + return parent::save_args( $object ); + } + + $args = $object->get_args(); + + $excluded = [ + 'object_type', + 'storage_type', + 'id', + 'name', + 'label', + 'description', + 'parent', + ]; + + $excluded = array_merge( $excluded, array_values( $this->primary_args ) ); + + foreach ( $excluded as $exclude ) { + if ( isset( $args[ $exclude ] ) ) { + unset( $args[ $exclude ] ); + } + } + + if ( empty( $args ) ) { + return false; + } + + foreach ( $args as $arg => $value ) { + update_post_meta( $id, $arg, $value ); + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function delete_object( Whatsit $object ) { + $id = $object->get_id(); + + if ( empty( $id ) ) { + return parent::delete_object( $object ); + } + + $deleted = wp_delete_post( $id, true ); + + if ( false !== $deleted && ! is_wp_error( $deleted ) ) { + return parent::delete_object( $object ); + } + + return false; + } + + /** + * Setup object from a Post ID or Post object. + * + * @param \WP_Post|array|int $post Post object or ID of the object. + * @param bool $force_refresh Whether to force the refresh of the object. + * + * @return Whatsit|null + */ + public function to_object( $post, $force_refresh = false ) { + if ( null !== $post && ! $post instanceof \WP_Post ) { + $post = get_post( $post ); + } + + if ( empty( $post ) ) { + return null; + } + + if ( ! $post || is_wp_error( $post ) ) { + return null; + } + + $object_collection = Store::get_instance(); + + // Check if we already have an object registered and available. + $object = $object_collection->get_object( $post->ID ); + + if ( $object instanceof Whatsit && $post->post_type === '_pods_' . $object->get_object_type() ) { + if ( ! $force_refresh ) { + return $object; + } + + $object_collection->unregister_object( $object ); + } + + $args = []; + + foreach ( $this->primary_args as $object_arg => $arg ) { + $args[ $arg ] = ''; + + if ( isset( $post->{$object_arg} ) ) { + $args[ $arg ] = $post->{$object_arg}; + } + } + + $object_type = substr( $post->post_type, strlen( '_pods_' ) ); + + $class_name = $object_collection->get_object_type( $object_type ); + + if ( ! $class_name || ! class_exists( $class_name ) ) { + return null; + } + + /** @var Whatsit $object */ + $object = new $class_name( $args ); + + $this->get_args( $object ); + + $object->set_arg( 'storage_type', $this->get_storage_type() ); + + if ( $object->is_valid() ) { + $object_collection->register_object( $object ); + } + + return $object; + } + +} diff --git a/src/Pods/Whatsit/Store.php b/src/Pods/Whatsit/Store.php new file mode 100644 index 0000000000..baf49a1830 --- /dev/null +++ b/src/Pods/Whatsit/Store.php @@ -0,0 +1,624 @@ +object_types = $this->get_default_object_types(); + $this->storage_types = $this->get_default_storage_types(); + $this->objects = $this->get_default_objects(); + } + + /** + * Get list of default object type classes. + * + * @return string[] List of object type classes. + */ + public function get_default_object_types() { + return [ + 'pod' => Pod::class, + 'field' => Field::class, + 'object-field' => Object_Field::class, + 'group' => Group::class, + 'template' => Template::class, + 'page' => Page::class, + 'block' => Block::class, + 'block-field' => Block_Field::class, + 'block-collection' => Block_Collection::class, + ]; + } + + /** + * Get list of default storage type classes. + * + * @return string[] List of storage type classes. + */ + public function get_default_storage_types() { + return [ + 'collection' => Collection::class, + 'post_type' => Post_Type::class, + ]; + } + + /** + * Get list of default objects. + * + * @return array List of objects. + */ + public function get_default_objects() { + return [ + 'pod/_pods_pod' => [ + 'internal' => true, + 'object_type' => 'pod', + 'storage_type' => 'collection', + 'name' => '_pods_pod', + 'label' => __( 'Pod', 'pods' ), + 'description' => __( 'Pod configuration', 'pods' ), + 'type' => 'post_type', + ], + 'pod/_pods_group' => [ + 'internal' => true, + 'object_type' => 'pod', + 'storage_type' => 'collection', + 'name' => '_pods_group', + 'label' => __( 'Pod Group', 'pods' ), + 'description' => __( 'Pod Group configuration', 'pods' ), + 'type' => 'post_type', + ], + 'pod/_pods_field' => [ + 'internal' => true, + 'object_type' => 'pod', + 'storage_type' => 'collection', + 'name' => '_pods_field', + 'label' => __( 'Pod Field', 'pods' ), + 'description' => __( 'Pod Field configuration', 'pods' ), + 'type' => 'post_type', + ], + 'pod/_pods_template' => [ + 'internal' => true, + 'object_type' => 'pod', + 'storage_type' => 'collection', + 'name' => '_pods_template', + 'label' => __( 'Pod Template', 'pods' ), + 'description' => __( 'Pod Template configuration', 'pods' ), + 'type' => 'post_type', + ], + 'pod/_pods_page' => [ + 'internal' => true, + 'object_type' => 'pod', + 'storage_type' => 'collection', + 'name' => '_pods_page', + 'label' => __( 'Pod Page', 'pods' ), + 'description' => __( 'Pod Page configuration', 'pods' ), + 'type' => 'post_type', + ], + ]; + } + + /** + * Get the Store instance. + * + * @param int|null $blog_id The blog ID for the Store instance. + * + * @return self The Store instance. + */ + public static function get_instance( $blog_id = null ) { + if ( null === $blog_id ) { + $blog_id = get_current_blog_id(); + } + + if ( ! isset( self::$instances[ $blog_id ] ) ) { + self::$instances[ $blog_id ] = new self(); + } + + return self::$instances[ $blog_id ]; + } + + /** + * Destroy the Store instance. + * + * @param int|null $blog_id The blog ID for the Store instance. + */ + public static function destroy( $blog_id = null ) { + if ( null === $blog_id ) { + self::$instances = []; + } elseif ( isset( self::$instances[ $blog_id ] ) ) { + unset( self::$instances[ $blog_id ] ); + } + } + + /** + * Register an object type to collection. + * + * @param string $object_type Pods object type. + * @param string $class_name Object class name. + */ + public function register_object_type( $object_type, $class_name ) { + $this->object_types[ $object_type ] = $class_name; + } + + /** + * Unregister an object type to collection. + * + * @param string $object_type Pods object type. + * + * @return boolean Whether the object type was successfully unregistered. + */ + public function unregister_object_type( $object_type ) { + $defaults = $this->get_default_object_types(); + + if ( isset( $defaults[ $object_type ] ) ) { + return false; + } + + if ( isset( $this->object_types[ $object_type ] ) ) { + unset( $this->object_types[ $object_type ] ); + + return true; + } + + return false; + } + + /** + * Remove all object types from collection. + */ + public function flush_object_types() { + $this->object_types = $this->get_default_object_types(); + } + + /** + * Get list of object types. + * + * @return array List of object types. + */ + public function get_object_types() { + return $this->object_types; + } + + /** + * Register an object storage type to collection. + * + * @param string $storage_type Pods object storage type. + * @param string|Storage $class_name Object storage class name or object. + */ + public function register_storage_type( $storage_type, $class_name ) { + if ( $class_name instanceof Storage ) { + $this->storage_engine[ $storage_type ] = clone $class_name; + + $class_name = get_class( $class_name ); + } + + $this->storage_types[ $storage_type ] = $class_name; + } + + /** + * Unregister an object storage type to collection. + * + * @param string $storage_type Pods object storage type. + * + * @return boolean Whether the object storage type was successfully unregistered. + */ + public function unregister_storage_type( $storage_type ) { + $defaults = $this->get_default_storage_types(); + + if ( isset( $defaults[ $storage_type ] ) ) { + return false; + } + + if ( isset( $this->storage_types[ $storage_type ] ) ) { + unset( $this->storage_types[ $storage_type ] ); + + if ( isset( $this->storage_engine[ $storage_type ] ) ) { + unset( $this->storage_engine[ $storage_type ] ); + } + + return true; + } + + return false; + } + + /** + * Remove all object storage types from collection. + */ + public function flush_storage_types() { + $this->storage_types = $this->get_default_storage_types(); + + // Remove all storage engines that have been flushed exist. + foreach ( $this->storage_engine as $storage_type => $engine ) { + if ( isset( $this->storage_types[ $storage_type ] ) ) { + continue; + } + + unset( $this->storage_engine[ $storage_type ] ); + } + } + + /** + * Get list of object storage types. + * + * @return array List of object storage types. + */ + public function get_storage_types() { + return $this->storage_types; + } + + /** + * Register an object to collection. + * + * @param Whatsit|array $object Pods object. + */ + public function register_object( $object ) { + $id = null; + $identifier = null; + $storage_type = 'collection'; + + if ( $object instanceof Whatsit ) { + $id = $object->get_id(); + $identifier = $object->get_identifier(); + $storage_type = $object->get_storage_type(); + } elseif ( is_array( $object ) ) { + if ( ! empty( $object['id'] ) ) { + $id = $object['id']; + } + + if ( ! empty( $object['storage_type'] ) ) { + $storage_type = $object['storage_type']; + } + + $identifier = Whatsit::get_identifier_from_args( $object ); + } else { + // Don't register this object. + return; + } + + // Store ids for reference. + if ( '' !== $id && null !== $id ) { + $this->object_ids[ $id ] = $identifier; + + if ( ! isset( $this->objects_in_storage[ $storage_type ] ) ) { + $this->objects_in_storage[ $storage_type ] = []; + } + + $this->objects_in_storage[ $storage_type ][] = $identifier; + } + + if ( $object instanceof Whatsit ) { + $object = clone $object; + } + + $this->objects[ $identifier ] = $object; + } + + /** + * Remove all objects from collection. + */ + public function flush_objects() { + $default_objects = $this->get_default_objects(); + + foreach ( $this->objects as $identifier => $object ) { + if ( isset( $default_objects[ $identifier ] ) ) { + continue; + } + + $this->unregister_object( $object ); + } + } + + /** + * Unregister an object to collection. + * + * @param string|Whatsit|array $identifier Object identifier, ID, or Pods object instance. + * + * @return boolean Whether the object was successfully unregistered. + */ + public function unregister_object( $identifier ) { + $defaults = $this->get_default_objects(); + + if ( $identifier instanceof Whatsit ) { + $id = $identifier->get_id(); + $identifier = $identifier->get_identifier(); + } else { + // This might be an ID. + $id = $identifier; + } + + if ( isset( $this->object_ids[ $id ] ) ) { + // If this was an ID lookup, set the identifier for removal. + if ( $identifier !== $this->object_ids[ $id ] ) { + $identifier = $this->object_ids[ $id ]; + } + + unset( $this->object_ids[ $id ] ); + } + + if ( isset( $this->objects[ $identifier ] ) ) { + if ( isset( $defaults[ $identifier ] ) ) { + return false; + } + + $object = $this->objects[ $identifier ]; + + $storage_type = 'collection'; + + if ( is_array( $object ) ) { + if ( ! empty( $object['storage_type'] ) ) { + $storage_type = $object['storage_type']; + } + } elseif ( $object instanceof Whatsit ) { + $storage_type = $object->get_storage_type(); + } else { + return false; + } + + // Ensure reference gets killed. + $object = null; + $this->objects[ $identifier ] = null; + + unset( $this->objects[ $identifier ] ); + + if ( ! empty( $this->objects_in_storage[ $storage_type ] ) ) { + $key = array_search( $identifier, $this->objects_in_storage[ $storage_type ], true ); + + if ( false !== $key ) { + unset( $this->objects_in_storage[ $storage_type ][ $key ] ); + } + } + + return true; + }//end if + + return false; + } + + /** + * Flatten objects so that PHP objects are removed but are still registered. + */ + public function flatten_objects() { + foreach ( $this->objects as $identifier => $object ) { + if ( ! $object instanceof Whatsit ) { + continue; + } + + // Ensure reference gets killed. + $object = null; + + $this->flatten_object( $identifier ); + } + } + + /** + * Flatten objects so that PHP objects are removed but are still registered. + */ + public function flatten_object( $identifier ) { + if ( $identifier instanceof Whatsit ) { + $identifier = $identifier->get_identifier(); + } + + if ( ! isset( $this->objects[ $identifier ] ) ) { + return; + } + + if ( ! $this->objects[ $identifier ] instanceof Whatsit ) { + return; + } + + $this->objects[ $identifier ] = $this->objects[ $identifier ]->get_args(); + } + + /** + * Delete all objects and then flush them from collection. + */ + public function delete_objects() { + $default_objects = $this->get_default_objects(); + + foreach ( $this->objects as $identifier => $object ) { + if ( isset( $default_objects[ $identifier ] ) ) { + continue; + } + + // Delete from storage. + $storage_type = $object->get_storage_type(); + + if ( empty( $storage_type ) ) { + $storage_type = 'collection'; + } + + $storage_object = $this->get_storage_object( $storage_type ); + + if ( $storage_object ) { + $storage_object->delete( $object ); + } + + $this->unregister_object( $object ); + } + } + + /** + * Get storage type object. + * + * @param string $storage_type Object storage type. + * + * @return Storage Storage type object. + */ + public function get_storage_object( $storage_type ) { + if ( isset( $this->storage_engine[ $storage_type ] ) ) { + return $this->storage_engine[ $storage_type ]; + } + + $class_name = $this->get_storage_type( $storage_type ); + + if ( ! $class_name || ! class_exists( $class_name ) ) { + return null; + } + + $storage_object = new $class_name(); + + $this->storage_engine[ $storage_type ] = $storage_object; + + return $storage_object; + } + + /** + * Get object storage type class. + * + * @param string $storage_type Object storage type. + * + * @return string Storage type class. + */ + public function get_storage_type( $storage_type ) { + if ( isset( $this->storage_types[ $storage_type ] ) ) { + return $this->storage_types[ $storage_type ]; + } + + return null; + } + + /** + * Get objects from collection. + * + * @return Whatsit[] List of objects. + */ + public function get_objects() { + $objects = array_map( [ $this, 'get_object' ], $this->objects ); + $objects = array_filter( $objects ); + + return $objects; + } + + /** + * Get object from collection. + * + * @param string|null|Whatsit|array $identifier Object identifier, ID, or the object/array itself. + * + * @return Whatsit|null Object or null if not found. + */ + public function get_object( $identifier ) { + // Is this already an object? + if ( $identifier instanceof Whatsit ) { + return $this->setup_object( $identifier ); + } + + // Is this an object config array? + if ( is_array( $identifier ) ) { + return $this->setup_object( $identifier ); + } + + // This might be an ID. + $id = $identifier; + + if ( isset( $this->object_ids[ $id ] ) ) { + $identifier = $this->object_ids[ $id ]; + } + + if ( isset( $this->objects[ $identifier ] ) ) { + $object = $this->objects[ $identifier ]; + + return $this->setup_object( $object ); + } + + return null; + } + + /** + * Setup object if it needs to be. + * + * @param Whatsit|array $object Pods object or array. + * + * @return Whatsit|null Pods object or null if not able to setup. + */ + public function setup_object( $object ) { + if ( $object instanceof Whatsit ) { + return $object; + } + + if ( ! is_array( $object ) ) { + return null; + } + + $args = $object; + + if ( ! isset( $args['object_type'] ) ) { + return null; + } + + $class_name = $this->get_object_type( $args['object_type'] ); + + if ( ! $class_name || ! class_exists( $class_name ) ) { + return null; + } + + /** @var Whatsit $object */ + $object = new $class_name(); + $object->setup( $args ); + + $this->objects[ $object->get_identifier() ] = $object; + + return $object; + } + + /** + * Get object type class. + * + * @param string $object_type Object type. + * + * @return string Object type class. + */ + public function get_object_type( $object_type ) { + if ( isset( $this->object_types[ $object_type ] ) ) { + return $this->object_types[ $object_type ]; + } + + return null; + } + +} diff --git a/src/Pods/Whatsit/Template.php b/src/Pods/Whatsit/Template.php new file mode 100644 index 0000000000..a6a875f605 --- /dev/null +++ b/src/Pods/Whatsit/Template.php @@ -0,0 +1,17 @@ +plugin_file = $_plugin_file; + $this->home_url = trailingslashit( $_home_url ); + + // If the filename is 'functions' then we're tracking a theme + if ( basename( $this->plugin_file, '.php' ) != 'functions' ) { + $this->plugin_name = ! empty( $_plugin_slug ) ? $_plugin_slug : basename( $this->plugin_file, '.php' ); + } else { + $this->what_am_i = 'theme'; + $theme = wp_get_theme(); + if ( $theme->Name ) { + $this->plugin_name = sanitize_text_field( $theme->Name ); + } + } + + $this->options = $_options; + $this->require_optin = $_require_optin; + $this->include_goodbye_form = $_include_goodbye_form; + $this->marketing = $_marketing; + + // Only use this on switching theme + $this->theme_allows_tracking = get_theme_mod( 'wisdom-allow-tracking', 0 ); + + // Schedule / deschedule tracking when activated / deactivated + if ( $this->what_am_i == 'theme' ) { + // Need to think about scheduling for sites that have already activated the theme + add_action( 'after_switch_theme', [ $this, 'schedule_tracking' ] ); + add_action( 'switch_theme', [ $this, 'deactivate_this_plugin' ] ); + } else { + register_activation_hook( $this->plugin_file, [ $this, 'schedule_tracking' ] ); + register_deactivation_hook( $this->plugin_file, [ $this, 'deactivate_this_plugin' ] ); + } + + // Get it going + $this->init(); + } + + public function init() { + // Check marketing + if ( $this->marketing == 3 ) { + $this->set_can_collect_email( true, $this->plugin_name ); + } + + // Check whether opt-in is required + // If not, then tracking is allowed + if ( ! $this->require_optin ) { + $this->set_can_collect_email( true, $this->plugin_name ); + $this->set_is_tracking_allowed( true ); + $this->update_block_notice(); + $this->do_tracking(); + } + + // Hook our do_tracking function to the weekly action + add_filter( 'cron_schedules', [ $this, 'schedule_weekly_event' ] ); + // It's called weekly, but in fact it could be daily, weekly or monthly + add_action( 'put_do_weekly_action', [ $this, 'do_tracking' ] ); + + // Use this action for local testing + // add_action( 'admin_init', array( $this, 'do_tracking' ) ); + + // Display the admin notice on activation + add_action( 'admin_init', [ $this, 'set_notification_time' ] ); + add_action( 'admin_notices', [ $this, 'optin_notice' ] ); + add_action( 'admin_notices', [ $this, 'marketing_notice' ] ); + + // Deactivation + add_filter( 'plugin_action_links_' . plugin_basename( $this->plugin_file ), [ $this, 'filter_action_links' ] ); + add_action( 'admin_footer-plugins.php', [ $this, 'goodbye_ajax' ] ); + add_action( 'wp_ajax_goodbye_form', [ $this, 'goodbye_form_callback' ] ); + } + + /** + * When the plugin is activated + * Create scheduled event + * And check if tracking is enabled - perhaps the plugin has been reactivated + * + * @since 1.0.0 + */ + public function schedule_tracking() { + if ( ! wp_next_scheduled( 'put_do_weekly_action' ) ) { + $schedule = $this->get_schedule(); + wp_schedule_event( time(), $schedule, 'put_do_weekly_action' ); + } + $this->do_tracking( true ); + } + + /** + * Create weekly schedule + * + * @since 1.2.3 + */ + public function schedule_weekly_event( $schedules ) { + $schedules['weekly'] = [ + 'interval' => 604800, + 'display' => __( 'Once Weekly' ), + ]; + $schedules['monthly'] = [ + 'interval' => 2635200, + 'display' => __( 'Once Monthly' ), + ]; + + return $schedules; + } + + /** + * Get how frequently data is tracked back + * + * @since 1.2.3 + */ + public function get_schedule() { + // Could be daily, weekly or monthly + $schedule = apply_filters( 'wisdom_filter_schedule_' . $this->plugin_name, 'monthly' ); + + return $schedule; + } + + /** + * This is our function to get everything going + * Check that user has opted in + * Collect data + * Then send it back + * + * @since 1.0.0 + * + * @param $force Force tracking if it's not time + */ + public function do_tracking( $force = false ) { + // If the home site hasn't been defined, we just drop out. Nothing much we can do. + if ( ! $this->home_url ) { + return; + } + + // Check to see if the user has opted in to tracking + $allow_tracking = $this->get_is_tracking_allowed(); + if ( ! $allow_tracking ) { + return; + } + + // Check to see if it's time to track + $track_time = $this->get_is_time_to_track(); + if ( ! $track_time && ! $force ) { + return; + } + + $this->set_admin_email(); + + // Get our data + $body = $this->get_data(); + + // Send the data + $this->send_data( $body ); + } + + /** + * We hook this to admin_init when the user accepts tracking + * Ensures the email address is available + * + * @since 1.2.1 + */ + public function force_tracking() { + $this->do_tracking( true ); // Run this straightaway + } + + /** + * Send the data to the home site + * + * @since 1.0.0 + */ + public function send_data( $body ) { + $request = wp_remote_post( esc_url( $this->home_url . '?usage_tracker=hello' ), [ + 'method' => 'POST', + 'timeout' => 20, + 'redirection' => 5, + 'httpversion' => '1.1', + 'blocking' => true, + 'body' => $body, + 'user-agent' => 'PUT/1.0.0; ' . home_url(), + ] ); + + $this->set_track_time(); + + if ( is_wp_error( $request ) ) { + return $request; + } + } + + /** + * Here we collect most of the data + * + * @since 1.0.0 + */ + public function get_data() { + // Use this to pass error messages back if necessary + $body['message'] = ''; + + // Use this array to send data back + $body = [ + 'plugin_slug' => sanitize_text_field( $this->plugin_name ), + 'url' => home_url(), + 'site_name' => get_bloginfo( 'name' ), + 'site_version' => get_bloginfo( 'version' ), + 'site_language' => get_bloginfo( 'language' ), + 'charset' => get_bloginfo( 'charset' ), + 'wisdom_version' => $this->wisdom_version, + 'php_version' => phpversion(), + 'multisite' => is_multisite(), + 'file_location' => __FILE__, + 'product_type' => esc_html( $this->what_am_i ), + ]; + + // Collect the email if the correct option has been set + if ( $this->get_can_collect_email() ) { + $body['email'] = $this->get_admin_email(); + } + $body['marketing_method'] = $this->marketing; + + $body['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : ''; + + // Extra PHP fields + $body['memory_limit'] = ini_get( 'memory_limit' ); + $body['upload_max_size'] = ini_get( 'upload_max_size' ); + $body['post_max_size'] = ini_get( 'post_max_size' ); + $body['upload_max_filesize'] = ini_get( 'upload_max_filesize' ); + $body['max_execution_time'] = ini_get( 'max_execution_time' ); + $body['max_input_time'] = ini_get( 'max_input_time' ); + + // Retrieve current plugin information + if ( ! function_exists( 'get_plugins' ) ) { + include ABSPATH . '/wp-admin/includes/plugin.php'; + } + + $plugins = array_keys( get_plugins() ); + $active_plugins = get_option( 'active_plugins', [] ); + + foreach ( $plugins as $key => $plugin ) { + if ( in_array( $plugin, $active_plugins ) ) { + // Remove active plugins from list so we can show active and inactive separately + unset( $plugins[ $key ] ); + } + } + + $body['active_plugins'] = $active_plugins; + $body['inactive_plugins'] = $plugins; + + // Check text direction + $body['text_direction'] = 'LTR'; + if ( function_exists( 'is_rtl' ) ) { + if ( is_rtl() ) { + $body['text_direction'] = 'RTL'; + } + } else { + $body['text_direction'] = 'not set'; + } + + /** + * Get our plugin data + * Currently we grab plugin name and version + * Or, return a message if the plugin data is not available + * + * @since 1.0.0 + */ + $plugin = $this->plugin_data(); + $body['status'] = 'Active'; // Never translated + if ( empty( $plugin ) ) { + // We can't find the plugin data + // Send a message back to our home site + $body['message'] .= __( 'We can\'t detect any product information. This is most probably because you have not included the code snippet.', 'singularity' ); + $body['status'] = 'Data not found'; // Never translated + } else { + if ( isset( $plugin['Name'] ) ) { + $body['plugin'] = sanitize_text_field( $plugin['Name'] ); + } + if ( isset( $plugin['Version'] ) ) { + $body['version'] = sanitize_text_field( $plugin['Version'] ); + } + } + + /** + * Get our plugin options + * + * @since 1.0.0 + */ + $options = $this->options; + $plugin_options = []; + if ( ! empty( $options ) && is_array( $options ) ) { + foreach ( $options as $option ) { + $fields = get_option( $option ); + // Check for permission to send this option + if ( isset( $fields['wisdom_registered_setting'] ) ) { + foreach ( $fields as $key => $value ) { + $plugin_options[ $key ] = $value; + } + } + } + } + $body['plugin_options'] = $this->options; // Returns array + $body['plugin_options_fields'] = $plugin_options; // Returns object + + /** + * Get our theme data + * Currently we grab theme name and version + * + * @since 1.0.0 + */ + $theme = wp_get_theme(); + if ( $theme->Name ) { + $body['theme'] = sanitize_text_field( $theme->Name ); + } + if ( $theme->Version ) { + $body['theme_version'] = sanitize_text_field( $theme->Version ); + } + if ( $theme->Template ) { + $body['theme_parent'] = sanitize_text_field( $theme->Template ); + } + + // Return the data + return $body; + } + + /** + * Return plugin data + * + * @since 1.0.0 + */ + public function plugin_data() { + // Being cautious here + if ( ! function_exists( 'get_plugin_data' ) ) { + include ABSPATH . '/wp-admin/includes/plugin.php'; + } + // Retrieve current plugin information + $plugin = get_plugin_data( $this->plugin_file ); + + return $plugin; + } + + /** + * Deactivating plugin + * + * @since 1.0.0 + */ + public function deactivate_this_plugin() { + // Check to see if the user has opted in to tracking + if ( $this->what_am_i == 'theme' ) { + $allow_tracking = $this->theme_allows_tracking; + } else { + $allow_tracking = $this->get_is_tracking_allowed(); + } + + if ( ! $allow_tracking ) { + return; + } + + $body = $this->get_data(); + $body['status'] = 'Deactivated'; // Never translated + $body['deactivated_date'] = time(); + + // Add deactivation form data + if ( false !== get_option( 'wisdom_deactivation_reason_' . $this->plugin_name ) ) { + $body['deactivation_reason'] = get_option( 'wisdom_deactivation_reason_' . $this->plugin_name ); + } + if ( false !== get_option( 'wisdom_deactivation_details_' . $this->plugin_name ) ) { + $body['deactivation_details'] = get_option( 'wisdom_deactivation_details_' . $this->plugin_name ); + } + + $this->send_data( $body ); + // Clear scheduled update + wp_clear_scheduled_hook( 'put_do_weekly_action' ); + + // Clear the wisdom_last_track_time value for this plugin + // @since 1.2.2 + $track_time = get_option( 'wisdom_last_track_time' ); + if ( isset( $track_time[ $this->plugin_name ] ) ) { + unset( $track_time[ $this->plugin_name ] ); + } + update_option( 'wisdom_last_track_time', $track_time ); + } + + /** + * Is tracking allowed? + * + * @since 1.0.0 + */ + public function get_is_tracking_allowed() { + // First, check if the user has changed their mind and opted out of tracking + if ( $this->has_user_opted_out() ) { + $this->set_is_tracking_allowed( false, $this->plugin_name ); + // SKC modification for Pods. + $this->set_can_collect_email( false, $this->plugin_name ); + + return false; + } + + if ( $this->what_am_i == 'theme' ) { + $mod = get_theme_mod( 'wisdom-allow-tracking', 0 ); + if ( $mod ) { + return true; + } + } else { + // The wisdom_allow_tracking option is an array of plugins that are being tracked + $allow_tracking = get_option( 'wisdom_allow_tracking' ); + // If this plugin is in the array, then tracking is allowed + if ( isset( $allow_tracking[ $this->plugin_name ] ) ) { + return true; + } + } + + return false; + } + + /** + * Set if tracking is allowed + * Option is an array of all plugins with tracking permitted + * More than one plugin may be using the tracker + * + * @since 1.0.0 + * + * @param $is_allowed Boolean true if tracking is allowed, false if not + */ + public function set_is_tracking_allowed( $is_allowed, $plugin = null ) { + if ( empty( $plugin ) ) { + $plugin = $this->plugin_name; + } + + // The wisdom_allow_tracking option is an array of plugins that are being tracked + $allow_tracking = get_option( 'wisdom_allow_tracking' ); + + // If the user has decided to opt out + if ( $this->has_user_opted_out() ) { + if ( $this->what_am_i == 'theme' ) { + set_theme_mod( 'wisdom-allow-tracking', 0 ); + } else { + if ( isset( $allow_tracking[ $plugin ] ) ) { + unset( $allow_tracking[ $plugin ] ); + } + } + } elseif ( $is_allowed || ! $this->require_optin ) { + // If the user has agreed to allow tracking or if opt-in is not required + + if ( $this->what_am_i == 'theme' ) { + set_theme_mod( 'wisdom-allow-tracking', 1 ); + } else { + if ( empty( $allow_tracking ) || ! is_array( $allow_tracking ) ) { + // If nothing exists in the option yet, start a new array with the plugin name + $allow_tracking = [ $plugin => $plugin ]; + } else { + // Else add the plugin name to the array + $allow_tracking[ $plugin ] = $plugin; + } + } + } else { + if ( $this->what_am_i == 'theme' ) { + set_theme_mod( 'wisdom-allow-tracking', 0 ); + } else { + if ( isset( $allow_tracking[ $plugin ] ) ) { + unset( $allow_tracking[ $plugin ] ); + } + } + } + + update_option( 'wisdom_allow_tracking', $allow_tracking ); + } + + /** + * Has the user opted out of allowing tracking? + * Note that themes are opt in / plugins are opt out + * + * @since 1.1.0 + * @return Boolean + */ + public function has_user_opted_out() { + // Different opt-out methods for plugins and themes + if ( $this->what_am_i == 'theme' ) { + // Look for the theme mod + $mod = get_theme_mod( 'wisdom-allow-tracking', 0 ); + if ( false === $mod ) { + // If the theme mod is not set, then return true - the user has opted out + return true; + } + } else { + // Iterate through the options that are being tracked looking for wisdom_opt_out setting + if ( ! empty( $this->options ) ) { + foreach ( $this->options as $option_name ) { + // Check each option + $options = get_option( $option_name ); + // If we find the setting, return true + if ( ! empty( $options['wisdom_opt_out'] ) ) { + return true; + } + } + } + } + + return false; + } + + /** + * Check if it's time to track + * + * @since 1.1.1 + */ + public function get_is_time_to_track() { + // Let's see if we're due to track this plugin yet + $track_times = get_option( 'wisdom_last_track_time', [] ); + if ( ! isset( $track_times[ $this->plugin_name ] ) ) { + // If we haven't set a time for this plugin yet, then we must track it + return true; + } else { + // If the time is set, let's get our schedule and check if it's time to track + $schedule = $this->get_schedule(); + if ( $schedule == 'daily' ) { + $period = 'day'; + } elseif ( $schedule == 'weekly' ) { + $period = 'week'; + } else { + $period = 'month'; + } + if ( $track_times[ $this->plugin_name ] < strtotime( '-1 ' . $period ) ) { + return true; + } + } + + return false; + } + + /** + * Record the time we send tracking data + * + * @since 1.1.1 + */ + public function set_track_time() { + // We've tracked, so record the time + $track_times = get_option( 'wisdom_last_track_time', [] ); + // Set different times according to plugin, in case we are tracking multiple plugins + $track_times[ $this->plugin_name ] = time(); + update_option( 'wisdom_last_track_time', $track_times ); + } + + /** + * Set the time when we can display the opt-in notification + * Will display now unless filtered + * + * @since 1.2.4 + */ + public function set_notification_time() { + $notification_times = get_option( 'wisdom_notification_times', [] ); + // Set different times according to plugin, in case we are tracking multiple plugins + if ( ! isset( $notification_times[ $this->plugin_name ] ) ) { + $delay_notification = apply_filters( 'wisdom_delay_notification_' . $this->plugin_name, 0 ); + // We can delay the notification time + $notification_time = time() + absint( $delay_notification ); + $notification_times[ $this->plugin_name ] = $notification_time; + update_option( 'wisdom_notification_times', $notification_times ); + } + } + + /** + * Get whether it's time to display the notification + * + * @since 1.2.4 + * @return Boolean + */ + public function get_is_notification_time() { + $notification_times = get_option( 'wisdom_notification_times', [] ); + $time = time(); + // Set different times according to plugin, in case we are tracking multiple plugins + if ( isset( $notification_times[ $this->plugin_name ] ) ) { + $notification_time = $notification_times[ $this->plugin_name ]; + if ( $time >= $notification_time ) { + return true; + } + } + + return false; + } + + /** + * Set if we should block the opt-in notice for this plugin + * Option is an array of all plugins that have received a response from the user + * + * @since 1.0.0 + */ + public function update_block_notice( $plugin = null ) { + if ( empty( $plugin ) ) { + $plugin = $this->plugin_name; + } + $block_notice = get_option( 'wisdom_block_notice' ); + if ( empty( $block_notice ) || ! is_array( $block_notice ) ) { + // If nothing exists in the option yet, start a new array with the plugin name + $block_notice = [ $plugin => $plugin ]; + } else { + // Else add the plugin name to the array + $block_notice[ $plugin ] = $plugin; + } + update_option( 'wisdom_block_notice', $block_notice ); + } + + /** + * Can we collect the email address? + * + * @since 1.0.0 + */ + public function get_can_collect_email() { + // The wisdom_collect_email option is an array of plugins that are being tracked + $collect_email = get_option( 'wisdom_collect_email' ); + // If this plugin is in the array, then we can collect the email address + if ( isset( $collect_email[ $this->plugin_name ] ) ) { + return true; + } + + return false; + } + + /** + * Set if user has allowed us to collect their email address + * Option is an array of all plugins with email collection permitted + * More than one plugin may be using the tracker + * + * @since 1.0.0 + * + * @param $can_collect Boolean true if collection is allowed, false if not + */ + public function set_can_collect_email( $can_collect, $plugin = null ) { + if ( empty( $plugin ) ) { + $plugin = $this->plugin_name; + } + // The wisdom_collect_email option is an array of plugins that are being tracked + $collect_email = get_option( 'wisdom_collect_email' ); + // If the user has agreed to allow tracking or if opt-in is not required + if ( $can_collect ) { + if ( empty( $collect_email ) || ! is_array( $collect_email ) ) { + // If nothing exists in the option yet, start a new array with the plugin name + $collect_email = [ $plugin => $plugin ]; + } else { + // Else add the plugin name to the array + $collect_email[ $plugin ] = $plugin; + } + } else { + if ( isset( $collect_email[ $plugin ] ) ) { + unset( $collect_email[ $plugin ] ); + } + } + update_option( 'wisdom_collect_email', $collect_email ); + } + + /** + * Get the correct email address to use + * + * @since 1.1.2 + * @return Email address + */ + public function get_admin_email() { + // The wisdom_collect_email option is an array of plugins that are being tracked + $email = get_option( 'wisdom_admin_emails' ); + // If this plugin is in the array, then we can collect the email address + if ( isset( $email[ $this->plugin_name ] ) ) { + return $email[ $this->plugin_name ]; + } + + return false; + } + + /** + * Set the correct email address to use + * There might be more than one admin on the site + * So we only use the first admin's email address + * + * @since 1.1.2 + * + * @param $plugin Plugin name to set email address for + * @param $email Email address to set + */ + public function set_admin_email( $email = null, $plugin = null ) { + if ( empty( $plugin ) ) { + $plugin = $this->plugin_name; + } + // If no email address passed, try to get the current user's email + if ( empty( $email ) ) { + // Have to check that current user object is available + if ( function_exists( 'wp_get_current_user' ) ) { + $current_user = wp_get_current_user(); + $email = $current_user->user_email; + } + } + // The wisdom_admin_emails option is an array of admin email addresses + $admin_emails = get_option( 'wisdom_admin_emails' ); + if ( empty( $admin_emails ) || ! is_array( $admin_emails ) ) { + // If nothing exists in the option yet, start a new array with the plugin name + $admin_emails = [ $plugin => sanitize_email( $email ) ]; + } elseif ( empty( $admin_emails[ $plugin ] ) ) { + // Else add the email address to the array, if not already set + $admin_emails[ $plugin ] = sanitize_email( $email ); + } + update_option( 'wisdom_admin_emails', $admin_emails ); + } + + /** + * Display the admin notice to users to allow them to opt in + * + * @since 1.0.0 + */ + public function optin_notice() { + // Check for plugin args + if ( isset( $_GET['plugin'] ) && isset( $_GET['plugin_action'] ) ) { + $plugin = sanitize_text_field( $_GET['plugin'] ); + $action = sanitize_text_field( $_GET['plugin_action'] ); + if ( $action == 'yes' ) { + $this->set_is_tracking_allowed( true, $plugin ); + // Run this straightaway + add_action( 'admin_init', [ $this, 'force_tracking' ] ); + } else { + $this->set_is_tracking_allowed( false, $plugin ); + } + $this->update_block_notice( $plugin ); + } + + // Is it time to display the notification? + $is_time = $this->get_is_notification_time(); + if ( ! $is_time ) { + return false; + } + + // Check whether to block the notice, e.g. because we're in a local environment + // wisdom_block_notice works the same as wisdom_allow_tracking, an array of plugin names + $block_notice = get_option( 'wisdom_block_notice' ); + + if ( isset( $block_notice[ $this->plugin_name ] ) ) { + return; + } + + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + + // @credit EDD + // Don't bother asking user to opt in if they're in local dev + $is_local = false; + if ( stristr( network_site_url( '/' ), '.dev' ) !== false || stristr( network_site_url( '/' ), 'localhost' ) !== false || stristr( network_site_url( '/' ), ':8888' ) !== false ) { + $is_local = true; + } + $is_local = apply_filters( 'wisdom_is_local_' . $this->plugin_name, $is_local ); + if ( $is_local ) { + $this->update_block_notice(); + + // SKC modification for Pods. + if ( $this->marketing ) { + $this->set_can_collect_email( false ); + } + } else { + // Display the notice requesting permission to track + // Retrieve current plugin information + $plugin = $this->plugin_data(); + $plugin_name = $plugin['Name']; + + // Args to add to query if user opts in to tracking + $yes_args = [ + 'plugin' => $this->plugin_name, + 'plugin_action' => 'yes', + ]; + + // Decide how to request permission to collect email addresses + if ( $this->marketing == 1 ) { + // Option 1 combines permissions to track and collect email + $yes_args['marketing_optin'] = 'yes'; + } elseif ( $this->marketing == 2 ) { + // Option 2 enables a second notice that fires after the user opts in to tracking + $yes_args['marketing'] = 'yes'; + } + $url_yes = add_query_arg( $yes_args ); + $url_no = add_query_arg( [ + 'plugin' => $this->plugin_name, + 'plugin_action' => 'no', + ] ); + + // Decide on notice text + if ( $this->marketing != 1 ) { + // Standard notice text + $notice_text = sprintf( __( 'Thank you for installing our %1$s. We would like to track its usage on your site. We don\'t record any sensitive data, only information regarding the WordPress environment and %1$s settings, which we will use to help us make improvements to the %1$s. Tracking is completely optional.', 'singularity' ), $this->what_am_i ); + } else { + // If we have option 1 for marketing, we include reference to sending product information here + $notice_text = sprintf( __( 'Thank you for installing our %1$s. We\'d like your permission to track its usage on your site and subscribe you to our newsletter. We won\'t record any sensitive data, only information regarding the WordPress environment and %1$s settings, which we will use to help us make improvements to the %1$s. Tracking is completely optional.', 'singularity' ), $this->what_am_i ); + } + // And we allow you to filter the text anyway + $notice_text = apply_filters( 'wisdom_notice_text_' . esc_attr( $this->plugin_name ), $notice_text ); ?> + +
            +

            ' . esc_html( $plugin_name ) . ''; ?>

            +

            +

            + + +

            +
            + set_can_collect_email( sanitize_text_field( $_GET['marketing_optin'] ), $this->plugin_name ); + // Do tracking + $this->do_tracking( true ); + } elseif ( isset( $_GET['marketing'] ) && $_GET['marketing'] == 'yes' ) { + // Display the notice requesting permission to collect email address + // Retrieve current plugin information + $plugin = $this->plugin_data(); + $plugin_name = $plugin['Name']; + + $url_yes = add_query_arg( [ + 'plugin' => $this->plugin_name, + 'marketing_optin' => 'yes', + ] ); + $url_no = add_query_arg( [ + 'plugin' => $this->plugin_name, + 'marketing_optin' => 'no', + ] ); + + $marketing_text = sprintf( __( 'Thank you for opting in to tracking. Would you like to receive occasional news about this %s, including details of new features and special offers?', 'singularity' ), $this->what_am_i ); + $marketing_text = apply_filters( 'wisdom_marketing_text_' . esc_attr( $this->plugin_name ), $marketing_text ); ?> + +
            +

            ' . esc_html( $plugin_name ) . ''; ?>

            +

            +

            + + +

            +
            + get_is_tracking_allowed() ) { + return $links; + } + if ( isset( $links['deactivate'] ) && $this->include_goodbye_form ) { + $deactivation_link = $links['deactivate']; + // Insert an onClick action to allow form before deactivating + $deactivation_link = str_replace( 'form_default_text(); + + return apply_filters( 'wisdom_form_text_' . esc_attr( $this->plugin_name ), $form ); + } + + /** + * Form text strings + * These can be filtered + * + * @since 1.0.0 + */ + public function goodbye_ajax() { + // Get our strings for the form + $form = $this->form_filterable_text(); + if ( ! isset( $form['heading'] ) || ! isset( $form['body'] ) || ! isset( $form['options'] ) || ! is_array( $form['options'] ) || ! isset( $form['details'] ) ) { + // If the form hasn't been filtered correctly, we revert to the default form + $form = $this->form_default_text(); + } + // Build the HTML to go in the form + $html = '
            ' . esc_html( $form['heading'] ) . '
            '; + $html .= '

            ' . esc_html( $form['body'] ) . '

            '; + if ( is_array( $form['options'] ) ) { + $html .= '

            '; + foreach ( $form['options'] as $option ) { + $html .= '
            '; + } + $html .= '

            '; + $html .= '
            '; + } + $html .= '
            '; + $html .= '

            ' . __( 'Submitting form', 'singularity' ) . '

            '; + ?> +
            + + + plugin_name, $values ); + } + if ( isset( $_POST['details'] ) ) { + $details = sanitize_text_field( $_POST['details'] ); + update_option( 'wisdom_deactivation_details_' . $this->plugin_name, $details ); + } + $this->do_tracking(); // Run this straightaway + echo 'success'; + wp_die(); + } + +} diff --git a/tests/codeception/_bootstrap.php b/tests/codeception/_bootstrap.php new file mode 100644 index 0000000000..6590d4878c --- /dev/null +++ b/tests/codeception/_bootstrap.php @@ -0,0 +1,3 @@ +W%Xdk)F/KeT){utDe9_4fU5E-1CD*L`Y+uW~0-qW,q[dl9q6#9BH2I?jX hu?PE^NwcP^3}qF2J^m}(hDb,A=8y!0c','no'),(128,'widget_tag_cloud','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(129,'widget_nav_menu','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(130,'widget_custom_html','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(131,'widget_pods_widget_single','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(132,'widget_pods_widget_list','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(133,'widget_pods_widget_field','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(134,'widget_pods_widget_form','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(135,'widget_pods_widget_view','a:1:{s:12:\"_multiwidget\";i:1;}','yes'),(367,'test_non_pod_ct_children','a:0:{}','yes'),(447,'category_children','a:0:{}','yes'),(462,'permalink_structure','/%postname%/','yes'),(463,'_transient_timeout_tribe_feature_detection','1590804133','no'),(464,'_transient_tribe_feature_detection','a:1:{s:22:\"supports_async_process\";b:0;}','no'),(466,'recovery_keys','a:1:{s:22:\"64OVk5A6aylOpFHLMOJnno\";a:2:{s:10:\"hashed_key\";s:34:\"$P$BhDiyT.n92a/VIY2mQwCNj7htu/MnH/\";s:10:\"created_at\";i:1590200185;}}','yes'),(467,'pods_framework_version_last','2.8.0-a-1','yes'),(468,'pods_framework_version','2.8.0-a-2','yes'),(469,'pods_framework_db_version','2.3.5','yes'),(486,'_transient_doing_cron','1590200352.0339810848236083984375','yes'),(489,'admin_email_lifespan','1605752163','yes'),(490,'db_upgraded','','yes'),(496,'_site_transient_update_core','O:8:\"stdClass\":4:{s:7:\"updates\";a:1:{i:0;O:8:\"stdClass\":10:{s:8:\"response\";s:6:\"latest\";s:8:\"download\";s:59:\"https://downloads.wordpress.org/release/wordpress-5.4.1.zip\";s:6:\"locale\";s:5:\"en_US\";s:8:\"packages\";O:8:\"stdClass\":5:{s:4:\"full\";s:59:\"https://downloads.wordpress.org/release/wordpress-5.4.1.zip\";s:10:\"no_content\";s:70:\"https://downloads.wordpress.org/release/wordpress-5.4.1-no-content.zip\";s:11:\"new_bundled\";s:71:\"https://downloads.wordpress.org/release/wordpress-5.4.1-new-bundled.zip\";s:7:\"partial\";b:0;s:8:\"rollback\";b:0;}s:7:\"current\";s:5:\"5.4.1\";s:7:\"version\";s:5:\"5.4.1\";s:11:\"php_version\";s:6:\"5.6.20\";s:13:\"mysql_version\";s:3:\"5.0\";s:11:\"new_bundled\";s:3:\"5.3\";s:15:\"partial_version\";s:0:\"\";}}s:12:\"last_checked\";i:1590200163;s:15:\"version_checked\";s:5:\"5.4.1\";s:12:\"translations\";a:0:{}}','no'),(497,'_site_transient_update_plugins','O:8:\"stdClass\":5:{s:12:\"last_checked\";i:1590200171;s:7:\"checked\";a:43:{s:49:\"advanced-custom-blocks/advanced-custom-blocks.php\";s:3:\"0.1\";s:30:\"advanced-custom-fields/acf.php\";s:6:\"5.8.11\";s:29:\"acf-extended/acf-extended.php\";s:7:\"0.8.5.5\";s:19:\"akismet/akismet.php\";s:5:\"4.1.5\";s:41:\"anywhere-elementor/anywhere-elementor.php\";s:5:\"1.2.1\";s:33:\"appsero-helper/appsero-helper.php\";s:5:\"1.1.7\";s:24:\"bb-plugin/fl-builder.php\";s:8:\"1.10.5.1\";s:37:\"bb-theme-builder/bb-theme-builder.php\";s:7:\"1.0.1.2\";s:29:\"block-fields/block-fields.php\";s:5:\"0.1.0\";s:33:\"classic-editor/classic-editor.php\";s:3:\"1.5\";s:25:\"easy-query/easy-query.php\";s:5:\"2.0.4\";s:23:\"elementor/elementor.php\";s:5:\"2.9.8\";s:43:\"exports-and-reports/exports-and-reports.php\";s:5:\"0.8.5\";s:17:\"facetwp/index.php\";s:5:\"3.2.3\";s:29:\"facetwp-pods/facetwp-pods.php\";s:3:\"0.1\";s:33:\"github-updater/github-updater.php\";s:5:\"8.5.1\";s:29:\"gravityforms/gravityforms.php\";s:6:\"2.4.17\";s:33:\"gravityforms-2.2/gravityforms.php\";s:5:\"2.2.3\";s:33:\"gravityforms-2.3/gravityforms.php\";s:7:\"2.3.3.9\";s:45:\"gravityformschainedselects/chainedselects.php\";s:3:\"1.1\";s:23:\"gravityformscli/cli.php\";s:3:\"1.2\";s:35:\"gravityformsgutenberg/gutenberg.php\";s:10:\"1.0-beta-2\";s:29:\"gravityformspaypal/paypal.php\";s:3:\"3.1\";s:41:\"gravityformspostcreation/postcreation.php\";s:10:\"1.0-beta-1\";s:29:\"gravityformsstripe/stripe.php\";s:3:\"2.5\";s:23:\"gutenberg/gutenberg.php\";s:5:\"8.1.0\";s:51:\"gutenberg-custom-fields/gutenberg-custom-fields.php\";s:5:\"1.5.6\";s:13:\"pods/init.php\";s:9:\"2.8.0-a-2\";s:35:\"pods-ajax-views/pods-ajax-views.php\";s:3:\"1.2\";s:49:\"pods-alternative-cache/pods-alternative-cache.php\";s:5:\"2.0.8\";s:56:\"pods-beaver-builder-themer-add-on/pods-beaver-themer.php\";s:5:\"1.3.3\";s:41:\"pods-gravity-forms/pods-gravity-forms.php\";s:5:\"1.4.3\";s:47:\"pods-gutenberg-blocks/pods-gutenberg-blocks.php\";s:10:\"1.0-beta-1\";s:51:\"pods-polylang-meta-sync/pods-polylang-meta-sync.php\";s:5:\"1.0.0\";s:21:\"pods-seo/pods-seo.php\";s:3:\"2.2\";s:28:\"bbpowerpack/bb-powerpack.php\";s:5:\"1.2.7\";s:35:\"rest-api-tester/rest-api-tester.php\";s:5:\"0.1.3\";s:21:\"searchwp/searchwp.php\";s:6:\"2.9.14\";s:39:\"bb-ultimate-addon/bb-ultimate-addon.php\";s:5:\"1.4.5\";s:40:\"wordpress-beta-tester/wp-beta-tester.php\";s:6:\"2.2.10\";s:41:\"wordpress-importer/wordpress-importer.php\";s:3:\"0.7\";s:21:\"wp-reset/wp-reset.php\";s:4:\"1.80\";s:24:\"wordpress-seo/wp-seo.php\";s:4:\"14.1\";}s:8:\"response\";a:0:{}s:12:\"translations\";a:0:{}s:9:\"no_update\";a:23:{s:49:\"advanced-custom-blocks/advanced-custom-blocks.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:36:\"w.org/plugins/advanced-custom-blocks\";s:4:\"slug\";s:22:\"advanced-custom-blocks\";s:6:\"plugin\";s:49:\"advanced-custom-blocks/advanced-custom-blocks.php\";s:11:\"new_version\";s:3:\"0.1\";s:3:\"url\";s:53:\"https://wordpress.org/plugins/advanced-custom-blocks/\";s:7:\"package\";s:65:\"https://downloads.wordpress.org/plugin/advanced-custom-blocks.zip\";s:5:\"icons\";a:2:{s:2:\"1x\";s:67:\"https://ps.w.org/advanced-custom-blocks/assets/icon.svg?rev=1919623\";s:3:\"svg\";s:67:\"https://ps.w.org/advanced-custom-blocks/assets/icon.svg?rev=1919623\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:78:\"https://ps.w.org/advanced-custom-blocks/assets/banner-1544x500.png?rev=1919623\";s:2:\"1x\";s:77:\"https://ps.w.org/advanced-custom-blocks/assets/banner-772x250.png?rev=1919623\";}s:11:\"banners_rtl\";a:0:{}}s:30:\"advanced-custom-fields/acf.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:36:\"w.org/plugins/advanced-custom-fields\";s:4:\"slug\";s:22:\"advanced-custom-fields\";s:6:\"plugin\";s:30:\"advanced-custom-fields/acf.php\";s:11:\"new_version\";s:6:\"5.8.11\";s:3:\"url\";s:53:\"https://wordpress.org/plugins/advanced-custom-fields/\";s:7:\"package\";s:72:\"https://downloads.wordpress.org/plugin/advanced-custom-fields.5.8.11.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:75:\"https://ps.w.org/advanced-custom-fields/assets/icon-256x256.png?rev=1082746\";s:2:\"1x\";s:75:\"https://ps.w.org/advanced-custom-fields/assets/icon-128x128.png?rev=1082746\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:78:\"https://ps.w.org/advanced-custom-fields/assets/banner-1544x500.jpg?rev=1729099\";s:2:\"1x\";s:77:\"https://ps.w.org/advanced-custom-fields/assets/banner-772x250.jpg?rev=1729102\";}s:11:\"banners_rtl\";a:0:{}}s:29:\"acf-extended/acf-extended.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:26:\"w.org/plugins/acf-extended\";s:4:\"slug\";s:12:\"acf-extended\";s:6:\"plugin\";s:29:\"acf-extended/acf-extended.php\";s:11:\"new_version\";s:7:\"0.8.5.5\";s:3:\"url\";s:43:\"https://wordpress.org/plugins/acf-extended/\";s:7:\"package\";s:63:\"https://downloads.wordpress.org/plugin/acf-extended.0.8.5.5.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:65:\"https://ps.w.org/acf-extended/assets/icon-256x256.png?rev=2071550\";s:2:\"1x\";s:65:\"https://ps.w.org/acf-extended/assets/icon-128x128.png?rev=2071550\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:68:\"https://ps.w.org/acf-extended/assets/banner-1544x500.png?rev=2071550\";s:2:\"1x\";s:67:\"https://ps.w.org/acf-extended/assets/banner-772x250.png?rev=2071550\";}s:11:\"banners_rtl\";a:0:{}}s:19:\"akismet/akismet.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:21:\"w.org/plugins/akismet\";s:4:\"slug\";s:7:\"akismet\";s:6:\"plugin\";s:19:\"akismet/akismet.php\";s:11:\"new_version\";s:5:\"4.1.5\";s:3:\"url\";s:38:\"https://wordpress.org/plugins/akismet/\";s:7:\"package\";s:56:\"https://downloads.wordpress.org/plugin/akismet.4.1.5.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:59:\"https://ps.w.org/akismet/assets/icon-256x256.png?rev=969272\";s:2:\"1x\";s:59:\"https://ps.w.org/akismet/assets/icon-128x128.png?rev=969272\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:61:\"https://ps.w.org/akismet/assets/banner-772x250.jpg?rev=479904\";}s:11:\"banners_rtl\";a:0:{}}s:41:\"anywhere-elementor/anywhere-elementor.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:32:\"w.org/plugins/anywhere-elementor\";s:4:\"slug\";s:18:\"anywhere-elementor\";s:6:\"plugin\";s:41:\"anywhere-elementor/anywhere-elementor.php\";s:11:\"new_version\";s:5:\"1.2.1\";s:3:\"url\";s:49:\"https://wordpress.org/plugins/anywhere-elementor/\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/plugin/anywhere-elementor.zip\";s:5:\"icons\";a:1:{s:2:\"1x\";s:71:\"https://ps.w.org/anywhere-elementor/assets/icon-128x128.jpg?rev=1614331\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:73:\"https://ps.w.org/anywhere-elementor/assets/banner-772x250.jpg?rev=1538122\";}s:11:\"banners_rtl\";a:0:{}}s:33:\"appsero-helper/appsero-helper.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:28:\"w.org/plugins/appsero-helper\";s:4:\"slug\";s:14:\"appsero-helper\";s:6:\"plugin\";s:33:\"appsero-helper/appsero-helper.php\";s:11:\"new_version\";s:5:\"1.1.7\";s:3:\"url\";s:45:\"https://wordpress.org/plugins/appsero-helper/\";s:7:\"package\";s:63:\"https://downloads.wordpress.org/plugin/appsero-helper.1.1.7.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:67:\"https://ps.w.org/appsero-helper/assets/icon-256x256.png?rev=2024381\";s:2:\"1x\";s:67:\"https://ps.w.org/appsero-helper/assets/icon-128x128.png?rev=2024381\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:70:\"https://ps.w.org/appsero-helper/assets/banner-1544x500.png?rev=2024381\";s:2:\"1x\";s:69:\"https://ps.w.org/appsero-helper/assets/banner-772x250.png?rev=2024381\";}s:11:\"banners_rtl\";a:0:{}}s:33:\"classic-editor/classic-editor.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:28:\"w.org/plugins/classic-editor\";s:4:\"slug\";s:14:\"classic-editor\";s:6:\"plugin\";s:33:\"classic-editor/classic-editor.php\";s:11:\"new_version\";s:3:\"1.5\";s:3:\"url\";s:45:\"https://wordpress.org/plugins/classic-editor/\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/plugin/classic-editor.1.5.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:67:\"https://ps.w.org/classic-editor/assets/icon-256x256.png?rev=1998671\";s:2:\"1x\";s:67:\"https://ps.w.org/classic-editor/assets/icon-128x128.png?rev=1998671\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:70:\"https://ps.w.org/classic-editor/assets/banner-1544x500.png?rev=1998671\";s:2:\"1x\";s:69:\"https://ps.w.org/classic-editor/assets/banner-772x250.png?rev=1998676\";}s:11:\"banners_rtl\";a:0:{}}s:25:\"easy-query/easy-query.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:24:\"w.org/plugins/easy-query\";s:4:\"slug\";s:10:\"easy-query\";s:6:\"plugin\";s:25:\"easy-query/easy-query.php\";s:11:\"new_version\";s:5:\"2.0.4\";s:3:\"url\";s:41:\"https://wordpress.org/plugins/easy-query/\";s:7:\"package\";s:53:\"https://downloads.wordpress.org/plugin/easy-query.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:63:\"https://ps.w.org/easy-query/assets/icon-256x256.png?rev=1138272\";s:2:\"1x\";s:63:\"https://ps.w.org/easy-query/assets/icon-128x128.png?rev=1555105\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:65:\"https://ps.w.org/easy-query/assets/banner-772x250.jpg?rev=1628622\";}s:11:\"banners_rtl\";a:0:{}}s:23:\"elementor/elementor.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:23:\"w.org/plugins/elementor\";s:4:\"slug\";s:9:\"elementor\";s:6:\"plugin\";s:23:\"elementor/elementor.php\";s:11:\"new_version\";s:5:\"2.9.8\";s:3:\"url\";s:40:\"https://wordpress.org/plugins/elementor/\";s:7:\"package\";s:58:\"https://downloads.wordpress.org/plugin/elementor.2.9.8.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:62:\"https://ps.w.org/elementor/assets/icon-256x256.png?rev=1427768\";s:2:\"1x\";s:54:\"https://ps.w.org/elementor/assets/icon.svg?rev=1426809\";s:3:\"svg\";s:54:\"https://ps.w.org/elementor/assets/icon.svg?rev=1426809\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:65:\"https://ps.w.org/elementor/assets/banner-1544x500.png?rev=1475479\";s:2:\"1x\";s:64:\"https://ps.w.org/elementor/assets/banner-772x250.png?rev=1475479\";}s:11:\"banners_rtl\";a:0:{}}s:43:\"exports-and-reports/exports-and-reports.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:33:\"w.org/plugins/exports-and-reports\";s:4:\"slug\";s:19:\"exports-and-reports\";s:6:\"plugin\";s:43:\"exports-and-reports/exports-and-reports.php\";s:11:\"new_version\";s:5:\"0.8.5\";s:3:\"url\";s:50:\"https://wordpress.org/plugins/exports-and-reports/\";s:7:\"package\";s:68:\"https://downloads.wordpress.org/plugin/exports-and-reports.0.8.5.zip\";s:5:\"icons\";a:1:{s:7:\"default\";s:63:\"https://s.w.org/plugins/geopattern-icon/exports-and-reports.svg\";}s:7:\"banners\";a:0:{}s:11:\"banners_rtl\";a:0:{}}s:23:\"gravityformscli/cli.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:29:\"w.org/plugins/gravityformscli\";s:4:\"slug\";s:15:\"gravityformscli\";s:6:\"plugin\";s:23:\"gravityformscli/cli.php\";s:11:\"new_version\";s:3:\"1.2\";s:3:\"url\";s:46:\"https://wordpress.org/plugins/gravityformscli/\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/plugin/gravityformscli.1.2.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:68:\"https://ps.w.org/gravityformscli/assets/icon-256x256.png?rev=1758207\";s:2:\"1x\";s:68:\"https://ps.w.org/gravityformscli/assets/icon-128x128.png?rev=1758207\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:71:\"https://ps.w.org/gravityformscli/assets/banner-1544x500.png?rev=1758207\";s:2:\"1x\";s:70:\"https://ps.w.org/gravityformscli/assets/banner-772x250.png?rev=1758207\";}s:11:\"banners_rtl\";a:0:{}}s:23:\"gutenberg/gutenberg.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:23:\"w.org/plugins/gutenberg\";s:4:\"slug\";s:9:\"gutenberg\";s:6:\"plugin\";s:23:\"gutenberg/gutenberg.php\";s:11:\"new_version\";s:5:\"8.1.0\";s:3:\"url\";s:40:\"https://wordpress.org/plugins/gutenberg/\";s:7:\"package\";s:58:\"https://downloads.wordpress.org/plugin/gutenberg.8.1.0.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:62:\"https://ps.w.org/gutenberg/assets/icon-256x256.jpg?rev=1776042\";s:2:\"1x\";s:62:\"https://ps.w.org/gutenberg/assets/icon-128x128.jpg?rev=1776042\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:65:\"https://ps.w.org/gutenberg/assets/banner-1544x500.jpg?rev=1718710\";s:2:\"1x\";s:64:\"https://ps.w.org/gutenberg/assets/banner-772x250.jpg?rev=1718710\";}s:11:\"banners_rtl\";a:0:{}}s:51:\"gutenberg-custom-fields/gutenberg-custom-fields.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:37:\"w.org/plugins/gutenberg-custom-fields\";s:4:\"slug\";s:23:\"gutenberg-custom-fields\";s:6:\"plugin\";s:51:\"gutenberg-custom-fields/gutenberg-custom-fields.php\";s:11:\"new_version\";s:5:\"1.5.6\";s:3:\"url\";s:54:\"https://wordpress.org/plugins/gutenberg-custom-fields/\";s:7:\"package\";s:72:\"https://downloads.wordpress.org/plugin/gutenberg-custom-fields.1.5.6.zip\";s:5:\"icons\";a:2:{s:2:\"1x\";s:68:\"https://ps.w.org/gutenberg-custom-fields/assets/icon.svg?rev=1845983\";s:3:\"svg\";s:68:\"https://ps.w.org/gutenberg-custom-fields/assets/icon.svg?rev=1845983\";}s:7:\"banners\";a:0:{}s:11:\"banners_rtl\";a:0:{}}s:13:\"pods/init.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:18:\"w.org/plugins/pods\";s:4:\"slug\";s:4:\"pods\";s:6:\"plugin\";s:13:\"pods/init.php\";s:11:\"new_version\";s:6:\"2.7.20\";s:3:\"url\";s:35:\"https://wordpress.org/plugins/pods/\";s:7:\"package\";s:54:\"https://downloads.wordpress.org/plugin/pods.2.7.20.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:57:\"https://ps.w.org/pods/assets/icon-256x256.png?rev=1667333\";s:2:\"1x\";s:49:\"https://ps.w.org/pods/assets/icon.svg?rev=1667333\";s:3:\"svg\";s:49:\"https://ps.w.org/pods/assets/icon.svg?rev=1667333\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:59:\"https://ps.w.org/pods/assets/banner-772x250.png?rev=1667333\";}s:11:\"banners_rtl\";a:0:{}}s:35:\"pods-ajax-views/pods-ajax-views.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:29:\"w.org/plugins/pods-ajax-views\";s:4:\"slug\";s:15:\"pods-ajax-views\";s:6:\"plugin\";s:35:\"pods-ajax-views/pods-ajax-views.php\";s:11:\"new_version\";s:3:\"1.2\";s:3:\"url\";s:46:\"https://wordpress.org/plugins/pods-ajax-views/\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/plugin/pods-ajax-views.1.2.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:67:\"https://ps.w.org/pods-ajax-views/assets/icon-256x256.png?rev=972954\";s:2:\"1x\";s:60:\"https://ps.w.org/pods-ajax-views/assets/icon.svg?rev=2268758\";s:3:\"svg\";s:60:\"https://ps.w.org/pods-ajax-views/assets/icon.svg?rev=2268758\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:69:\"https://ps.w.org/pods-ajax-views/assets/banner-772x250.png?rev=935492\";}s:11:\"banners_rtl\";a:0:{}}s:49:\"pods-alternative-cache/pods-alternative-cache.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:36:\"w.org/plugins/pods-alternative-cache\";s:4:\"slug\";s:22:\"pods-alternative-cache\";s:6:\"plugin\";s:49:\"pods-alternative-cache/pods-alternative-cache.php\";s:11:\"new_version\";s:5:\"2.0.7\";s:3:\"url\";s:53:\"https://wordpress.org/plugins/pods-alternative-cache/\";s:7:\"package\";s:71:\"https://downloads.wordpress.org/plugin/pods-alternative-cache.2.0.7.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:75:\"https://ps.w.org/pods-alternative-cache/assets/icon-256x256.png?rev=1669115\";s:2:\"1x\";s:67:\"https://ps.w.org/pods-alternative-cache/assets/icon.svg?rev=1669115\";s:3:\"svg\";s:67:\"https://ps.w.org/pods-alternative-cache/assets/icon.svg?rev=1669115\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:77:\"https://ps.w.org/pods-alternative-cache/assets/banner-772x250.png?rev=1669115\";}s:11:\"banners_rtl\";a:0:{}}s:56:\"pods-beaver-builder-themer-add-on/pods-beaver-themer.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:47:\"w.org/plugins/pods-beaver-builder-themer-add-on\";s:4:\"slug\";s:33:\"pods-beaver-builder-themer-add-on\";s:6:\"plugin\";s:56:\"pods-beaver-builder-themer-add-on/pods-beaver-themer.php\";s:11:\"new_version\";s:5:\"1.3.3\";s:3:\"url\";s:64:\"https://wordpress.org/plugins/pods-beaver-builder-themer-add-on/\";s:7:\"package\";s:82:\"https://downloads.wordpress.org/plugin/pods-beaver-builder-themer-add-on.1.3.3.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:86:\"https://ps.w.org/pods-beaver-builder-themer-add-on/assets/icon-256x256.png?rev=1674242\";s:2:\"1x\";s:78:\"https://ps.w.org/pods-beaver-builder-themer-add-on/assets/icon.svg?rev=1674242\";s:3:\"svg\";s:78:\"https://ps.w.org/pods-beaver-builder-themer-add-on/assets/icon.svg?rev=1674242\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:88:\"https://ps.w.org/pods-beaver-builder-themer-add-on/assets/banner-772x250.png?rev=1674242\";}s:11:\"banners_rtl\";a:0:{}}s:41:\"pods-gravity-forms/pods-gravity-forms.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:32:\"w.org/plugins/pods-gravity-forms\";s:4:\"slug\";s:18:\"pods-gravity-forms\";s:6:\"plugin\";s:41:\"pods-gravity-forms/pods-gravity-forms.php\";s:11:\"new_version\";s:5:\"1.4.3\";s:3:\"url\";s:49:\"https://wordpress.org/plugins/pods-gravity-forms/\";s:7:\"package\";s:67:\"https://downloads.wordpress.org/plugin/pods-gravity-forms.1.4.3.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:71:\"https://ps.w.org/pods-gravity-forms/assets/icon-256x256.png?rev=1669109\";s:2:\"1x\";s:63:\"https://ps.w.org/pods-gravity-forms/assets/icon.svg?rev=1669109\";s:3:\"svg\";s:63:\"https://ps.w.org/pods-gravity-forms/assets/icon.svg?rev=1669109\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:73:\"https://ps.w.org/pods-gravity-forms/assets/banner-772x250.png?rev=1669109\";}s:11:\"banners_rtl\";a:0:{}}s:21:\"pods-seo/pods-seo.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:22:\"w.org/plugins/pods-seo\";s:4:\"slug\";s:8:\"pods-seo\";s:6:\"plugin\";s:21:\"pods-seo/pods-seo.php\";s:11:\"new_version\";s:3:\"2.2\";s:3:\"url\";s:39:\"https://wordpress.org/plugins/pods-seo/\";s:7:\"package\";s:55:\"https://downloads.wordpress.org/plugin/pods-seo.2.2.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:61:\"https://ps.w.org/pods-seo/assets/icon-256x256.png?rev=1669107\";s:2:\"1x\";s:53:\"https://ps.w.org/pods-seo/assets/icon.svg?rev=1669107\";s:3:\"svg\";s:53:\"https://ps.w.org/pods-seo/assets/icon.svg?rev=1669107\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:63:\"https://ps.w.org/pods-seo/assets/banner-772x250.png?rev=1669107\";}s:11:\"banners_rtl\";a:0:{}}s:40:\"wordpress-beta-tester/wp-beta-tester.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:35:\"w.org/plugins/wordpress-beta-tester\";s:4:\"slug\";s:21:\"wordpress-beta-tester\";s:6:\"plugin\";s:40:\"wordpress-beta-tester/wp-beta-tester.php\";s:11:\"new_version\";s:6:\"2.2.10\";s:3:\"url\";s:52:\"https://wordpress.org/plugins/wordpress-beta-tester/\";s:7:\"package\";s:71:\"https://downloads.wordpress.org/plugin/wordpress-beta-tester.2.2.10.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:74:\"https://ps.w.org/wordpress-beta-tester/assets/icon-256x256.png?rev=2296163\";s:2:\"1x\";s:74:\"https://ps.w.org/wordpress-beta-tester/assets/icon-128x128.png?rev=2296163\";}s:7:\"banners\";a:0:{}s:11:\"banners_rtl\";a:0:{}}s:41:\"wordpress-importer/wordpress-importer.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:32:\"w.org/plugins/wordpress-importer\";s:4:\"slug\";s:18:\"wordpress-importer\";s:6:\"plugin\";s:41:\"wordpress-importer/wordpress-importer.php\";s:11:\"new_version\";s:3:\"0.7\";s:3:\"url\";s:49:\"https://wordpress.org/plugins/wordpress-importer/\";s:7:\"package\";s:65:\"https://downloads.wordpress.org/plugin/wordpress-importer.0.7.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:71:\"https://ps.w.org/wordpress-importer/assets/icon-256x256.png?rev=1908375\";s:2:\"1x\";s:63:\"https://ps.w.org/wordpress-importer/assets/icon.svg?rev=1908375\";s:3:\"svg\";s:63:\"https://ps.w.org/wordpress-importer/assets/icon.svg?rev=1908375\";}s:7:\"banners\";a:1:{s:2:\"1x\";s:72:\"https://ps.w.org/wordpress-importer/assets/banner-772x250.png?rev=547654\";}s:11:\"banners_rtl\";a:0:{}}s:21:\"wp-reset/wp-reset.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:22:\"w.org/plugins/wp-reset\";s:4:\"slug\";s:8:\"wp-reset\";s:6:\"plugin\";s:21:\"wp-reset/wp-reset.php\";s:11:\"new_version\";s:4:\"1.80\";s:3:\"url\";s:39:\"https://wordpress.org/plugins/wp-reset/\";s:7:\"package\";s:56:\"https://downloads.wordpress.org/plugin/wp-reset.1.80.zip\";s:5:\"icons\";a:2:{s:2:\"2x\";s:61:\"https://ps.w.org/wp-reset/assets/icon-256x256.png?rev=1906468\";s:2:\"1x\";s:61:\"https://ps.w.org/wp-reset/assets/icon-128x128.png?rev=1906468\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:64:\"https://ps.w.org/wp-reset/assets/banner-1544x500.png?rev=2163880\";s:2:\"1x\";s:63:\"https://ps.w.org/wp-reset/assets/banner-772x250.png?rev=2163880\";}s:11:\"banners_rtl\";a:0:{}}s:24:\"wordpress-seo/wp-seo.php\";O:8:\"stdClass\":9:{s:2:\"id\";s:27:\"w.org/plugins/wordpress-seo\";s:4:\"slug\";s:13:\"wordpress-seo\";s:6:\"plugin\";s:24:\"wordpress-seo/wp-seo.php\";s:11:\"new_version\";s:4:\"14.1\";s:3:\"url\";s:44:\"https://wordpress.org/plugins/wordpress-seo/\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/plugin/wordpress-seo.14.1.zip\";s:5:\"icons\";a:3:{s:2:\"2x\";s:66:\"https://ps.w.org/wordpress-seo/assets/icon-256x256.png?rev=1834347\";s:2:\"1x\";s:58:\"https://ps.w.org/wordpress-seo/assets/icon.svg?rev=1946641\";s:3:\"svg\";s:58:\"https://ps.w.org/wordpress-seo/assets/icon.svg?rev=1946641\";}s:7:\"banners\";a:2:{s:2:\"2x\";s:69:\"https://ps.w.org/wordpress-seo/assets/banner-1544x500.png?rev=1843435\";s:2:\"1x\";s:68:\"https://ps.w.org/wordpress-seo/assets/banner-772x250.png?rev=1843435\";}s:11:\"banners_rtl\";a:2:{s:2:\"2x\";s:73:\"https://ps.w.org/wordpress-seo/assets/banner-1544x500-rtl.png?rev=1843435\";s:2:\"1x\";s:72:\"https://ps.w.org/wordpress-seo/assets/banner-772x250-rtl.png?rev=1843435\";}}}}','no'),(498,'_site_transient_timeout_theme_roots','1590201964','no'),(499,'_site_transient_theme_roots','a:3:{s:14:\"twentynineteen\";s:7:\"/themes\";s:15:\"twentyseventeen\";s:7:\"/themes\";s:12:\"twentytwenty\";s:7:\"/themes\";}','no'),(500,'_site_transient_update_themes','O:8:\"stdClass\":4:{s:12:\"last_checked\";i:1590200164;s:7:\"checked\";a:3:{s:14:\"twentynineteen\";s:3:\"1.5\";s:15:\"twentyseventeen\";s:3:\"2.3\";s:12:\"twentytwenty\";s:3:\"1.2\";}s:8:\"response\";a:1:{s:12:\"twentytwenty\";a:6:{s:5:\"theme\";s:12:\"twentytwenty\";s:11:\"new_version\";s:3:\"1.3\";s:3:\"url\";s:42:\"https://wordpress.org/themes/twentytwenty/\";s:7:\"package\";s:58:\"https://downloads.wordpress.org/theme/twentytwenty.1.3.zip\";s:8:\"requires\";s:3:\"4.7\";s:12:\"requires_php\";s:5:\"5.2.4\";}}s:12:\"translations\";a:0:{}}','no'),(503,'_site_transient_timeout_browser_116a4a046f1a400b852a44ba2b8ab31c','1590804965','no'),(504,'_site_transient_browser_116a4a046f1a400b852a44ba2b8ab31c','a:10:{s:4:\"name\";s:6:\"Chrome\";s:7:\"version\";s:13:\"81.0.4044.129\";s:8:\"platform\";s:9:\"Macintosh\";s:10:\"update_url\";s:29:\"https://www.google.com/chrome\";s:7:\"img_src\";s:43:\"http://s.w.org/images/browsers/chrome.png?1\";s:11:\"img_src_ssl\";s:44:\"https://s.w.org/images/browsers/chrome.png?1\";s:15:\"current_version\";s:2:\"18\";s:7:\"upgrade\";b:0;s:8:\"insecure\";b:0;s:6:\"mobile\";b:0;}','no'),(505,'_site_transient_timeout_php_check_09a2ad9330cccb8a83c2e6443b87150f','1590804965','no'),(506,'_site_transient_php_check_09a2ad9330cccb8a83c2e6443b87150f','a:5:{s:19:\"recommended_version\";s:3:\"7.3\";s:15:\"minimum_version\";s:6:\"5.6.20\";s:12:\"is_supported\";b:1;s:9:\"is_secure\";b:1;s:13:\"is_acceptable\";b:1;}','no'),(514,'fs_active_plugins','O:8:\"stdClass\":3:{s:7:\"plugins\";a:1:{s:34:\"pods/vendor/freemius/wordpress-sdk\";O:8:\"stdClass\":4:{s:7:\"version\";s:5:\"2.3.2\";s:4:\"type\";s:6:\"plugin\";s:9:\"timestamp\";i:1590200167;s:11:\"plugin_path\";s:13:\"pods/init.php\";}}s:7:\"abspath\";s:14:\"/var/www/html/\";s:6:\"newest\";O:8:\"stdClass\":5:{s:11:\"plugin_path\";s:13:\"pods/init.php\";s:8:\"sdk_path\";s:34:\"pods/vendor/freemius/wordpress-sdk\";s:7:\"version\";s:5:\"2.3.2\";s:13:\"in_activation\";b:0;s:9:\"timestamp\";i:1590200167;}}','yes'),(517,'fs_debug_mode','','yes'),(519,'fs_accounts','a:7:{s:21:\"id_slug_type_path_map\";a:1:{i:5347;a:3:{s:4:\"slug\";s:4:\"pods\";s:4:\"type\";s:6:\"plugin\";s:4:\"path\";s:13:\"pods/init.php\";}}s:11:\"plugin_data\";a:1:{s:4:\"pods\";a:17:{s:16:\"plugin_main_file\";O:8:\"stdClass\":1:{s:4:\"path\";s:13:\"pods/init.php\";}s:20:\"is_network_activated\";b:0;s:17:\"install_timestamp\";i:1590200167;s:17:\"was_plugin_loaded\";b:1;s:21:\"is_plugin_new_install\";b:0;s:16:\"sdk_last_version\";N;s:11:\"sdk_version\";s:5:\"2.3.2\";s:16:\"sdk_upgrade_mode\";b:1;s:18:\"sdk_downgrade_mode\";b:0;s:19:\"plugin_last_version\";N;s:14:\"plugin_version\";s:9:\"2.8.0-a-2\";s:19:\"plugin_upgrade_mode\";b:1;s:21:\"plugin_downgrade_mode\";b:0;s:17:\"connectivity_test\";a:6:{s:12:\"is_connected\";b:1;s:4:\"host\";s:19:\"wordpress.test:8888\";s:9:\"server_ip\";s:10:\"172.28.0.1\";s:9:\"is_active\";b:1;s:9:\"timestamp\";i:1590200167;s:7:\"version\";s:9:\"2.8.0-a-2\";}s:15:\"prev_is_premium\";b:0;s:18:\"sticky_optin_added\";b:1;s:12:\"is_anonymous\";a:3:{s:2:\"is\";b:1;s:9:\"timestamp\";i:1590200184;s:7:\"version\";s:9:\"2.8.0-a-2\";}}}s:13:\"file_slug_map\";a:1:{s:13:\"pods/init.php\";s:4:\"pods\";}s:7:\"plugins\";a:1:{s:4:\"pods\";O:9:\"FS_Plugin\":23:{s:16:\"parent_plugin_id\";N;s:5:\"title\";s:38:\"Pods - Custom Content Types and Fields\";s:4:\"slug\";s:4:\"pods\";s:12:\"premium_slug\";s:12:\"pods-premium\";s:4:\"type\";s:6:\"plugin\";s:20:\"affiliate_moderation\";b:0;s:19:\"is_wp_org_compliant\";b:1;s:22:\"premium_releases_count\";N;s:4:\"file\";s:13:\"pods/init.php\";s:7:\"version\";s:9:\"2.8.0-a-2\";s:11:\"auto_update\";N;s:4:\"info\";N;s:10:\"is_premium\";b:0;s:14:\"premium_suffix\";s:9:\"(Premium)\";s:7:\"is_live\";b:1;s:9:\"bundle_id\";N;s:17:\"bundle_public_key\";N;s:10:\"public_key\";s:32:\"pk_737105490825babae220297e18920\";s:10:\"secret_key\";N;s:2:\"id\";s:4:\"5347\";s:7:\"updated\";N;s:7:\"created\";N;s:22:\"\0FS_Entity\0_is_updated\";b:0;}}s:9:\"unique_id\";s:32:\"903cad78fb10c714534376b37d5837df\";s:13:\"admin_notices\";a:1:{s:4:\"pods\";a:0:{}}s:6:\"addons\";a:1:{i:5347;a:5:{i:0;O:9:\"FS_Plugin\":23:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:5:\"title\";s:22:\"Pods Alternative Cache\";s:4:\"slug\";s:22:\"pods-alternative-cache\";s:12:\"premium_slug\";s:33:\"pods-simple-relationships-premium\";s:4:\"type\";s:6:\"plugin\";s:20:\"affiliate_moderation\";N;s:19:\"is_wp_org_compliant\";b:1;s:22:\"premium_releases_count\";i:0;s:4:\"file\";N;s:7:\"version\";N;s:11:\"auto_update\";N;s:4:\"info\";O:14:\"FS_Plugin_Info\":13:{s:9:\"plugin_id\";s:4:\"5348\";s:11:\"description\";N;s:17:\"short_description\";s:124:\"Alternative caching engine for Pods for large sites on hosts with hard limits on how much you can store in the object cache.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5348/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5348/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1352\";s:7:\"updated\";s:19:\"2020-03-18 23:02:11\";s:7:\"created\";s:19:\"2020-01-16 15:38:46\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}s:10:\"is_premium\";b:0;s:14:\"premium_suffix\";s:9:\"(Premium)\";s:7:\"is_live\";b:1;s:9:\"bundle_id\";N;s:17:\"bundle_public_key\";N;s:10:\"public_key\";s:32:\"pk_c51e7ff51e827ecaddb23664c050d\";s:10:\"secret_key\";N;s:2:\"id\";s:4:\"5348\";s:7:\"updated\";s:19:\"2020-03-27 15:47:24\";s:7:\"created\";s:19:\"2020-01-16 15:35:45\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}i:1;O:9:\"FS_Plugin\":23:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:5:\"title\";s:18:\"Pods Beaver Themer\";s:4:\"slug\";s:33:\"pods-beaver-builder-themer-add-on\";s:12:\"premium_slug\";s:41:\"pods-beaver-builder-themer-add-on-premium\";s:4:\"type\";s:6:\"plugin\";s:20:\"affiliate_moderation\";N;s:19:\"is_wp_org_compliant\";b:1;s:22:\"premium_releases_count\";i:0;s:4:\"file\";N;s:7:\"version\";N;s:11:\"auto_update\";N;s:4:\"info\";O:14:\"FS_Plugin_Info\":13:{s:9:\"plugin_id\";s:4:\"5349\";s:11:\"description\";N;s:17:\"short_description\";s:94:\"Integration with Beaver Builder Themer. Provides a UI for mapping Field Connections with Pods.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5349/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5349/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1503\";s:7:\"updated\";s:19:\"2020-03-23 13:29:21\";s:7:\"created\";s:19:\"2020-03-18 16:27:22\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}s:10:\"is_premium\";b:0;s:14:\"premium_suffix\";s:9:\"(Premium)\";s:7:\"is_live\";b:1;s:9:\"bundle_id\";N;s:17:\"bundle_public_key\";N;s:10:\"public_key\";s:32:\"pk_d8a10a25a662419add4ff3fbcc493\";s:10:\"secret_key\";N;s:2:\"id\";s:4:\"5349\";s:7:\"updated\";s:19:\"2020-05-22 19:36:55\";s:7:\"created\";s:19:\"2020-01-16 15:37:32\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}i:2;O:9:\"FS_Plugin\":23:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:5:\"title\";s:8:\"Pods SEO\";s:4:\"slug\";s:8:\"pods-seo\";s:12:\"premium_slug\";s:16:\"pods-seo-premium\";s:4:\"type\";s:6:\"plugin\";s:20:\"affiliate_moderation\";N;s:19:\"is_wp_org_compliant\";b:1;s:22:\"premium_releases_count\";i:0;s:4:\"file\";N;s:7:\"version\";N;s:11:\"auto_update\";N;s:4:\"info\";O:14:\"FS_Plugin_Info\":13:{s:9:\"plugin_id\";s:4:\"5753\";s:11:\"description\";s:0:\"\";s:17:\"short_description\";s:114:\"Integrates with WP SEO Analysis for custom fields and Pods Advanced Content Types with WordPress SEO XML Sitemaps.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5753/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5753/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1505\";s:7:\"updated\";s:19:\"2020-03-18 23:05:03\";s:7:\"created\";s:19:\"2020-03-18 16:41:19\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}s:10:\"is_premium\";b:0;s:14:\"premium_suffix\";s:9:\"(Premium)\";s:7:\"is_live\";b:1;s:9:\"bundle_id\";N;s:17:\"bundle_public_key\";N;s:10:\"public_key\";s:32:\"pk_46fa00cfe39af82dd1ed03033bea4\";s:10:\"secret_key\";N;s:2:\"id\";s:4:\"5753\";s:7:\"updated\";s:19:\"2020-05-21 03:00:56\";s:7:\"created\";s:19:\"2020-03-18 16:30:02\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}i:3;O:9:\"FS_Plugin\":23:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:5:\"title\";s:18:\"Pods Gravity Forms\";s:4:\"slug\";s:18:\"pods-gravity-forms\";s:12:\"premium_slug\";s:26:\"pods-gravity-forms-premium\";s:4:\"type\";s:6:\"plugin\";s:20:\"affiliate_moderation\";N;s:19:\"is_wp_org_compliant\";b:1;s:22:\"premium_releases_count\";i:0;s:4:\"file\";N;s:7:\"version\";N;s:11:\"auto_update\";N;s:4:\"info\";O:14:\"FS_Plugin_Info\":13:{s:9:\"plugin_id\";s:4:\"5754\";s:11:\"description\";N;s:17:\"short_description\";s:90:\"Integration with Gravity Forms. Provides a UI for mapping a Form\'s submissions into a Pod.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5754/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5754/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1506\";s:7:\"updated\";s:19:\"2020-03-23 13:27:45\";s:7:\"created\";s:19:\"2020-03-18 22:53:21\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}s:10:\"is_premium\";b:0;s:14:\"premium_suffix\";s:9:\"(Premium)\";s:7:\"is_live\";b:1;s:9:\"bundle_id\";N;s:17:\"bundle_public_key\";N;s:10:\"public_key\";s:32:\"pk_1aaaee6bf8963f2077405e84f2ac5\";s:10:\"secret_key\";N;s:2:\"id\";s:4:\"5754\";s:7:\"updated\";s:19:\"2020-05-22 01:35:15\";s:7:\"created\";s:19:\"2020-03-18 16:40:29\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}i:4;O:9:\"FS_Plugin\":23:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:5:\"title\";s:15:\"Pods AJAX Views\";s:4:\"slug\";s:15:\"pods-ajax-views\";s:12:\"premium_slug\";s:23:\"pods-ajax-views-premium\";s:4:\"type\";s:6:\"plugin\";s:20:\"affiliate_moderation\";N;s:19:\"is_wp_org_compliant\";b:1;s:22:\"premium_releases_count\";i:0;s:4:\"file\";N;s:7:\"version\";N;s:11:\"auto_update\";N;s:4:\"info\";O:14:\"FS_Plugin_Info\":13:{s:9:\"plugin_id\";s:4:\"5755\";s:11:\"description\";N;s:17:\"short_description\";s:81:\"An easy way to generate cached views from AJAX when they haven\'t been cached yet.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5755/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5755/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1507\";s:7:\"updated\";s:19:\"2020-03-18 23:00:49\";s:7:\"created\";s:19:\"2020-03-18 22:54:20\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}s:10:\"is_premium\";b:0;s:14:\"premium_suffix\";s:9:\"(Premium)\";s:7:\"is_live\";b:1;s:9:\"bundle_id\";N;s:17:\"bundle_public_key\";N;s:10:\"public_key\";s:32:\"pk_8606e36bd5153a1faf1e041342634\";s:10:\"secret_key\";N;s:2:\"id\";s:4:\"5755\";s:7:\"updated\";s:19:\"2020-05-19 01:19:42\";s:7:\"created\";s:19:\"2020-03-18 16:43:04\";s:22:\"\0FS_Entity\0_is_updated\";b:0;}}}}','yes'),(523,'fs_gdpr','a:1:{s:2:\"u1\";a:1:{s:8:\"required\";b:0;}}','yes'),(526,'_site_transient_timeout_community-events-33b508558b1818b215cd4d397a75331a','1590243368','no'),(527,'_site_transient_community-events-33b508558b1818b215cd4d397a75331a','a:3:{s:9:\"sandboxed\";b:0;s:8:\"location\";a:1:{s:2:\"ip\";s:10:\"172.28.0.0\";}s:6:\"events\";a:6:{i:0;a:8:{s:4:\"type\";s:8:\"wordcamp\";s:5:\"title\";s:20:\"WordCamp Kent Online\";s:3:\"url\";s:30:\"https://2020.kent.wordcamp.org\";s:6:\"meetup\";N;s:10:\"meetup_url\";N;s:4:\"date\";s:19:\"2020-05-30 12:30:00\";s:8:\"end_date\";s:19:\"2020-05-31 00:00:00\";s:8:\"location\";a:4:{s:8:\"location\";s:6:\"Online\";s:7:\"country\";s:2:\"US\";s:8:\"latitude\";d:41.1536674;s:9:\"longitude\";d:-81.3578859;}}i:1;a:8:{s:4:\"type\";s:6:\"meetup\";s:5:\"title\";s:20:\"WordPress Roundtable\";s:3:\"url\";s:75:\"https://www.meetup.com/WordPress-Midcities-User-Group/events/tvcwrrybcjbjb/\";s:6:\"meetup\";s:30:\"WordPress Midcities User Group\";s:10:\"meetup_url\";s:54:\"https://www.meetup.com/WordPress-Midcities-User-Group/\";s:4:\"date\";s:19:\"2020-06-06 13:00:00\";s:8:\"end_date\";s:19:\"2020-06-06 15:00:00\";s:8:\"location\";a:4:{s:8:\"location\";s:6:\"Online\";s:7:\"country\";s:2:\"US\";s:8:\"latitude\";d:32.860000610352;s:9:\"longitude\";d:-97.139999389648;}}i:2;a:8:{s:4:\"type\";s:6:\"meetup\";s:5:\"title\";s:20:\"WordPress Roundtable\";s:3:\"url\";s:75:\"https://www.meetup.com/WordPress-Midcities-User-Group/events/tvcwrrybckbgb/\";s:6:\"meetup\";s:30:\"WordPress Midcities User Group\";s:10:\"meetup_url\";s:54:\"https://www.meetup.com/WordPress-Midcities-User-Group/\";s:4:\"date\";s:19:\"2020-07-04 13:00:00\";s:8:\"end_date\";s:19:\"2020-07-04 15:00:00\";s:8:\"location\";a:4:{s:8:\"location\";s:6:\"Online\";s:7:\"country\";s:2:\"US\";s:8:\"latitude\";d:32.860000610352;s:9:\"longitude\";d:-97.139999389648;}}i:3;a:8:{s:4:\"type\";s:6:\"meetup\";s:5:\"title\";s:20:\"WordPress Roundtable\";s:3:\"url\";s:75:\"https://www.meetup.com/WordPress-Midcities-User-Group/events/tvcwrrybclbcb/\";s:6:\"meetup\";s:30:\"WordPress Midcities User Group\";s:10:\"meetup_url\";s:54:\"https://www.meetup.com/WordPress-Midcities-User-Group/\";s:4:\"date\";s:19:\"2020-08-01 13:00:00\";s:8:\"end_date\";s:19:\"2020-08-01 15:00:00\";s:8:\"location\";a:4:{s:8:\"location\";s:6:\"Online\";s:7:\"country\";s:2:\"US\";s:8:\"latitude\";d:32.860000610352;s:9:\"longitude\";d:-97.139999389648;}}i:4;a:8:{s:4:\"type\";s:8:\"wordcamp\";s:5:\"title\";s:29:\"WordCamp Tulsa, Oklahoma, USA\";s:3:\"url\";s:31:\"https://2020.tulsa.wordcamp.org\";s:6:\"meetup\";N;s:10:\"meetup_url\";N;s:4:\"date\";s:19:\"2020-08-29 00:00:00\";s:8:\"end_date\";s:19:\"2020-08-30 00:00:00\";s:8:\"location\";a:4:{s:8:\"location\";s:23:\"Tulsa, OK United States\";s:7:\"country\";s:2:\"US\";s:8:\"latitude\";d:36.1591107;s:9:\"longitude\";d:-95.9937418;}}i:5;a:8:{s:4:\"type\";s:6:\"meetup\";s:5:\"title\";s:20:\"WordPress Roundtable\";s:3:\"url\";s:75:\"https://www.meetup.com/WordPress-Midcities-User-Group/events/tvcwrrybcmbhb/\";s:6:\"meetup\";s:30:\"WordPress Midcities User Group\";s:10:\"meetup_url\";s:54:\"https://www.meetup.com/WordPress-Midcities-User-Group/\";s:4:\"date\";s:19:\"2020-09-05 13:00:00\";s:8:\"end_date\";s:19:\"2020-09-05 15:00:00\";s:8:\"location\";a:4:{s:8:\"location\";s:6:\"Online\";s:7:\"country\";s:2:\"US\";s:8:\"latitude\";d:32.860000610352;s:9:\"longitude\";d:-97.139999389648;}}}}','no'),(528,'can_compress_scripts','0','no'),(529,'_transient_timeout_feed_9bbd59226dc36b9b26cd43f15694c5c3','1590243369','no'),(530,'_transient_feed_9bbd59226dc36b9b26cd43f15694c5c3','a:4:{s:5:\"child\";a:1:{s:0:\"\";a:1:{s:3:\"rss\";a:1:{i:0;a:6:{s:4:\"data\";s:3:\"\n\n\n\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:7:\"version\";s:3:\"2.0\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:1:{s:0:\"\";a:1:{s:7:\"channel\";a:1:{i:0;a:6:{s:4:\"data\";s:49:\"\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:7:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:27:\"News โ€“ โ€“ WordPress.org\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:26:\"https://wordpress.org/news\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"WordPress News\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:13:\"lastBuildDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 13 May 2020 11:05:48 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"language\";a:1:{i:0;a:5:{s:4:\"data\";s:5:\"en-US\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:9:\"generator\";a:1:{i:0;a:5:{s:4:\"data\";s:40:\"https://wordpress.org/?v=5.5-alpha-47838\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"item\";a:10:{i:0;a:6:{s:4:\"data\";s:57:\"\n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"The Month in WordPress: April 2020\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:69:\"https://wordpress.org/news/2020/05/the-month-in-wordpress-april-2020/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 04 May 2020 09:31:22 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:1:{i:0;a:5:{s:4:\"data\";s:18:\"Month in WordPress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8571\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:364:\"April continued to be a challenging time for the WordPress community, with many under stay-at-home recommendations. However, it was also an exciting month in which we created new ways to connect with and inspire each other! This month, amazing contributors moved more WordCamps online and shipped new releases for WordPress and Gutenberg. For the latest, […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:10:\"Angela Jin\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:8195:\"\n

            April continued to be a challenging time for the WordPress community, with many under stay-at-home recommendations. However, it was also an exciting month in which we created new ways to connect with and inspire each other! This month, amazing contributors moved more WordCamps online and shipped new releases for WordPress and Gutenberg. For the latest, read on.ย 

            \n\n\n\n
            \n\n\n\n

            WordPress 5.4.1 released

            \n\n\n\n

            On April 24th,  WordPress 5.4.1 Release Candidate 1 (RC1) was released for testing, quickly followed by the official release of WordPress 5.4.1 on April 29th. This security release features 17 bug fixes and seven security fixes, so we recommend updating your sites immediately. To download WordPress 5.4.1, visit your Dashboard, click on Updates, then Update Now, or download the latest version directly from WordPress.org. For more information, visit this post, review the full list of changes on Trac, or check out the version 5.4.1 HelpHub documentation page.

            \n\n\n\n

            Want to get involved in building WordPress Core? Follow the Core team blog, and join the #core channel in the Making WordPress Slack group.

            \n\n\n\n

            Gutenberg 7.9 and 8.0 released

            \n\n\n\n

            It was another exciting month for Gutenberg, with the release of 7.9 and 8.0! Version 7.9 brought new block design tools, three new patterns, and improved block markup. Gutenberg 8.0 continued to refine the new block patterns feature, with additional options for inline formatting, and extending the functionality of the Code Editor. In addition to these new features, both releases included new enhancements and APIs, along with a number of bug fixes, performance improvements, some experiments, and more! You can read all the details about the latest Gutenberg releases in the announcement posts for 7.9 and 8.0

            \n\n\n\n

            Want to get involved in building Gutenberg? Follow the Core team blog, contribute to Gutenberg on GitHub, and join the #core-editor channel in the Making WordPress Slack group.

            \n\n\n\n

            BuddyPress 6.0.0

            \n\n\n\n

            BuddyPress 6.0.0-beta2 was released for testing in mid-April, leading to the BuddyPress 6.0.0 Release Candidate, announced on April 29. This is an important step before  the final release of BuddyPress 6.0.0, which is slated for Thursday, May 14. Changes and new features in this release include moving the profile photo and user cover image under the BP Members component, and a new BP Rest API. Additionally, this release will introduce the first round of BuddyPress Blocks! Last, but not least, BuddyPress 6.0.0 will require at least PHP 5.6 and WordPress 4.8. 

            \n\n\n\n

            Want to get involved? Test the 6.0.0-RC here! You can also help by translating BuddyPress into another language, or let the team know of any issues you find, either in the support forums and/or in their development tracker

            \n\n\n\n

            WordCamp US goes online, apply to speak!

            \n\n\n\n

            WordCamp US will take place online due to the COVID-19 pandemic. The event still runs from October 27-29, 2020, and will be free to anyone who wishes to attend. The team plans to offer  what WCUS has historically brought to the community in person: sessions and workshops, Contributor Day, a hallway track, and of course, State of the Word. 

            \n\n\n\n

            Interested in speaking at WCUS? The Call for Speakers is still open! You can apply to speak on the speaker application site until May 31, 2020 at 11:59 pm CDT (UTC-5). 

            \n\n\n\n

            Additionally, the Call for Cities is also open. If your community is interested in hosting WordCamp US in 2021 & 2022, please fill out this application

            \n\n\n\n

            For the latest information about WordCamp US, sign up for updates on the website, or follow Facebook, Twitter, or Instagram

            \n\n\n\n

            WordCamp Europe 2020 goes virtual 

            \n\n\n\n

            Last month, WordCamp Europe decided to postpone its Porto event to 2021. This April, the WCEU organizing team announced that the 2020 WordCamp will be online! WordCamp Europe 2020 Online will take place from June 4-6, 2020, and tickets will be free. There will be a virtual Contributor Day on June 4, and then two half days of live-streamed talks and workshops. To participate, get your free ticket here

            \n\n\n\n

            To get the latest news for WordCamp Europe 2020 Online, follow on Facebook, Twitter, LinkedIn, or on Instagram

            \n\n\n\n
            \n\n\n\n

            Further Reading

            \n\n\n\n\n\n\n\n

            Have a story that we should include in the next โ€œMonth in WordPressโ€ post? Please submit it here.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8571\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:1;a:6:{s:4:\"data\";s:60:\"\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:15:\"WordPress 5.4.1\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:51:\"https://wordpress.org/news/2020/04/wordpress-5-4-1/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 29 Apr 2020 19:56:47 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:2:{i:0;a:5:{s:4:\"data\";s:8:\"Releases\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:8:\"Security\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8553\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:363:\"WordPress 5.4.1 is now available! This security and maintenance release features 17 bug fixes in addition to 7 security fixes. Because this is a security release, it is recommended that you update your sites immediately. All versions since WordPress 3.7 have also been updated. WordPress 5.4.1 is a short-cycle security and maintenance release. The next […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Jake Spurlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:7029:\"\n

            WordPress 5.4.1 is now available!

            \n\n\n\n

            This security and maintenance release features 17 bug fixes in addition to 7 security fixes. Because this is a security release, it is recommended that you update your sites immediately. All versions since WordPress 3.7 have also been updated.

            \n\n\n\n

            WordPress 5.4.1 is a short-cycle security and maintenance release. The next major release will be version 5.5.

            \n\n\n\n

            You can download WordPress 5.4.1 by downloading from WordPress.org, or visit your Dashboard โ†’ Updates and click Update Now.

            \n\n\n\n

            If you have sites that support automatic background updates, theyโ€™ve already started the update process.

            \n\n\n\n

            Security Updates

            \n\n\n\n

            Seven security issues affect WordPress versions 5.4 and earlier. If you havenโ€™t yet updated to 5.4, all WordPress versions since 3.7 have also been updated to fix the following security issues:

            \n\n\n\n
            • Props to Muaz Bin Abdus Sattar and Jannes who both independently reported an issue where password reset tokens were not properly invalidated.
            • Props to ka1n4t for finding an issue where certain private posts can be viewed unauthenticated.
            • Props to Evan Ricafort for discovering an XSS issue in the Customizer
            • Props to Ben Bidner from the WordPress Security Team who discovered an XSS issue in the search block.
            • Props to Nick Daugherty from WordPress VIP / WordPress Security Team who discovered an XSS issue in wp-object-cache.
            • Props to Ronnie Goodrich (Kahoots) and Jason Medeiros who independently reported an XSS issue in file uploads.
            • Props to Weston Ruter for fixing a stored XSS vulnerability in the WordPress customizer.
            • Additionally, an authenticated XSS issue in the block editor was discovered by Nguyen The Duc (ducnt) in WordPress 5.4 RC1 and RC2. It was fixed in 5.4 RC5. We wanted to be sure to give credit and thank them for all of their work in making WordPress more secure.
            \n\n\n\n

            Thank you to all of the reporters for privately disclosing the vulnerabilities. This gave the security team time to fix the vulnerabilities before WordPress sites could be attacked.

            \n\n\n\n

            For more information, browse the full list of changes on Trac, or check out the version 5.4.1 HelpHub documentation page.

            \n\n\n\n

            In addition to the security researchers mentioned above, thank you to everyone who helped make WordPress 5.4.1 happen:

            \n\n\n\n

            Alex Concha, Andrea Fercia, Andrew Duthie, Andrew Ozz, Andy Fragen, Andy Peatling, arnaudbroes, Chris Van Patten, Daniel Richards, DhrRob, Dono12, dudo, Ehtisham Siddiqui, Ella van Durpe, Garrett Hyder, Ian Belanger, Ipstenu (Mika Epstein), Jake Spurlock, Jb Audras, John Blackbourn, John James Jacoby, Jonathan Desrosiers, Jorge Costa, K. Adam White, Kelly Choyce-Dwan, MarkRH, mattyrob, Miguel Fonseca, Mohammad Jangda, Mukesh Panchal, Nick Daugherty, noahtallen, Paul Biron, Peter Westwood, Peter Wilson, pikamander2, r-a-y, Riad Benguella, Robert Anderson, Samuel Wood (Otto), Sergey Biryukov, Sรธren Brรธnsted, Stanimir Stoyanov, tellthemachines, Timothy Jacobs, Toro_Unit (Hiroshi Urabe), treecutter, and yohannp.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8553\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:2;a:6:{s:4:\"data\";s:76:\"\n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:6:{s:0:\"\";a:7:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:33:\"People of WordPress: Mario Peshev\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:68:\"https://wordpress.org/news/2020/04/people-of-wordpress-mario-peshev/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"comments\";a:1:{i:0;a:5:{s:4:\"data\";s:77:\"https://wordpress.org/news/2020/04/people-of-wordpress-mario-peshev/#comments\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 08 Apr 2020 00:57:03 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:2:{i:0;a:5:{s:4:\"data\";s:9:\"Community\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:9:\"heropress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8536\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:158:\"In the April edition of our \"People of WordPress\" series, you\'ll find out how Mario Peshev went from self-taught developer to teaching basic digital literacy.\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:16:\"Yvette Sonneveld\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:12069:\"\n

            Youโ€™ve probably heard that WordPress is open source software, and may know that itโ€™s created and run by volunteers. Enthusiasts share many examples of how WordPress has changed peopleโ€™s lives for the better. In this monthly series, we share some of those lesser-known, amazing stories.

            \n\n\n\n

            Computer science in the nineties

            \n\n\n\n
            \"\"
            Mario Peshev
            \n\n\n\n

            Mario has been hooked on computers ever since he got his first one in 1996. He started with digging into MS-DOS and Windows 3.1 first and learned tons by trial and error. Following that adventure, Mario built his first HTML site in 1999. He found development so exciting that he spent day and night learning QBasic and started working at the local PC game club. Mario got involved with several other things related to website administration (translating security bulletins, setting up simple sites, etc) and soon found the technology field was full of activities he really enjoyed.

            \n\n\n\n

            The Corporate Lifestyle

            \n\n\n\n

            Mario started studying programming including an intensive high-level course for C#, Java development, and software engineering, and eventually got a job in a corporate environment. He soon became a team lead there, managing all the planning and paperwork for their projects.

            \n\n\n\n

            But he continued freelancing on the side. He grew his own network of technical experts through attending, volunteering at, and organizing conferences. He also ran a technical forum and regularly spoke at universities and enterprise companies.

            \n\n\n\n

            Remote Working and Business Opportunity

            \n\n\n\n

            The combination of a high workload and a daily three-hour-long commute made Marioโ€™s life difficult. Many of his friends were still studying, traveling or unemployed. The blissful and calm lives they lived seemed like a fairy tale to him. And even while both his managers and his clients were abroad, he was unable to obtain permission to work remotely. 

            \n\n\n\n

            So Mario decided to leave his job and start freelancing full time. But he found he faced a massive challenge. 

            \n\n\n\n

            He discovered Java projects were pretty large and required an established team of people working together in an office. All job opportunities were on-site, and some even required relocation abroad. Certified Java programmers werenโ€™t being hired on a remote basis. 

            \n\n\n\n

            As Mario had some PHP experience from previous jobs, he used this to start his freelance career. For his projects, he used both plain PHP and PHP frameworks like CakePHP and CodeIgniter. 

            \n\n\n\n

            For a while, Mario accepted work using commonly known platforms including Joomla, Drupal, and WordPress. In addition, he worked on PHP, Java, Python and some C# projects for a couple of years, after which he decided to switch to WordPress completely.

            \n\n\n\n

            Building products

            \n\n\n\n

            One of his projects involved a technically challenging charity backed by several international organizations. Unexpected shortages in the team put him in the technical lead position. As a result, Mario found himself planning the next phases, meeting with the client regularly, and renegotiating the terms. The team completed the project successfully, and after the launch, a TV campaign led millions of visitors to the website.

            \n\n\n\n

            As a result of the successful launch, this client invited Mario to participate in more WordPress projects, including building a custom framework.

            \n\n\n\n

            โ€œI wasnโ€™t that acquainted with WordPress back then. For me, a conventional person trained in architectural design patterns and best practices, WordPress seemed like an eccentric young hipster somewhere on the line between insane and genius at the same time. I had to spend a couple of months learning WordPress from the inside out.โ€

            Mario Peshev
            \n\n\n\n

            As his interest in WordPress grew, Mario stopped delivering other custom platforms, and converted clients to WordPress. 

            \n\n\n\n

            European Community

            \n\n\n\n
            \"Mario
            Mario presenting at a WordCamp
            \n\n\n\n

            For Mario, one of the key selling points of WordPress was the international openness. He had previously been involved with other open source communities, some of which were US-focused. He felt they were more reliant on meeting people in person. With events only taking place in the US, this made building relationships much harder for people living in other countries.

            \n\n\n\n

            While the WordPress project started out in the US, the WordPress community quickly globalized. Dozens of WordCamps and hundreds of Meetup events take place around the globe every year.  All of these events bring a wide variety of people sharing their enthusiasm for WordPress together.

            \n\n\n\n

            For Mario, the birth of WordCamp Europe was something magical. The fact that hundreds, and later on thousands, of people from all over the world gathered around the topic of WordPress speaks for itself. Mario has been involved with organizing WordCamp Europe twice (in 2014 and 2015). 

            \n\n\n\n

            โ€œThereโ€™s nothing like meeting WordPress enthusiasts and professionals from more than 50 countries brainstorming and working together at a WordCamp. You simply have to be there to understand how powerful it all is.โ€

            Mario Peshev
            \n\n\n\n

            Growing businesses and teams

            \n\n\n\n

            A key WordPress benefit is its popularity โ€“ an ever growing project currently powering more than 35% of the Internet [2020]. Itโ€™s popular enough to be a de facto standard for websites, platforms, e-commerce and blogs. 

            \n\n\n\n

            WordPress has a low barrier to entry. You can achieve a lot without being an expert, meaning most people can start gaining experience without having to spend years learning how to code. That also makes it easier to build businesses and teams.

            \n\n\n\n

            โ€œBeing able to use a tool that is user-friendly, not overly complicated and easily extensible makes introducing it to team members faster and easier. It requires less time for adjustment, and as a result makes a team stronger and faster. The fact that this tool is cost-effective also allows more startups to enter the market. It requires  less time and investments to launch an MVP. This boosts the entire ecosystem.โ€

            Mario Peshev
            \n\n\n\n

            Helping Others

            \n\n\n\n

            Mario also introduced WordPress to children and young people. He taught them how to use WordPress as a tool for homework and class assignments. By using WordPress, they were able to learn the basics of designing themes, developing plugins, marketing statistics, social media, copywriting, and so much more. This approachable introduction to the software meant technical skills were not needed.

            \n\n\n\n

            He was also part of a team of volunteers who helped a group of young people living at a foster home struggling to provide for themselves. The team taught the basic digital literacy skills necessary in the modern workplace and potentially pay for their rent and basic needs. This included working with Microsoft Word, Excel and WordPress, as well as some basic design and marketing skills.ย 

            \n\n\n\n

            โ€œWhen you look at that from another perspective, a platform that could save lives – literally – and change the world for better is worth contributing to, in any possible manner.โ€

            Mario Peshev
            \n\n\n\n

            Contributing to the WordPress community

            \n\n\n\n

            From the core team to supporting and organizing WordCamps, Mario has long been an active contributor to the global WordPress project. He is passionate about the connections fostered by people who are involved in building both the WordPress software and the community around it.

            \n\n\n\n

            โ€œThe WordPress community consists of people of all race and color, living all around the world, working as teachers, developers, bloggers, designers, business owners. Letโ€™s work together to help each other. Letโ€™s stick together and show  the world WordPress can help make it a better place.โ€

            Mario Peshev
            \n\n\n\n

            Contributors

            \n\n\n\n

            Thanks to Alison Rothwell (@wpfiddlybits), Yvette Sonneveld (@yvettesonneveld), Abha Thakor (@webcommsat), Josepha Haden (@chanthaboune) and Topher DeRosia (@topher1kenobe). Thank you to Mario Peshev (@nofearinc) for sharing his #ContributorStory.

            \n\n\n\n
            \"HeroPress
            \n\n\n\n

            This post is based onย an article originally published on HeroPress.com, a community initiative created byย Topher DeRosia. HeroPress highlights people in the WordPress community who have overcome barriers and whose stories would otherwise go unheard.

            \n\n\n\n

            Meet more WordPress community members over atย HeroPress.com!

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:36:\"http://wellformedweb.org/CommentAPI/\";a:1:{s:10:\"commentRss\";a:1:{i:0;a:5:{s:4:\"data\";s:73:\"https://wordpress.org/news/2020/04/people-of-wordpress-mario-peshev/feed/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:38:\"http://purl.org/rss/1.0/modules/slash/\";a:1:{s:8:\"comments\";a:1:{i:0;a:5:{s:4:\"data\";s:2:\"12\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8536\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:3;a:6:{s:4:\"data\";s:57:\"\n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"The Month in WordPress: March 2020\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:69:\"https://wordpress.org/news/2020/04/the-month-in-wordpress-march-2020/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 03 Apr 2020 12:01:00 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:1:{i:0;a:5:{s:4:\"data\";s:18:\"Month in WordPress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8532\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:363:\"The month of March was both a tough and exciting time for the WordPress open-source project. With COVID-19 declared a pandemic, in-person events have had to adapt quickly – a challenge for any community. March culminated with the release of WordPress 5.4, an exhilarating milestone only made possible by dedicated contributors. For all the latest, […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:15:\"Hugh Lashbrooke\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:8588:\"\n

            The month of March was both a tough and exciting time for the WordPress open-source project. With COVID-19 declared a pandemic, in-person events have had to adapt quickly – a challenge for any community. March culminated with the release of WordPress 5.4, an exhilarating milestone only made possible by dedicated contributors. For all the latest, read on. 

            \n\n\n\n
            \n\n\n\n

            WordPress 5.4 โ€œAdderleyโ€

            \n\n\n\n

            WordPress 5.4 โ€œAdderleyโ€ was released on March 31 and includes a robust list of new blocks, enhancements, and new features for both users and developers. The primary focus areas of this release included the block editor, privacy, accessibility, and developer improvements, with the full list of enhancements covered in the 5.4 field guide.

            \n\n\n\n

            Want to get involved in building WordPress Core? Follow the Core team blog, and join the #core channel in the Making WordPress Slack group.

            \n\n\n\n

            Releases of Gutenberg 7.7 and 7.8

            \n\n\n\n

            Itโ€™s been another busy month for Gutenberg, this time with the release of Gutenberg 7.7 and 7.8. Gutenberg 7.7 introduced block patterns – predefined block layouts that are ready to use and tweak. This is an important step towards Full Site Editing, which is currently targeted for inclusion in WordPress 5.6. As a first iteration, you can pick and insert patterns from the Block Patterns UI, which has been added as a sidebar plugin.

            \n\n\n\n

            Gutenberg 7.7 also includes a refresh of the Block UI, which better responds to the ways users interact with the editor. For more information on the User UI and Block Patterns, read this summary of the most recent Block-Based Themes meeting. Gutenberg 7.8, introduced on March 25, further enhanced this Block UI redesign. Both releases also included a suite of improvements, bug fixes, new APIs, documentation, and more!

            \n\n\n\n

            Want to get involved in building Gutenberg? Follow the Core team blog, contribute to Gutenberg on GitHub, and join the #core-editor channel in the Making WordPress Slack group.

            \n\n\n\n

            WordCamp cancellations and shift to online events

            \n\n\n\n

            In early March, the Community team issued new recommendations for event organizers in light of growing concerns around COVID-19. Following this guidance, and with COVID-19 declared a pandemic, WordPress community organizers reluctantly but responsibly postponed or canceled their upcoming WordCamps and meetups.

            \n\n\n\n

            As community events are an important part of the WordPress open-source project, the Community team made suggestions for taking charity hackathons online, proposed interim adjustments to existing community event guidelines, and provided training for online conference organizing with Crowdcast. The team is currently working on building a Virtual Events Handbook that will continue to support WordPress community organizers at this time. 

            \n\n\n\n

            Want to get involved with the WordPress Community team, host your own virtual WordPress event, or help improve the documentation for all of this? Follow the Community team blog, learn more about virtual events, and join the #community-events channel in the Making WordPress Slack group.

            \n\n\n\n

            Link your GitHub profile to WordPress.org

            \n\n\n\n

            Last month, an experimental feature was added to Trac, WordPress Coreโ€™s bug-tracking system, to improve collaboration between Trac and GitHub. This month, to help make tracking contributions to the WordPress project across multiple locations easier, there is a new option to connect your GitHub account to your WordPress.org profile. This connection allows for more accurate acknowledgement and recognition of contributors. You can connect your GitHub account to your WordPress.org account by editing your WordPress.org profile.

            \n\n\n\n

            For more information and instructions on how to connect your accounts, read the announcement post.

            \n\n\n\n

            Modernizing WordPress coding standards

            \n\n\n\n

            Defined coding standards is an important step in creating the consistent codebase needed to prepare for requiring PHP 7.x for WordPress Core. As such, coding standards have been proposed for implementation in WordPress Coding Standards 3.0.0. This includes new proposed standards for namespace declarations, import use statements, fully qualified names in inline code, traits and interfaces, type declarations, declare statements/strict typing, the ::class constant, operators, and more. 

            \n\n\n\n

            Want to get involved or view the full list of currently proposed new coding standards? Visit and add your feedback to the post on updating the Coding standards for modern PHP and follow the Core team blog.

            \n\n\n\n
            \n\n\n\n

            Further Reading:

            \n\n\n\n\n\n\n\n

            Have a story that we should include in the next โ€œMonth in WordPressโ€ post? Please submit it here.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8532\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:4;a:6:{s:4:\"data\";s:58:\"\n \n \n \n \n \n \n \n\n \n \n \n \n \n\n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:7:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:28:\"WordPress 5.4 โ€œAdderleyโ€\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:44:\"https://wordpress.org/news/2020/03/adderley/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 31 Mar 2020 19:04:02 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:1:{i:0;a:5:{s:4:\"data\";s:8:\"Releases\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8455\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:255:\"Version 5.4 \"Adderley\" of WordPress is available for download or update in your WordPress dashboard. This version brings you more ways to make content come alive with your best images and helps make your vision real by putting blocks in the perfect place.\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:9:\"enclosure\";a:1:{i:0;a:5:{s:4:\"data\";s:0:\"\";s:7:\"attribs\";a:1:{s:0:\"\";a:3:{s:3:\"url\";s:45:\"https://s.w.org/images/core/5.4/textcolor.mp4\";s:6:\"length\";s:6:\"440616\";s:4:\"type\";s:9:\"video/mp4\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Matt Mullenweg\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:52946:\"\n

            Here it is! Named โ€œAdderleyโ€ in honor of Nat Adderley, the latest and greatest version of WordPress is available for download or update in your dashboard.

            \n\n\n\n
            \"\"
            \n\n\n\n
            \n

            Say hello to more and better.

            \n\n\n\n

            More ways to make your pages come alive. With easier ways to get it all done and looking better than everโ€”and boosts in speed you can feel.

            \n
            \n\n\n\n
            \n\n\n\n

            Welcome to WordPress 5.4

            \n\n\n\n

            Every major release adds more to the block editor.

            \n\n\n\n

            More ways to make posts and pages come alive with your best images. More ways to bring your visitors in, and keep them engaged, with the richness of embedded media from the webโ€™s top services.

            \n\n\n\n

            More ways to make your vision real, and put blocks in the perfect placeโ€”even if a particular kind of block is new to you. More efficient processes.

            \n\n\n\n

            And more speed everywhere, so as you build sections or galleries, or just type in a line of prose, you can feel how much faster your work flows.

            \n\n\n\n
            \n\n\n\n
            \"\"
            \n\n\n\n

            Two new blocks. And better blocks overall.

            \n\n\n\n
            • Two brand-new blocks: Social Icons and Buttons make adding interactive features fast and easy.
            • New ways with color: Gradients in the Buttons and Cover block, toolbar access to color options in Rich Text blocks, and for the first time, color options in the Group and Columns blocks.
            • Guess a whole lot less! Version 5.4 streamlines the whole process for placing and replacing multimedia in every block. Now it works the same way in almost every block!
            • And if youโ€™ve ever thought your image in the Media+Text block should link to something elseโ€”perhaps a picture of a brochure should download that brochure as a document? Well, now it can.
            \n\n\n\n
            \n\n\n\n
            \n\n\n\n

            Cleaner UI, clearer navigationโ€”and easier tabbing!

            \n\n\n\n
            • Clearer block navigation with block breadcrumbs. And easier selection once you get there.
            • For when you need to navigate with the keyboard, better tabbing and focus. Plus, you can tab over to the sidebar of nearly any block.
            • Speed! 14% faster loading of the editor, 51% faster time-to-type!
            • Tips are gone. In their place, a Welcome Guide window you can bring up when you need itโ€”and only when you need itโ€”again and again.
            • Know at a glance whether youโ€™re in a blockโ€™s Edit or Navigation mode. Or, if you have restricted vision, your screen reader will tell you which mode youโ€™re in.
            \n\n\n\n

            Of course, if you want to work with the very latest tools and features, install the Gutenberg plugin. Youโ€™ll get to be the first to use new and exciting features in the block editor before anyone else has seen them!

            \n\n\n\n
            \n\n\n\n
            \"\"
            \n\n\n\n

            Your fundamental right: privacy

            \n\n\n\n

            5.4 helps with a variety of privacy issues around the world. So when users and stakeholders ask about regulatory compliance, or how your team handles user data, the answers should be a lot easier to get right.

            \n\n\n\n

            Take a look:

            \n\n\n\n
            • Now personal data exports include users session information and users location data from the community events widget. Plus, a table of contents!
            • See progress as you process export and erasure requests through the privacy tools.
            • Plus, little enhancements throughout give the privacy tools a little cleaner look. Your eyes will thank you!
            \n\n\n\n
            \n\n\n\n
            \"\"
            \n\n\n\n

            Just for developers

            \n\n\n\n

            Add custom fields to menu itemsโ€”natively

            \n\n\n\n

            Two new actions let you add custom fields to menu itemsโ€”without a plugin and without writing custom walkers.

            \n\n\n\n

            On the Menus admin screen, wp_nav_menu_item_custom_fields fires just before the move buttons of a nav menu item in the menu editor.

            \n\n\n\n

            In the Customizer, wp_nav_menu_item_custom_fields_customize_template fires at the end of the menu-items form-fields template.

            \n\n\n\n

            Check your code and see where these new actions can replace your custom code, and if youโ€™re concerned about duplication, add a check for the WordPress version.

            \n\n\n\n

            Blocks! Simpler styling, new APIs and embeds

            \n\n\n\n
            • Radically simpler block styling. Negative margins and default padding are gone! Now you can style blocks the way you need them. And, a refactor got rid of four redundant wrapper divs.
            • If you build plugins, now you can register collections of your blocks by namespace across categoriesโ€”a great way to get more brand visibility.
            • Let users do more with two new APIs: block variations and gradients.
            • In embeds, now the block editor supports TikTokโ€”and CollegeHumor is gone.
            \n\n\n\n

            Thereโ€™s lots more for developers to love in WordPress 5.4. To discover more and learn how to make these changes shine on your sites, themes, plugins and more, check the WordPress 5.4 Field Guide.

            \n\n\n\n
            \n\n\n\n

            The Squad

            \n\n\n\n

            This release was led by Matt MullenwegFrancesca Marano, and David Baumwald. They were enthusiastically supported by a release squad:

            \n\n\n\n\n\n\n\n

            The squad was joined throughout the release cycle by 552 generous volunteer contributors who collectively worked on 361 tickets on Trac and 1226 pull requests on GitHub.

            \n\n\n\n

            Put on a Nat Adderley playlist, click that update button (or download it directly), and check the profiles of the fine folks that helped:

            \n\n\n0v3rth3d4wn, 123host, 1naveengiri, Aaron Jorbin, Abhijit Rakas, abrightclearweb, acosmin, Adam Silverstein, adamboro, Addie, adnan.limdi, Aezaz Shaikh, Aftab Ali Muni, Aki Björklund, Akib, Akira Tachibana, akshayar, Alain Schlesser, Albert Juhé Lluveras, Alex Concha, Alex Mills, AlexHolsgrove, alexischenal, alextran, alishankhan, allancole, Allen Snook, alpipego, Amir Seljubac, Amit Dudhat, Amol Vhankalas, Amr Gawish, Amy Kamala, Anantajit JG, Anders Norén, Andrés, Andrea Fercia, Andrea Tarantini, andreaitm, Andrei Draganescu, Andrew Dixon, Andrew Duthie, Andrew Nacin, Andrew Ozz, Andrew Serong, Andrew Wilder, Andrey Savchenko, Andy Fragen, Andy Meerwaldt, Andy Peatling, Angelika Reisiger, Ankit Panchal, Anthony Burchell, Anthony Ledesma, apedog, Apermo, apieschel, Aravind Ajith, archon810, arenddeboer, Ari Stathopoulos, arnaudbroes, Arslan Ahmed, ashokrd2013, Ataur R, Ate Up With Motor, autotutorial, Ayesh Karunaratne, BackuPs, bahia0019, Bappi, Bart Czyz, ben.greeley, benedictsinger, Benjamin Intal, bibliofille, bilgilabs, Birgir Erlendsson, Birgit Pauli-Haack, BMO, Boga86, Boone Gorges, Brad Markle, Brandon Kraft, Brent Swisher, Cameron Voell, Carolina Nymark, ceyhun0, Chetan Prajapati, Chetan Satasiya, Chintesh Prajapati, Chip Snyder, Chris Klosowski, Chris Trynkiewicz (Sukces Strony), Chris Van Patten, Christian Sabo, Christiana Mohr, clayisland, Copons, Corey McKrill, crdunst, Csaba (LittleBigThings), Dademaru, Damiรกn Suรกrez, Daniel Bachhuber, Daniel James, Daniel Llewellyn, Daniel Richards, Daniele Scasciafratte, daniloercoli, Darren Ethier (nerrad), darrenlambert, Dave Mackey, Dave Smith, daveslaughter, DaveWP196, David Artiss, David Binovec, David Herrera, David Ryan, David Shanske, David Stone, Debabrata Karfa, dekervit, Delowar Hossain, Denis Yanchevskiy, Dhaval kasavala, dhurlburtusa, Dilip Bheda, dingo-d, Dion Hulse, dipeshkakadiya, djp424, dominic_ks, Dominik Schilling, Dono12, Dotan Cohen, dphiffer, dragosh635, Drew Jaynes, dudo, eclev91, ecotechie, eden159, Edi Amin, edmundcwm, Eduardo Toledo, ehtis, Ella van Durpe, Ellen Bauer, Emil E, Enrique Piqueras, Enrique Sรกnchez, equin0x80, erikkroes, Estela Rueda, Fabian, Fabian Kägy, Fahim Murshed, Faisal Alvi, Felipe Elia, Felipe Santos, Felix Arntz, Fernando Souza, fervillz, fgiannar, flaviozavan, Florian TIAR, Fotis Pastrakis, Frank Martin, Gal Baras, Garrett Hyder, Gary Jones, Gary Pendergast, Gaurang Dabhi, George Stephanis, geriux, Girish Panchal, Gleb Kemarsky, Glenn, Goto Hayato, grafruessel, Greg Rickaby, Grzegorz Ziรณล‚kowski, Grzegorz.Janoszka, Gustavo Bordoni, gwwar, hamedmoodi, hAmpzter, happiryu, Hareesh Pillai, Harry Milatz, Haz, helgatheviking, Henry Holtgeerts, Himani Lotia, Hubert Kubiak, i3anaan, Ian Belanger, Ian Dunn, ianatkins, ianmjones, IdeaBox Creations, Ihtisham Zahoor, intimez, Ipstenu (Mika Epstein), Isabel Brison, ispreview, Jake Spurlock, Jakub Binda, James Huff, James Koster, James Nylen, jameslnewell, Janki Moradiya, Jarret, Jasper van der Meer, jaydeep23290, jdy68, Jean-Baptiste Audras, Jean-David Daviet, Jeff Bowen, Jeff Ong, Jeff Paul, Jeffrey Carandang, jeichorn, Jenil Kanani, Jenny Wong, jepperask, Jer Clarke, Jeremy Felt, Jeremy Herve, Jeroen Rotty, Jerry Jones, Jessica Lyschik, Jip Moors, Joe Dolson, Joe Hoyle, Joe McGill, Joen Asmussen, John Blackbourn, John James Jacoby, John Watkins, Jon, Jon Quach, Jon Surrell, Jonathan Desrosiers, Jonathan Goldford, Jonny Harris, Jono Alderson, Joonas Vanhatapio, Joost de Valk, Jorge Bernal, Jorge Costa, Josepha Haden, JoshuaWold, Joy, jqz, jsnajdr, Juanfra Aldasoro, Julian Weiland, julian.kimmig, Juliette Reinders Folmer, Julio Potier, Junko Nukaga, jurgen, justdaiv, Justin Ahinon, K. Adam White, kaggdesign, KalpShit Akabari, Kantari Samy, Kaspars, Kelly Dwan, Kennith Nichol, Kevin Hagerty, Kharis Sulistiyono, Khushbu Modi, killerbishop, kinjaldalwadi, kitchin, Kite, Kjell Reigstad, kkarpieszuk, Knut Sparhell, KokkieH, Konstantin Obenland, Konstantinos Xenos, Krystyna, kubiq, kuflievskiy, Kukhyeon Heo, kyliesabra, Laken Hafner, leandroalonso, leogermani, lgrev01, linuxologos, lisota, Lorenzo Fracassi, luisherranz, luisrivera, lukaswaudentio, Lukasz Jasinski, Luke Cavanagh, Lydia Wodarek, M A Vinoth Kumar, maciejmackowiak, Mahesh Waghmare, Manzoor Wani, marcelo2605, Marcio Zebedeu, MarcoZ, Marcus Kazmierczak, Marek Dฤ›diฤ, Marius Jensen, Marius84, Mark Jaquith, Mark Marzeotti, Mark Uraine, MarkRH, Martin Stehle, Marty Helmick, Mary Baum, Mat Gargano, Mat Lipe, Mathieu Viet, Matias Ventura, Matt Keys, Matt van Andel, mattchowning, mattcursor, Matthew Kevins, mattyrob, maxme, mayanksonawat, mbrailer, Mehidi Hassan, Mel Choyce-Dwan, mensmaximus, Michael Arestad, Michael Ecklund, Michael Panaga, Michelle Schulp, mickaelperrin, miette49, Miguel Fonseca, Miguel Torres, mihdan, Miina Sikk, Mikael Korpela, Mike Auteri, Mike Hansen, Mike Schinkel [WPLib Box project lead], Mike Schroder, mikejdent, Mikko Saari, Milan Patel, Milan Petrovic, mimi, mircoraffinetti, mjnewman, mlbrgl, Mohammad Jangda, Morgan Estes, Morteza Geransayeh, mppfeiffer, mryoga, Muhammad Usama Masood, mujuonly, Mukesh Panchal, Nadir Seghir, nagoke, Nahid Ferdous Mohit, Nate Finch, Nazmul Ahsan, nekomajin, NextScripts, Nick Daugherty, Nick Halsey, Nicklas Sundberg, Nicky Lim, nicolad, Nicolas Juen, nicole2292, Niels Lange, nikhilgupte, nilamacharya, noahtallen, noyle, nsubugak, oakesjosh, oldenburg, Omar Alshaker, Otto Kekäläinen, Ov3rfly, Paal Joachim Romdahl, page-carbajal, pagewidth, Paragon Initiative Enterprises, Pascal Birchler, Pascal Casier, Paul Bearne, Paul Biron, Paul Kevin, Paul Schreiber, pcarvalho, Pedro Mendonça, perrywagle, Peter Westwood, Peter Wilson, Philip Jackson, Pierre Gordon, Pierre Lannoy, pikamander2, Prashant Singh, Pratik Jain, Presskopp, Priyanka Behera, r-a-y, Raam Dev, Rachel Cherry, Rachel Peter, ragnarokatz, Rami Yushuvaev, raoulunger, razamalik, Remco Tolsma, rephotsirch, rheinardkorf, Riad Benguella, Ricard Torres, Rich Tabor, rimadoshi, Rinku Y, Rob Cutmore, Rob Migchels, rob006, Robert Anderson, Roi Conde, Roland Murg, Rostislav Wolný, Roy Tanck, Russell Heimlich, Ryan, Ryan Fredlund, Ryan McCue, Ryan Welcher, Ryo, Sébastien SERRE, Søren Brønsted, sablednah, Sampat Viral, Samuel Wood (Otto), SamuelFernandez, Sander, santilinwp, Sathiyamoorthy V, Schuhwerk, Scott Reilly, Scott Taylor, scruffian, scvleon, Sebastian Pisula, Sergey Biryukov, Sergio de Falco, sergiomdgomes, sgastard, sgoen, Shaharia Azam, Shannon Smith, shariqkhan2012, Shawntelle Coker, sheparddw, Shital Marakana, Shizumi Yoshiaki, simonjanin, sinatrateam, sirreal, skorasaurus, smerriman, socalchristina, Soren Wrede, spenserhale, sproutchris, squarecandy, Stanimir Stoyanov, starvoters1, SteelWagstaff, steevithak, Stefano Minoia, Stefanos Togoulidis, steffanhalv, Stephen Bernhardt, Stephen Edgar, Steve Dufresne, Steve Grunwell, stevenlinx, Stiofan, straightvisions GmbH, stroona.com, Subrata Mal, Subrata Sarkar, Sultan Nasir Uddin, swapnild, Sybre Waaijer, Sรฉrgio Estรชvรฃo, Takayuki Miyauchi, Takeshi Furusato, Tammie Lister, Tanvirul Haque, TBschen, tdlewis77, Tellyworth, Thamaraiselvam, thefarlilacfield, ThemeZee, Tim Havinga, Tim Hengeveld, timon33, Timothée Brosille, Timothy Jacobs, Tkama, tmanoilov, tmatsuur, tobifjellner (Tor-Bjorn Fjellner), Tom Greer, Tom J Nowell, tommix, Toni Viemerö, Toro_Unit (Hiroshi Urabe), torres126, Torsten Landsiedel, Towhidul Islam, treecutter, tristangemus, tristanleboss, tsuyoring, Tung Du, Udit Desai, Ulrich, upadalavipul, Utsav tilava, Vaishali Panchal, Valentin Bora, Varun Shanbhag, Veminom, Vinita Tandulkar, virgodesign, Vlad. S., vortfu, waleedt93, WebMan Design | Oliver Juhas, websupporter, Weston Ruter, William Earnhardt, William Patton, wpgurudev, WPMarmite, wptoolsdev, xedinunknown-1, yale01, Yannicki, yohannp, Yordan Soares, Yui, zachflauaus, Zack Tollman, Zebulan Stanphill, Zee, and zsusag.\n\n\n\n
            \n\n\n\n

            Many thanks to all of the community volunteers who contribute in the support forums. They answer questions from people across the world, whether they are using WordPress for the first time or since the first release. These releases are more successful for their efforts!

            \n\n\n\n

            Finally, thanks to all the community translators who worked on WordPress 5.4. Their efforts bring WordPress fully translated to 46 languages at release time, with more on the way.

            \n\n\n\n

            If you want to learn more about volunteering with WordPress, check out Make WordPress or the core development blog.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8455\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:5;a:6:{s:4:\"data\";s:60:\"\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:17:\"WordPress 5.4 RC5\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:53:\"https://wordpress.org/news/2020/03/wordpress-5-4-rc5/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Sat, 28 Mar 2020 00:47:08 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:2:{i:0;a:5:{s:4:\"data\";s:11:\"Development\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:8:\"Releases\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8451\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:379:\"The fifth release candidate for WordPress 5.4 is live! WordPress 5.4 is currently scheduled to land on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time! You can test the WordPress 5.4 release candidate in two ways: Try theย WordPress Beta Testerย plugin (choose the โ€œbleeding edge nightliesโ€ option) […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"David Baumwald\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:2181:\"\n


            The fifth release candidate for WordPress 5.4 is live!

            \n\n\n\n

            WordPress 5.4 is currently scheduled to land on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time!

            \n\n\n\n

            You can test the WordPress 5.4 release candidate in two ways:

            \n\n\n\n\n\n\n\n

            For details about what to expect in WordPress 5.4, please see the first release candidate post.

            \n\n\n\n

            Plugin and Theme Developers

            \n\n\n\n

            Please test your plugins and themes against WordPress 5.4 and update the Tested up to version in the readme to 5.4. The priority in testing is compatibility. If you find issues, please be sure to post to the support forums so we can figure them out before the final release.

            \n\n\n\n

            The WordPress 5.4 Field Guide is also out! Itโ€™s your source for details on all the major changes.

            \n\n\n\n

            How to Help

            \n\n\n\n

            Do you speak a language besides English? Help us translate WordPress into more than 100 languages!

            \n\n\n\n

            If you think youโ€™ve found a bug, you can post to the Alpha/Beta area in the support forums. Weโ€™d love to hear from you! If youโ€™re comfortable writing a reproducible bug report, file one on WordPress Trac, where you can also find a list of known bugs.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8451\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:6;a:6:{s:4:\"data\";s:60:\"\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:17:\"WordPress 5.4 RC4\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:53:\"https://wordpress.org/news/2020/03/wordpress-5-4-rc4/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 24 Mar 2020 22:00:07 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:2:{i:0;a:5:{s:4:\"data\";s:11:\"Development\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:8:\"Releases\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8444\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:388:\"The fourth release candidate for WordPress 5.4 is live! WordPress 5.4 is currently scheduled to land on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time! You can test the WordPress 5.4 release candidate in two ways: Try the WordPress Beta Tester plugin (choose the โ€œbleeding edge nightliesโ€ option) […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:16:\"Francesca Marano\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:2395:\"\n

            The fourth release candidate for WordPress 5.4 is live!

            \n\n\n\n

            WordPress 5.4 is currently scheduled to land on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time!

            \n\n\n\n

            You can test the WordPress 5.4 release candidate in two ways:

            \n\n\n\n\n\n\n\n

            For details about what to expect in WordPress 5.4, please see the first release candidate post.

            \n\n\n\n

            RC4 commits the new About page and updates the editor packages.

            \n\n\n\n

            Plugin and Theme Developers

            \n\n\n\n

            Please test your plugins and themes against WordPress 5.4 and update the Tested up to version in the readme to 5.4. The priority in testing is compatibility. If you find issues, please be sure to post to the support forums so we can figure them out before the final release.

            \n\n\n\n

            The WordPress 5.4 Field Guide is also out! It’s your source for details on all the major changes.

            \n\n\n\n

            How to Help

            \n\n\n\n

            Do you speak a language besides English? Help us translate WordPress into more than 100 languages!

            \n\n\n\n

            If you think youโ€™ve found a bug, you can post to the Alpha/Beta area in the support forums. Weโ€™d love to hear from you! If youโ€™re comfortable writing a reproducible bug report, file one on WordPress Trac, where you can also find a list of known bugs.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8444\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:7;a:6:{s:4:\"data\";s:60:\"\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:17:\"WordPress 5.4 RC3\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:53:\"https://wordpress.org/news/2020/03/wordpress-5-4-rc3/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 17 Mar 2020 21:24:24 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:2:{i:0;a:5:{s:4:\"data\";s:11:\"Development\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:8:\"Releases\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8432\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:384:\"The third release candidate for WordPress 5.4 is now available! WordPress 5.4 is currently scheduled to be released on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time! There are two ways to test the WordPress 5.4 release candidate: Try the WordPress Beta Tester plugin (choose the โ€œbleeding edge […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"David Baumwald\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:4104:\"\n

            The third release candidate for WordPress 5.4 is now available!

            \n\n\n\n

            WordPress 5.4 is currently scheduled to be released on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time!

            \n\n\n\n

            There are two ways to test the WordPress 5.4 release candidate:

            \n\n\n\n\n\n\n\n

            For details about what to expect in WordPress 5.4, please see the first release candidate post.

            \n\n\n\n

            RC3 addresses improvements to the new About page and 8 fixes for the following bugs and regressions:

            \n\n\n\n\n\n\n\n

            Plugin and Theme Developers

            \n\n\n\n

            Please test your plugins and themes against WordPress 5.4 and update the Tested up to version in the readme to 5.4. If you find compatibility problems, please be sure to post to the support forums so we can figure those out before the final release.

            \n\n\n\n

            The WordPress 5.4 Field Guide has also been published, which details the major changes.

            \n\n\n\n

            How to Help

            \n\n\n\n

            Do you speak a language other than English? Help us translate WordPress into more than 100 languages!

            \n\n\n\n

            If you think youโ€™ve found a bug, you can post to the Alpha/Beta area in the support forums. Weโ€™d love to hear from you! If youโ€™re comfortable writing a reproducible bug report, file one on WordPress Trac, where you can also find a list of known bugs.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8432\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:8;a:6:{s:4:\"data\";s:60:\"\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:4:{s:0:\"\";a:6:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:17:\"WordPress 5.4 RC2\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:53:\"https://wordpress.org/news/2020/03/wordpress-5-4-rc2/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 10 Mar 2020 21:40:51 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:2:{i:0;a:5:{s:4:\"data\";s:11:\"Development\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:8:\"Releases\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8422\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:385:\"The second release candidate for WordPress 5.4 is now available! WordPress 5.4 is currently scheduled to be released on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time! There are two ways to test the WordPress 5.4 release candidate: Try the WordPress Beta Tester plugin (choose the โ€œbleeding edge […]\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:16:\"Francesca Marano\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:3311:\"\n

            The second release candidate for WordPress 5.4 is now available!

            \n\n\n\n

            WordPress 5.4 is currently scheduled to be released on March 31 2020, and we need your help to get thereโ€”if you havenโ€™t tried 5.4 yet, now is the time!

            \n\n\n\n

            There are two ways to test the WordPress 5.4 release candidate:

            \n\n\n\n\n\n\n\n

            For details about what to expect in WordPress 5.4, please see the first release candidate post.

            \n\n\n\n

            RC2 addresses improvements to the new About page andย 5 fixesย for the following bugs and regressions:

            \n\n\n\n
            • 49611 – Block Editor: Update WordPress Packages WordPress 5.4 RC 2
            • 49318 – Bundled Themes: Twenty Twenty content font CSS selector is too important
            • 49585 – REST API: Fix typo in disable-custom-gradients theme feature description
            • 49568 – Block Editor: Fix visual regression in editor’s color picker
            • 49549 – Bundled Themes: Calendar widget CSS fixes on various Bundled themes
            \n\n\n\n

            Plugin and Theme Developers

            \n\n\n\n

            Please test your plugins and themes against WordPress 5.4 and update the Tested up to version in the readme to 5.4. If you find compatibility problems, please be sure to post to the support forums so we can figure those out before the final release.

            \n\n\n\n

            The WordPress 5.4 Field Guide has also been published, which details the major changes.

            \n\n\n\n

            How to Help

            \n\n\n\n

            Do you speak a language other than English? Help us translate WordPress into more than 100 languages!

            \n\n\n\n

            If you think youโ€™ve found a bug, you can post to the Alpha/Beta area in the support forums. Weโ€™d love to hear from you! If youโ€™re comfortable writing a reproducible bug report, file one on WordPress Trac, where you can also find a list of known bugs.

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8422\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:9;a:6:{s:4:\"data\";s:79:\"\n \n \n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:6:{s:0:\"\";a:7:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"People of WordPress: Mary Job\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:64:\"https://wordpress.org/news/2020/03/people-of-wordpress-mary-job/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"comments\";a:1:{i:0;a:5:{s:4:\"data\";s:73:\"https://wordpress.org/news/2020/03/people-of-wordpress-mary-job/#comments\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 06 Mar 2020 16:30:43 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"category\";a:3:{i:0;a:5:{s:4:\"data\";s:9:\"Community\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:1;a:5:{s:4:\"data\";s:9:\"heropress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}i:2;a:5:{s:4:\"data\";s:10:\"Interviews\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8406\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:11:\"isPermaLink\";s:5:\"false\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:189:\"In the March edition of our \"People of WordPress\" series, you\'ll find out how Mary Job grew from a timid, curious cat into a public speaker and organizer of WordPress Meetups and WordCamps.\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:16:\"Yvette Sonneveld\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:40:\"http://purl.org/rss/1.0/modules/content/\";a:1:{s:7:\"encoded\";a:1:{i:0;a:5:{s:4:\"data\";s:9720:\"\n

            Youโ€™ve probably heard that WordPress is open-source software, and may know that itโ€™s created and run by volunteers. WordPress enthusiasts share many examples of how WordPress changed peopleโ€™s lives for the better. This monthly series shares some of those lesser-known, amazing stories. 

            \n\n\n\n

            How it all began

            \n\n\n\n
            \"Mary
            Mary Job at WordCamp Kampala 2020
            \n\n\n\n

            Mary remembers when cybercafรฉs started trending in Nigeria. She had just finished high school and was awaiting her results for admission to university. She spent all of her time (10 hours a day) and all of her pocket money buying bulk time online at cafes. All the way through university that was true, until in 2008 she graduated with a degree in philosophy and bought her own computer and modem.

            \n\n\n\n

            She started blogging in 2009. Initially, she tried out Blogger, Hubpages, and WordPressโ€”but found WordPress too complicated. 

            \n\n\n\n

            Growing up as a timid but curious cat

            \n\n\n\n

            Mary is one of four kids, and the only girl among her siblings. Throughout her childhood she felt shy, even though others didnโ€™t always see her that way.

            \n\n\n\n

            When she first started her personal blog, it was mostly an opportunity for her to speak her mind where she was comfortable. Blogging gave her a medium to express her thoughts and with every new post she became a better writer.

            \n\n\n\n

            Rediscovering WordPress

            \n\n\n\n

            After completing a postgraduate diploma in mass communication, Mary started a Masters degree in Information Management. This required a three month internship. She decided to volunteer in Ghana in 2015 at the headquarters of the Salesians of Don Bosco in West Africa (SDBAFW) where her uncle was based.

            \n\n\n\n

            While she was there, her uncle asked Mary why she was not blogging on WordPress, which also happened to be the software the organisation used. She explained how difficult and complicated it was so he shared a group of beginner-level tutorial videos with her.

            \n\n\n\n

            After two weeks of watching those videos, she started to realize she could have a full-time career doing this. So she immediately joined a number of online training groups so she could learn everything.

            \n\n\n\n

            I saw a lot of people earning an income from things I knew and did for the fun of it. I found myself asking why I had not turned my passion into a business.

            Mary Job
            \n\n\n\n

            Not long after that, she was contacted by a website editor who was impressed by her blog. With the information available online for WordPress, she was able to learn everything she needed to improve and redesign a site for what turned into her first client.

            \n\n\n\n
            \"\"
            Mary’s home office in 2016
            \n\n\n\n

            I visited the WordPress.org showcase and was wowed with all the good things I could do with WordPress.

            Mary Job
            \n\n\n\n

            In 2016 after a year of deep WordPress learning, she had fallen in love with the CMS and wanted to give back to the WordPress open source project

            \n\n\n\n

            She volunteered to help the Community team. And when she moved to Lagos later that year, she discovered there was an active WordPress Meetup community. This started her journey toward becoming a WordPress Meetup Co-organizer and a Global Community Team Deputy.

            \n\n\n\n

            Today the Nigerian WordPress community continues to grow, as has the Lagos WordPress Meetup group. The first Nigerian WordCamp took place in Lagos in 2018 and a 2020 event is being planned. A local WordPress community also developed in Maryโ€™s hometown in Ijebu.

            \n\n\n\n

            I have made great friends and met co-organizers in the community who are dedicated to building and sharing their WordPress knowledge with the community like I am.

            Mary Job
            \n\n\n\n

            What did Mary gain from using and contributing to WordPress?

            \n\n\n\n
            • She overcame her stage fright by getting up in front of an audience at her local Meetup to introduce speakers and to talk about the WordPress community. 
            • She attended her first of many African WordCamps in Cape Town, South Africa. Coincidentally this was also her first time outside West Africa. Before that, she had not been in an aircraft for more than one hour.
            • She earned money from WordPress web design projects to sustain her during her learning period. Mary continues to use WordPress in her work and says she is still learning every day!
            • She got to jump off Signal Hill in Cape Town when visiting a WordCamp! 
            \n\n\n\n
            \"\"
            Mary moderating a panel at WordCamp Lagos in 2019
            \n\n\n\n

            Essentially, the community has taught me to be a better communicator, and a better person. Iโ€™ve made friends across the world that have become like a family to me.

            Mary Job
            \n\n\n\n

            She now runs a village hub in Ijebu,  where she teaches girls digital skills and WordPress as a way of giving back to her town.

            \n\n\n\n

            Since she started on this journey, Mary has gotten a fulltime job supporting a WordPress plugin. Sheโ€™s also become a Community Team Rep and continues to build and foster communities.

            \n\n\n\n

            Maryโ€™s advice to others

            \n\n\n\n

            Always seek to understand the basics of whatever knowledge you seek. Never jump in too fast, wanting to spiral to the top while ignoring the learning curve. You will likely crash down effortlessly if you do so, and would have learned nothing.

            Mary Job
            \n\n\n\n

            Contributors

            \n\n\n\n

            Thanks to Alison Rothwell (@wpfiddlybits), Yvette Sonneveld (@yvettesonneveld), Abha Thakor (@webcommsat), Josepha Haden (@chanthaboune), Topher DeRosia (@topher1kenobe). Thank you to Mary Job (@maryojob) for sharing her #ContributorStory.

            \n\n\n\n
            \"\"
            \n\n\n\n

            This post is based on an article originally published on HeroPress.com, a community initiative created by Topher DeRosia. HeroPress highlights people in the WordPress community who have overcome barriers and whose stories would otherwise go unheard.

            \n\n\n\n

            Meet more WordPress community members over at HeroPress.com!

            \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:36:\"http://wellformedweb.org/CommentAPI/\";a:1:{s:10:\"commentRss\";a:1:{i:0;a:5:{s:4:\"data\";s:69:\"https://wordpress.org/news/2020/03/people-of-wordpress-mary-job/feed/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:38:\"http://purl.org/rss/1.0/modules/slash/\";a:1:{s:8:\"comments\";a:1:{i:0;a:5:{s:4:\"data\";s:2:\"18\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:7:\"post-id\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"8406\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}}}s:27:\"http://www.w3.org/2005/Atom\";a:1:{s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:0:\"\";s:7:\"attribs\";a:1:{s:0:\"\";a:3:{s:4:\"href\";s:32:\"https://wordpress.org/news/feed/\";s:3:\"rel\";s:4:\"self\";s:4:\"type\";s:19:\"application/rss+xml\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:44:\"http://purl.org/rss/1.0/modules/syndication/\";a:2:{s:12:\"updatePeriod\";a:1:{i:0;a:5:{s:4:\"data\";s:9:\"\n hourly \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:15:\"updateFrequency\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"\n 1 \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:30:\"com-wordpress:feed-additions:1\";a:1:{s:4:\"site\";a:1:{i:0;a:5:{s:4:\"data\";s:8:\"14607090\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}}}}}}}}s:4:\"type\";i:128;s:7:\"headers\";O:42:\"Requests_Utility_CaseInsensitiveDictionary\":1:{s:7:\"\0*\0data\";a:9:{s:6:\"server\";s:5:\"nginx\";s:4:\"date\";s:29:\"Sat, 23 May 2020 02:16:08 GMT\";s:12:\"content-type\";s:34:\"application/rss+xml; charset=UTF-8\";s:25:\"strict-transport-security\";s:11:\"max-age=360\";s:6:\"x-olaf\";s:3:\"โ›„\";s:13:\"last-modified\";s:29:\"Wed, 13 May 2020 11:05:48 GMT\";s:4:\"link\";s:63:\"; rel=\"https://api.w.org/\"\";s:15:\"x-frame-options\";s:10:\"SAMEORIGIN\";s:4:\"x-nc\";s:9:\"HIT ord 1\";}}s:5:\"build\";s:14:\"20130911040210\";}','no'),(531,'_transient_timeout_feed_mod_9bbd59226dc36b9b26cd43f15694c5c3','1590243369','no'),(532,'_transient_feed_mod_9bbd59226dc36b9b26cd43f15694c5c3','1590200169','no'),(533,'_transient_timeout_feed_d117b5738fbd35bd8c0391cda1f2b5d9','1590243369','no'),(534,'_transient_feed_d117b5738fbd35bd8c0391cda1f2b5d9','a:4:{s:5:\"child\";a:1:{s:0:\"\";a:1:{s:3:\"rss\";a:1:{i:0;a:6:{s:4:\"data\";s:3:\"\n\n\n\";s:7:\"attribs\";a:1:{s:0:\"\";a:1:{s:7:\"version\";s:3:\"2.0\";}}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:1:{s:0:\"\";a:1:{s:7:\"channel\";a:1:{i:0;a:6:{s:4:\"data\";s:61:\"\n \n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:1:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:16:\"WordPress Planet\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:28:\"http://planet.wordpress.org/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:8:\"language\";a:1:{i:0;a:5:{s:4:\"data\";s:2:\"en\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:47:\"WordPress Planet - http://planet.wordpress.org/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"item\";a:50:{i:0;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:63:\"WPTavern: Local Brings Back Support for Apache and Site Cloning\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99924\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:171:\"https://wptavern.com/local-brings-back-support-for-apache-and-site-cloning?utm_source=rss&utm_medium=rss&utm_campaign=local-brings-back-support-for-apache-and-site-cloning\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2899:\"

            Flywheel’s Local development app has received several major updates during the past month. The most recent release brings back support for Apache as a web server choice (version 5.5.1), in response to user feedback. This was the most highly requested feature on the app’s community voting board.

            \n\n\n\n

            Although nginx is the leader in web server market share for the top 10k, top 100k, and top 1M sites, Apache is still used by more of the web. Lack of support for Apache was a deal breaker for many Local users who support clients on shared hosting, which often runs Apache and MySQL. It was also a blocker for potential new users switching from MAMP. Having the option to choose the web server on a per-site basis makes Local much more flexible.

            \n\n\n\n\n\n\n\n

            Site cloning is another highly requested feature that was brought back in version 5.3.3 at the end of April. Users can now right-click on a site in Local’s sites sidebar and click on “Clone Site.” This feature is useful for using one site as a jumping off point or even for setting up a “blueprint” for future sites to use.

            \n\n\n\n

            Flywheel is gradually adding back a list of features after rebuilding Local’s core architecture in 2019. The “Local Lightning” update moved the app away from virtualization in favor of native, system-level software for running WordPress locally.

            \n\n\n\n

            “Feature parity with Local Classic is the top item for us in our Q2 roadmap,” Local creator Clay Griffiths said. So far his team has already brought back 64-bit PHP binaries for Windows, site cloning, and Apache support as part of this process.

            \n\n\n\n

            The app has become an indispensable development tool for many WordPress developers. In February, WP Engine reported that Local is used by more than 50,000 developers. The company has a long-term roadmap that aims to make it easier for users to customize their development environments.

            \n\n\n\n

            Local has a fairly transparent development process with community feature requests highly prioritized. The app’s community feedback site gives users an overview of all the features that are currently planned, in progress, and complete. Updates currently in progress include a setting for a default browser and improvements to the Live Link feature. The team is also exploring a Local CLI as part of the Q2 roadmap.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 22 May 2020 22:21:34 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:1;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:66:\"WPTavern: Should WordPress Provide an API for Third-Party Editors?\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99970\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:175:\"https://wptavern.com/should-wordpress-provide-an-api-for-third-party-editors?utm_source=rss&utm_medium=rss&utm_campaign=should-wordpress-provide-an-api-for-third-party-editors\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6858:\"

            Imagine a future where you log into your website’s admin. You head over to the editor. This particular editor has all the tools and features in place that make you more efficient at producing whatever content you put out for the world to see. You immediately start tapping keys or dragging your mouse around the screen, satisfied with what the software you’re using has to offer.

            \n\n\n\n

            Today, that editor may be the default block editor for WordPress. Some may be running the Classic Editor plugin for a familiar writing experience. Others will be crafting beautiful layouts with the Elementor page builder.

            \n\n\n\n

            As of this week, people are finding themselves at home with Iceberg, an interface built on top of the block editor for folks who prefer a minimalist environment and love Markdown.

            \n\n\n\n

            Some bloggers post by email. Others use apps from their phone. And, an entire class of people works in third-party, offline editors such as Microsoft Word, Atom, and plain ol’ Notepad.

            \n\n\n\n

            If there is one thing I have come to realize over the years it is that editing environments are as varied as the people who use them. There is no one-size-fits-all solution. The experience I am looking for is not necessarily the same experience you need.

            \n\n\n\n

            Given the freedom to choose, most people would rearrange their desk, use a different notepad, and opt for a different writing utensil than their neighbor. Even if starting with the same tools, we eventually make tweaks to accommodate our personal tastes.

            \n\n\n\n

            Throughout most of its history, WordPress has had a single editor that its users shared. It has changed over time — even the addition of TinyMCE was once controversial. However, the default editor has never been sufficient for every user. Personally, I abhorred the classic editing experience. It led me to write in various Markdown editors over the years for efficiency and a true distraction-free experience. It has also led to developers taking on the challenge of creating alternative experiences for large swaths of end-users.

            \n\n\n\n

            As much as many people love the classic WordPress editor, it was a pain for many others. Otherwise, all of the tools that have cropped up over the years would have been unnecessary.

            \n\n\n\n

            In much the same way, the block editor is often a love-it-or-hate-it experience. It is the ideal editing environment for many users. For others, it is a roadblock at best. At worst, it is worthy of a gasoline soaking and a book of matches.

            \n\n\n\n

            The promise of WordPress is to provide an editing experience that allows people from all walks of life to publish their content on the web. The promise is to make that experience as pain-free as possible and to continue iterating toward that unattainable-but-worthwhile-goal of perfecting the publishing process.

            \n\n\n\n

            WordPress — any publishing platform for that matter — is only as good as its editor.

            \n\n\n\n

            It is a predicament. There is no way to make the ideal editor for all people.

            \n\n\n\n

            What’s the next move?

            \n\n\n\n

            An Editors Registry and API

            \n\n\n\n

            In the comments of the Tavern’s Iceberg editor coverage, Phil Johnston proposed a solution for WordPress going forward. “With all of the amazing publishing experiences coming out, I wonder if it’s time for WP to include the concept of ‘Editors,\'”, he wrote. “Like an official registry of installed Editors.”

            \n\n\n\n

            He later created a feature request that called for an API that would make it easier for plugin authors to create new editing experiences on top of WordPress. The proposal is a high-level idea about how the editing screen could allow users to choose their preferred editor.

            \n\n\n\n

            Potentially, users could install and use various editors, depending on what type of content they are building. A user may want something akin to a Markdown editor for blog posts but switch over to a page builder for their site’s pages. eCommerce plugins might have custom editing interfaces that are ideal for shop owners. Ultimately, the possibilities are endless. But, it all starts down at the WordPress level.

            \n\n\n\n

            The idea is not about dropping the default WordPress editor. It is about creating a flexible framework for plugin developers to cater to more users’ needs. Additional methods of editing content would make WordPress a stronger CMS, drawing in users who would otherwise prefer a different experience, regardless of the type of site they are building.

            \n\n\n\n

            It is possible to do this now. However, what could WordPress be doing to improve this process for developers?

            \n\n\n\n

            Jeffrey Carandang, co-creator of Iceberg, believes that core could open the editing space to more third-party solutions. “Creating our own editor mode was challenging but a super exciting experience overall,” he said. “Gutenberg is still far from being extensible compared to other parts of WordPress, but we managed to hack on some areas that needed to work.”

            \n\n\n\n

            Carandang identified a few hurdles his team had to overcome when building the Iceberg editor:

            \n\n\n\n
            • Limited hooks and filters outside of block development, such as the top and bottom areas of the editor and wrappers.
            • Little-to-no options to remove editor components, relying on CSS hacks to hide them.
            • The core editor’s reliance on localStorage.
            \n\n\n\n

            In addition to the primary issues, his team had to develop against multiple versions of the block editor to ensure a seamless experience for users. Despite the issues, he still believes in a future where the block editor project can open up “potential innovations” in the space.

            \n\n\n\n
            \n\n\n\n

            Today, I am composing this post in an offline Markdown editor. I will copy and paste my second or third draft into the block editor, which does a great job of converting Markdown into blocks, before final edits. On other days, I work directly in WordPress, depending on my mood. However, my preferred writing experience is as simple as it gets and often happens in Atom. It is what I am accustomed to.

            \n\n\n\n

            I wonder if there will one day be an editor that will convert me to writing full time from within WordPress. I eagerly await the plugin developers who will make the attempt. My hope is that WordPress cultivates these ideas without standing in the way.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 22 May 2020 19:05:07 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:2;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:54:\"WPTavern: Molly Burke on the Power of Universal Design\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99949\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:153:\"https://wptavern.com/molly-burke-on-the-power-of-universal-design?utm_source=rss&utm_medium=rss&utm_campaign=molly-burke-on-the-power-of-universal-design\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:1814:\"

            In a 2017 speech titled “Stop trying to fix disability,” YouTube and motivational speaker Molly Burke says, “I live in a world that wasn’t built for me, but what if it was?” Burke was born with a rare, genetic eye disease that caused her to go blind. In this short but moving 8 minute video, she contends that making the world accessible helps everyone. She introduces the concept of universal design to her audience in simple terms:

            \n\n\n\n

            “Universal design [is] designing and building everything to be accessed, enjoyed, and understood to its fullest extent by everyone, regardless of their size, their age, their ability, or their perceived disability.”

            \n\n\n\n

            Burke identified Apple as one company that exemplifies universal design.

            \n\n\n\n

            “Every product they release, I could buy at a store, open up, and use on my own independently, with no extra cost and no assistance needed,” she said. “I ask you to imagine how liberating, how empowering it is to be shown by a company that they view you as belonging to their customers, when so many others tell you the exact opposite.”

            \n\n\n\n

            In honor of Global Accessibility Awareness Day, I wanted to highlight this video that tells just one person’s story on the powerful impact of technology that is built with everyone in mind. Burke’s speech is a poignant reminder of how designers and builders can extend a sense of belonging to their customers by making their products accessible.

            \n\n\n\n
            \n\n
            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 21 May 2020 23:03:30 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:3;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:30:\"Matt: Gradually, Then Suddenly\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:22:\"https://ma.tt/?p=51510\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:46:\"https://ma.tt/2020/05/gradually-then-suddenly/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:4676:\"\n\n\n\n

            The two main theses of my professional career have been that distributed is the future of work, and that open source is the future of technology and innovation. I’ve built Automattic and WordPress around these, and it’s also informed my investments and hobbies. Just today, we announced an investment into a distributed, open source, and encrypted communication company called New Vector.

            \n\n\n\n

            On the distributed front, the future of work has been arriving quickly. This week, a wave of companies representing over $800B in market capitalization announced they’re embracing distributed work beyond what’s required by the pandemic:

            \n\n\n\n\n\n\n\n

            Change happens slowly, then all at once.

            \n\n\n\n

            The forces that enable working in a distributed fashion have been in motion for decades, and if you talk to anyone who was working in technology in the ’60s and ’70s they expected this to happen much sooner. Stephan Wolfram has been a remote CEO for 28 years. Automattic has been distributed-first for 15 years.

            \n\n\n\n

            What’s been holding us back is fear of the unknown, and attachment to the familiar. I can’t tell you how many of the investors I see espousing distributed work once told me that Automattic would never scale past a few dozen people unless we brought everyone into an office. Or the CEOs who said this would never work for them, now proclaiming their company hasn’t missed a beat as tens of thousands of people started working from home.

            \n\n\n\n

            What’s going to be newsworthy by the end of the year is not technology companies saying they’re embracing distributed work, but those that aren’t. Those who thought this couldn’t work have been forced by the pandemic to do it anyway, and they’ve now seen that it’s possible.

            \n\n\n\n

            It was probably terrible at first, but now two or three months in it’s gotten better. We’ve learned and adapted, and will continue to do so. Necessity breeds invention. I promise you if you stick with it, you’ll progress through the levels of distributed autonomy. Over time people will be able to move houses, tweak furniture, buy equipment, upgrade their internet, and otherwise adapt to being more productive in a distributed environment than they ever could be in an office. Products and services are being developed all around the world that will make it even better. I’m so excited about how a majority of the economy going distributed will improve people’s quality of life, and unlock incredible creativity and innovation at work. (They go hand in hand.)

            \n\n\n\n

            At some point, we’ll break bread with our colleagues again, and that will be glorious. I can’t wait. But along the way we’ll discover that things we thought were impossible were just hard at first, and got easier the more we did it. Some will return to physically co-working with strangers, and some employers trapped in the past will force people to go to offices, but the illusion that the office was about work will be shattered forever, and companies that hold on to that legacy will be replaced by companies who embrace the antifragile nature of distributed organizations.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 21 May 2020 20:28:47 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:4:\"Matt\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:4;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:59:\"WPTavern: PHP and WordPress Version Checks Coming to Themes\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99928\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:163:\"https://wptavern.com/php-and-wordpress-version-checks-coming-to-themes?utm_source=rss&utm_medium=rss&utm_campaign=php-and-wordpress-version-checks-coming-to-themes\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:4753:\"

            PHP and WordPress version checks are coming to the WordPress theme system — finally. The feature was pulled into core WordPress three days ago. It will prevent end-users from installing or activating a theme that is incompatible with their current version of PHP or WordPress. The change is slated to land in WordPress 5.5.

            \n\n\n\n

            This feature has long been on many theme authors’ wish lists, particularly PHP version checking. Plugins authors gained the ability to support specific PHP versions starting with WordPress 5.2. However, theme authors were left feeling like the second-class citizens they usually are when it comes to the addition of core features, waiting patiently as plugin authors received the new and shiny tools they were looking forward to.

            \n\n\n\n

            Previously, the code for manually handling version checking within individual themes was more complex than in plugins. Theme authors needed to run compatibility checks after theme switch and block theme previews in the customizer using two different methods, depending on the user’s WordPress version. That is assuming theme authors were covering all their bases.

            \n\n\n\n

            Users had no real way of knowing whether a theme would work on their site before installing and attempting to activate it. It was a poor user experience, even when a theme gracefully failed for the end-user.

            \n\n\n\n

            This user experience has also held back some theme authors from transitioning to newer versions of PHP. For years, many were supporting PHP 5.2. Slowly, some of these same authors are now making the move toward newer features up to PHP 5.6, which is now the minimum that WordPress supports. However, not many have made the jump to PHP 7 and newer.

            \n\n\n\n

            Until now, there has been no mechanism for letting the user know they need to upgrade their PHP to use a particular theme.

            \n\n\n\n

            Some theme authors may choose to continue supporting older versions of PHP, such as 5.6, for a potentially wider user base. However, developers who want to switch to newer features can now do so with the support of the core platform.

            \n\n\n\n

            Changes for Users

            \n\n\n\nNew WordPress and PHP versions added to Twenty Twenty theme.\n\n\n\n

            Users who are browsing the WordPress theme directory may begin to notice new information available for some themes. Similar to plugins, visitors should see a WordPress Version and PHP Version listed for some themes. For example, the Twenty Twenty theme now lists the following minimum requirements:

            \n\n\n\n
            • WordPress Version: 4.7 or higher
            • PHP Version: 5.2.4 or higher
            \n\n\n\n

            Not all themes will have these numbers listed yet. It will take some time before older themes are updated with the data required to populate these fields.

            \n\n\n\n

            In WordPress 5.5, the admin interface for themes will change. When attempting to install or activate a theme, WordPress will prevent such actions. If a user searches for a theme that has an incompatible WordPress or PHP version, the normal installation button will be replaced with a disabled button that reads “Cannot Install.” If a theme is installed but not activated, the activation link will similarly be replaced with a disabled “Cannot Activate” button. Users will also not be allowed to live preview incompatible themes.

            \n\n\n\nCannot activate Twenty Twenty theme with incompatible PHP version.\n\n\n\n

            The feature works the same from within the customizer interface as it does via the themes screen in the WordPress admin.

            \n\n\n\n

            Changes for Theme Authors

            \n\n\n\n

            The WordPress Themes Team recently announced two new required headers for theme authors to place in their style.css files. The first required field is Tested up to, which is the latest version of WordPress the theme has been tested against. The second is a Requires PHP field, which is the minimum PHP version the theme supports.

            \n\n\n\n

            It is unclear is why the team decided to require those two fields but not the Requires at least field, which represents the minimum WordPress version needed. Most likely, theme authors will want to place all three headers in their themes.

            \n\n\n\n

            Theme authors who will still support versions of WordPress earlier than 5.5 will want to continue using their old compatibility checks. However, this is the first step in phasing such code out.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 21 May 2020 19:57:03 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:5;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:80:\"WPTavern: WordCamp Kent Online Features Business and Marketing Tracks, May 30-31\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99897\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:203:\"https://wptavern.com/wordcamp-kent-online-features-business-and-marketing-tracks-may-30-31?utm_source=rss&utm_medium=rss&utm_campaign=wordcamp-kent-online-features-business-and-marketing-tracks-may-30-31\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2315:\"

            One of the exciting things about WordCamps going virtual is the community gaining access to more events and presentations than ever before, from anywhere in the world. Even in this new online-only format, local camps still retain their unique character as they feature speakers from their respective communities.

            \n\n\n\n

            WordCamp Kent (Ohio) is one of these upcoming events that has been forced online by the pandemic. Organizers will be broadcasting all sessions on the weekend of May 30-31, and tickets are free for anyone who wants to attend.

            \n\n\n\n

            The schedule for this particular event runs heavy on the business and marketing side of working with WordPress, with very few talks geared towards developers. If you are a freelancer, run an agency, or have a WordPress product business, you will find WordCamp Kent’s program more tailored to topics that help you improve client services.

            \n\n\n\n

            The schedule on the first day of the event is divided into two tracks: Freelance/Business and User/Marketing. These sessions will run alongside live Q&A and a Help Desk managed by volunteers in the #wp-help-desk channel in the NEO WordPress Slack workspace. The second day of the event will be also be split into two tracks: Freelance/Business/Developer and WordPress 101/User.

            \n\n\n\n

            Topics include designing websites for generating leads, improving your business model for freelancers and small businesses, client consultations, content marketing, and customer support.

            \n\n\n\n

            This Kent, Ohio, WordCamp may not have made it on your radar in the past, but the pandemic has opened up events in some ways. It forces a greater number of camps online and allows attendees to join any event without the travel expenses that would ordinarily be prohibitive. In the past, many people who were not local would simply opt to save their money for the bigger camps. The WordPress community has a greater potential to accelerate their learning opportunities, as more smaller camps gain a global audience online.

            \n\n\n\n

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 21 May 2020 17:19:17 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:6;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:103:\"WPTavern: CampusPress Releases Accessible Content Plugin in Time for Global Accessibility Awareness Day\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99804\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:251:\"https://wptavern.com/campuspress-releases-accessible-content-plugin-in-time-for-global-accessibility-awareness-day?utm_source=rss&utm_medium=rss&utm_campaign=campuspress-releases-accessible-content-plugin-in-time-for-global-accessibility-awareness-day\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:10213:\"

            While it is still Wednesday here in the U.S., some parts of the world are already awakening to the third Thursday in May, which is Global Accessibility Awareness Day (GAAD). The purpose of the event is to get more people discussing, learning, and addressing issues related to the inclusion of people with disabilities in the digital world. That is what CampusPress hopes to do with its new plugin.

            \n\n\n\n

            The CampusPress team announced its Accessible Content plugin for WordPress last week. The goal of the plugin is to help end-users address accessibility issues on their sites. Many tools are built for developers and designers, but the team wanted something to put into the hands of users to allow them to take the extra steps necessary in creating an accessible website.

            \n\n\n\n

            The plugin is currently available through GitHub, but the team plans to submit it to the official WordPress plugin repository soon. The developers are gathering user feedback from customers and the community first.

            \n\n\n\n

            “Our Accessible Content plugin was developed specifically to help with training and putting real-time information into the hands of those creating WordPress pages and posts,” said Ronnie Burt, General Manager at CampusPress. “There are a ton of site checker tools out there, and many work quite well. But all of them will spit out false positives and list issues on a page that have nothing to do with the content (navigation issues and the like). So as a bit of a disclaimer, by design, this plugin will not find or help with all potential accessibility issues on a site. But if used over time, it will help train content creators to understand many of the best practices that they should be following and avoid mistakes.”

            \n\n\n\n

            CampusPress is a managed WordPress hosting and service provider for organizations in the educational sector. It is a sister service to Edublogs.org, which originally launched 15 years ago.

            \n\n\n\n

            “In that time, we’ve been quietly catering to the unique needs of schools and universities that use WordPress in various ways,” said Burt. “Historically, that was more on the blogging and learning side, but as WordPress has grown into the CMS of choice, we’ve moved along with it to high-level main websites too.”

            \n\n\n\n

            Development of the Accessible Content plugin will help the CampusPress team’s customers in education, particularly when diving into the world of accessibility guidelines.

            \n\n\n\n

            “Overall, awareness around accessibility has improved considerably in recent years, but for many, the topic is overwhelming,” said Burt. “In our case, school administrators know they need a ‘compliant’ site, but when you go to read the compliance standards, some are subjective and, at best, really complex. The biggest hurdle that we see is that we are still in a place where accessibility expertise is left up to specialists or tools that are usually brought in after the fact or at the end of a project. In an ideal world, we’ll get to where the expertise is shared by all developers, content creators, and anyone else working on the site. This is because accessibility is so much better and easier when it is built-in and thought about from the beginning and continuously.”

            \n\n\n\n

            The team is releasing this plugin not only to its customer base but as a free tool for all WordPress users.

            \n\n\n\n

            How the Plugin Works

            \n\n\n\n

            The plugin is simple enough for most people to use. When previewing a post, it labels and points out issues that need attention. The goal is not to focus on larger accessibility issues that may be coming from the theme. Instead, the plugin lists issues directly with the post content.

            \n\n\n\n

            The interface on the post preview screen is simple enough to understand without documentation. Preview a post and the plugin provides buttons on the sides of the screen to navigate through each issue found. At the bottom of the screen, it leaves a full description of the problem. Users can also access this feature via the toolbar on the site front end when viewing a post.

            \n\n\n\nAccessible Content plugin’s output on post preview.\n\n\n\n

            In some cases, such as missing image alt text, the plugin provides a link to directly add the alt text in the admin. This is done through a custom Alt Text sub-menu under the Media screen in the WordPress admin. Users can also use this screen at any time to manage alt text for images used throughout the site in one location.

            \n\n\n\n\n\n\n\n

            Burt said the original spec for the plugin had all of the accessibility checks and information within the block editor interface. However, the team hit a couple of roadblocks and ended up moving the plugin’s interface to the post preview screen as a result.

            \n\n\n\n

            “Gutenberg is still in flux at a pretty rapid pace,” he said. “Just as we were getting our first proof of concept working on the image block, there was a change and it all broke. No fun! But moving to the previewer had some nice unintended consequences. Namely, the plugin works just as well with Classic Editor and with most page builders. The trade-off is that the warnings and helpful text aren’t quite in as real-time as I hope to get them to someday.”

            \n\n\n\n

            In the long term, the team still plans on integrating directly with the block editor. For now, the plugin works well as part of the previewer. However, instant feedback in the editor would be a huge boost to fixing accessibility issues as they arise.

            \n\n\n\n

            Community Accessibility Improvements

            \n\n\n\n

            Burt was not shy about sharing his thoughts about what the WordPress community can be doing to improve accessibility around the web. He praised some of the work that the WordPress project has done thus far. He also shared some concerns.

            \n\n\n\n

            “One thing I’m worried about — there’s a trend out there with a few WordPress plugins and a growing number of third-party tools to add a little ‘accessibility’ icon to the corner of your website,” he said. “When clicked, these icons open up options for fonts, contrast ratios, and may give an alternative way of navigating the site. I’ve noticed them on bank websites, government sites, and now the schools we work with are buying into them too because it can be tempting to just add a few snippets of embed code to a site and call it a day. To me, this sorta lets all of us that work on websites off the hook to not be responsible for accessible design and development, which really should be our ultimate goal.”

            \n\n\n\n

            He stressed that using quality themes and plugins as a good step for most users along with being mindful of the content we create. Taking these simple steps should make for a more accessible user experience overall.

            \n\n\n\n

            “There is lots of good news when it comes to WordPress and accessibility that we should be shouting from the rooftops,” said Burt. “For one, while there’s still a bit of work to be done, the majority of the issues identified in the WPCampus sponsored audit of Gutenberg have been resolved. That was a great example of the higher-ed community leading the charge to impact change. Without the change, simply put, schools, universities, and government agencies may be forced or encouraged to drop their adoption of WordPress.”

            \n\n\n\n

            The WPCampus-sponsored audit in 2019 resulted in a 329-page technical analysis by Tenon, LLC. It covered user-based testing that included people with various disabilities. Since then, the Gutenberg project has worked to overcome issues identified by the audit.

            \n\n\n\n

            “As I use Gutenberg more and more, there are some nice little accessibility Easter eggs for content creators, such as warnings about contrast ratios and the Headings block won’t show you the option for H1 by default,” said Burt. “I love it! If our community can just continue to highlight these improvements whenever possible, it will make a big difference. I’m also hopeful that some of our checks from this plugin can eventually not be needed as future improvements to blocks and the editor are made.”

            \n\n\n\n

            Burt described the best thing the community can do is to be responsive and treat all accessibility issues as a major bug or even a release blocker before plugins or themes go live. In part, it is about being open to communicating and resolving issues that users bring up.

            \n\n\n\n

            “With so many competing priorities, it can be tempting to just write off a complaint or suggestion as coming from one user,” he said. “But really this is how we continue to make the most progress on all of our tools and services. Feedback from users on barriers and problems they face in using our stuff is pure gold and useful to help ensure we don’t repeat those same mistakes.”

            \n\n\n\n

            Burt listed some key questions he believes the community should continue having conversations around:

            \n\n\n\n
            • Should all new themes to WordPress.org be required to meet the ‘accessibility-ready’ standards?
            • Are there similar standards and checks we could add to plugins? How can plugin authors declare if their plugin may impact accessibility?
            • Is a separate ‘Accessibility’ team for WordPress core still the best way? How do we improve accessible design and development earlier on in practice? It is usually much harder to fix accessibility issues than it is to prevent them to begin with.
            \n\n\n\n

            These are definitely worth discussing further. For now, his team is trying to do its small part with the Accessible Content plugin.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 20 May 2020 19:39:25 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:7;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:86:\"WPTavern: New Iceberg Plugin Brings a Distraction-Free Writing Experience to WordPress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99062\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:217:\"https://wptavern.com/new-iceberg-plugin-brings-a-distraction-free-writing-experience-to-wordpress?utm_source=rss&utm_medium=rss&utm_campaign=new-iceberg-plugin-brings-a-distraction-free-writing-experience-to-wordpress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:8656:\"

            Ever on the hunt for a more beautiful, simplified writing experience inside WordPress, I jumped at the chance to beta test the new Iceberg plugin. Rich Tabor and Jeffrey Caradang, the same team behind CoBlocks, have created a new markdown editor built on top of Gutenberg that provides the best writing experience for WordPress since core’s retired Distraction Free Writing mode.

            \n\n\n\n\n\n\n\n

            Iceberg features a minimalist editor with four color themes, the ability to create a custom theme, and a set of typography controls. In switching to Iceberg, there is not much missing much from the default block editor that would be necessary for writing. Users can drag and drop media into Iceberg and the backslash command works to trigger the block inserter. It also includes a Table of Contents, word and character counts, reading time, keyboard shortcuts, and support for emoji.

            \n\n\n\n

            “Iceberg was brought to fruition out of an experiment to make WordPress look and feel more like my favorite writing applications,” Tabor said. “My personal publishing flow was to write in an external application, paste it all into the block editor, followed by fixing/adjusting/resizing everything–honestly not fun. You see, writing with blocks is just ‘ok’ – and doesn’t feel natural.

            \n\n\n\n

            “After chatting with others, I realized a lot of folks shared the same sentiment and that such a small number of folks I talked to actually composed articles within WordPress. And although I appreciate how far the block editor has come over the years as a site editor and page builder, I wanted to morph the experience to better support publishing.”

            \n\n\n\n

            The Iceberg name is a nod towards Guten “berg.” Tabor said he wanted the project to seem more approachable, without being tied to WordPress or emphasizing blocks.

            \n\n\n\n

            Tabor said he was inspired by dedicated writing applications like Bear, Ulysses, Dropbox Paper, and Google Docs. What he loves most about Iceberg is that its design is centered around the writer’s preferences.

            \n\n\n\n

            “The editor themes that sit at the core of Iceberg’s design language empower each writer to define their flavor of the editor,” he said. “Every color variable is auto-generated based on the editor theme and applied throughout the interface as necessary.”

            \n\n\n\n

            Gutenberg was also a strong inspiration for the design principles that guided Tabor in creating Iceberg.

            \n\n\n\n

            “Gutenberg itself is undergoing quite a transformation with what’s being dubbed as ‘G2’ – a new design system geared towards improved contrast, modern lines and an overall cleaner look,” he said. “I knew I wanted to push Iceberg in that direction, bringing a clean and modern look to the writing environment.”

            \n\n\n\n

            Under the hood, Iceberg is simply an extension of the block editor that de-emphasizes blocks to better enable writers. Since the plugin manipulates the editor itself, users’ content remains intact even if it is deactivated.

            \n\n\n\n

            “It’s a clever combination of React components, styles, CSS custom variables and UX that is centered entirely around the art of writing,” Tabor said. “In short, if folks are familiar with Gutenberg development, they’ll find Iceberg similarly structured.”

            \n\n\n\n

            Tabor said he wants to keep the plugin simple while also exploring where he can push the writing experience further forward. Possible features coming to the roadmap include goal setting, readability analysis, an improved pre-publish checklist, and better post previews/live previewing.

            \n\n\n\n

            Iceberg Gets Positive Reviews at Launch, Fills a Gap in the Block Editor’s Support for Writers

            \n\n\n\n

            Iceberg is launching as a commercial product, priced at $39 for a single site or $99 for unlimited sites. The product seems to have filled a gap in the market, covering Gutenberg’s long-standing deficiency in supporting writers. Community feedback during the beta and on Twitter and Product Hunt has so far been overwhelmingly positive.

            \n\n\n\n

            “Iceberg is like a noise-cancellation for the WordPress editor,” Rajendra Zore said.

            \n\n\n\n

            Nick Hamze offered feedback in a Twitter thread, saying he was excited to see a product that can “take markdown back from developers.” He views Iceberg as a positive development in the WordPress product space, and urged the community to support these kinds of innovations:

            \n\n\n\n

            The fun thing about Iceberg is it’s an enhancement of the block editor not a replacement. No editor can be everything to everyone. Iceberg takes all the parts that are great for writers and emphasizes them while moving everything else into the background.

            It’s not a criticism of the block editor but a celebration of it. Even if you aren’t a writer I think you should buy a copy. As a community we need to support people who are doing stuff like this. They’re never going to stop making cool stuff but they might stop making it for WP.

            \n\n\n\n

            After beta testing the plugin I found that it provides the kind of writing experience that I have been missing in the block editor. Iceberg removes the cumbersome feeling of forcing your writing into blocks. More than anything, I want to see something like this land in WordPress core someday.

            \n\n\n\n

            It’s somewhat bittersweet to see a better writing experience arrive as a commercial plugin, instead of from core improvements. I desperately want WordPress to be home to the best tools for writers, because it is a publishing platform that is so powerful in nearly every other way. This is not to say that core developers cannot adopt something similar. That’s the beauty of open source software – products inspiring new and improved solutions in a never-ending cycle.

            \n\n\n\n

            Gutenberg designers and engineers have been working for the past two years to bring the writing experience in the editor to a functional place that meets the needs of those who use WordPress primarily for writing. So far the block editor’s Fullscreen mode is incapable of producing the kind of zen writing experience that most writers crave when turning to third-party writing apps.

            \n\n\n\n

            Iceberg is GPL-licensed and is even available on GitHub for download and collaboration. I asked Tabor what he planned to do if someone proposed that some version of Iceberg be added to core.

            \n\n\n\n

            “Honestly, I think it would be great if WordPress adopted the same high level of support for writers as Iceberg does,” he said. “Sure it may not be completely ideal economically, but Iceberg is built on an editor built by thousands of hands. If Iceberg is deemed a clever enough solution to be a part of core, then that’s ok. Although I’m positive there’s room to continue experimenting within the realm of empowering writers.”

            \n\n\n\n

            As WordPress continues to move full steam ahead on the site building aspects of the editor, a truly distraction-free writing experience is not likely to become a high priority anytime soon. Tabor sees this as an opportunity for products that can transform the editor for different types of users who may not be focused on building websites.

            \n\n\n\n

            “We’re in such a transformative period of WordPress right now,” Tabor said. “The editing experience we’re building with the block editor is much more focused on designing and publishing websites – not writing posts. Consequently, there’s been much more focus on the site building experience, in lieu of the writing experience. That’s not to say I don’t love the direction WordPress is heading–I absolutely do. But rather that I feel there’s room for a tool to improve the writing experience within the block editor.”

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 19 May 2020 23:16:17 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:8;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:100:\"WPTavern: WooCommerce Payments Allows Shop Owners to Manage Payments Without Leaving WordPress Admin\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99776\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:245:\"https://wptavern.com/woocommerce-payments-allows-shop-owners-to-manage-payments-without-leaving-wordpress-admin?utm_source=rss&utm_medium=rss&utm_campaign=woocommerce-payments-allows-shop-owners-to-manage-payments-without-leaving-wordpress-admin\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:5670:\"\n\n\n\n

            Automattic-owned eCommerce platform WooCommerce launched its new WooCommerce Payments feature today. The company seeks to make it easier for plugin users to manage the entirety of their shop from a single location. For users based in the U.S. with WordPress.com-connected accounts, they can begin managing payments directly from their WordPress admin.

            \n\n\n\n

            WooCommerce Payments is available as a free download via the WordPress plugin directory. Any costs associated with the plugin are on a per-transaction basis. Fees start at 2.9% + $0.30 per transaction for cards issued in the U.S. An additional 1% fee is tacked on for cards outside the U.S.

            \n\n\n\n

            Under the hood, payments are handled through Stripe Express. The WooCommerce team developed the front-end so that it would match the look and feel of WooCommerce, making it function like a native part of the plugin. Stripe handles the processing from the backend.

            \n\n\n\n

            The team began work on the system in 2019 and launched an invitational beta in late February 2020. Since then, it has seen over 1,000 accounts connect to WooCommerce Payments.

            \n\n\n\n

            “New users have been able to add it to their stores in onboarding,” said Paul Maiorana, General Manager of WooCommerce. “Current customers have heard about it through either our newsletter or virtual community meetups. Through this period, we’ve learned what store owners like about WooCommerce Payments — managing their store and payments in one place; intuitive dashboard views; ‘flow’ and ‘ease.’ We’ve also heard their questions, which are mostly related to features we’ve got planned and are working hard to make available as soon as possible.”

            \n\n\n\n

            WooCommerce Payments creates an integrated payments dashboard in the WordPress admin. It allows shop owners to manage charges, deposits, refunds, and disputes without leaving their store. By not having to toggle between the store and third-party payment processors, administrators should be able to enjoy a more seamless experience.

            \n\n\n\n

            The following are some screenshots from a demo install of the WooCommerce Payments plugin:

            \n\n\n\n
            \n\n\n\n

            On the customer end, the experience should also be more convenient for shoppers. Instead of being redirected to a processor like PayPal, customers can make payments directly on the site. This may also help curb cart abandonment, which can often happen when shoppers are redirected.

            \n\n\n\n

            “Now that we’re announcing general availability in the U.S. and putting focused marketing effort behind it, we’re hoping to draw more store owners to join us on the journey,” said Maiorana.

            \n\n\n\n

            New account holders will need to wait for seven business days before receiving their first deposit from sales. Afterward, the payments system will bundle daily revenue into a single deposit and automatically transfer it to the users’ bank accounts. This also cuts out the process of logging into an account with a payment processor to manually deposit earnings.

            \n\n\n\n

            On the Roadmap

            \n\n\n\n

            Currently, WooCommerce Payments is only available to U.S.-based shops. However, the team expects to begin rolling out support for more countries and local payment methods in 2020.

            \n\n\n\n

            “We’re launching in the U.S. to start to manage scope, but WooCommerce is a global platform and global support for WooCommerce Payments is a priority for us,” said Maiorana. “Payments is obviously a complex and highly-regulated space. We have a three-year roadmap for WooCommerce Payments that includes feature and geographical expansion. Our legal and business teams are investing the appropriate time and resources to lay a strong foundation for future growth.”

            \n\n\n\n

            Upcoming releases of the WooCommerce Payments plugin are slated to receive support for subscriptions, saved cards, wallets, and instant deposits.

            \n\n\n\n

            The WooCommerce team also has no plans of stopping with online sales. It is already taking some steps toward moving into the physical world. “WooCommerce’s mission is to democratize commerce — not only eCommerce — so yes, we’re thinking a lot about how to bring this great payment experience offline to point-of-sale devices too,” said Maiorana.

            \n\n\n\n

            It would be interesting to see small store owners with physical locations — from a fruit stand to a collectibles shop to a mom-and-pop restaurant — be able to manage payments from a central location, all backed with WooCommerce and the WordPress platform.

            \n\n\n\n

            The new system does not currently support CBD merchants. WooCommerce has a partnership with Square, and shop owners who are selling CBD-derived products can still use that particular payment processor for the time being. This is likely tied to Stripe’s policies on restricted businesses.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 19 May 2020 17:39:18 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:9;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:69:\"WPTavern: BuddyPress 6.0.0 Released with New Group and Members Blocks\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99784\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:183:\"https://wptavern.com/buddypress-6-0-0-released-with-new-group-and-members-blocks?utm_source=rss&utm_medium=rss&utm_campaign=buddypress-6-0-0-released-with-new-group-and-members-blocks\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:4395:\"

            BuddyPress has entered the world of blocks with the release of version 6.0, the latest major update that has been in development since November 2019. The release, code-named “iovine’s” for a favorite pizza restaurant in Paris, introduces blocks for Groups and Members. It also marks the completion of the BP Rest API, adding the final remaining endpoints for Blogs, Blog avatar, Friends, Group Cover Image, Member Cover Image, and User Signups.

            \n\n\n\n

            The first set of blocks allow community site owners to insert a specific Member or Group from the editor into any WordPress post or page. More advanced customizations are available to developers who want to make blocks available to (or restricted from) specific custom post types. Developers can also override block output using new filters, disable blocks, and specify a custom stylesheet for a block.

            \n\n\n\nNew BP Blocks in action\n\n\n\n

            In a previous WP Tavern review of the 6.0 beta, Justin Tadlock noted that the block settings had each setting is placed within its own tabbed section, which increased the number of clicks required. This feedback was incorporated six weeks ago in a patch from BuddyPress core developer Mathieu Viet, which places all settings into one panel until such a time as more panels become necessary.

            \n\n\n\n

            Next Up for BuddyPress: Block Versions of Existing Widgets and Community-Requested Blocks

            \n\n\n\n

            The BuddyPress community has a unique opportunity to shape the future of block development for the plugin. The next blocks are not yet set in stone but Viet said contributors will probably start by adding block versions of the existing widgets, followed by block requests based on community feedback.

            \n\n\n\n

            “The poll we made about BuddyPress blocks showed there were expectations about a block to share a post or a page into the Activity Stream, so l think we should include such a block,” Viet said. “But we’re are very open to new ideas or contributions to the GitHub repository we use to develop them.”

            \n\n\n\n

            The poll results indicated that in addition to a block to share a post or a page via the Activity Stream, the community is also strongly interested a block to list the recently published posts from across a network, followed by a block to display Sitewide Notices posted by the site administrator. 

            \n\n\n\n

            Viet said core contributors have not yet set a roadmap but are working in small steps and carefully following the Gutenberg project to see how they can incorporate it more into community features. A block-based activity posting form is one feature they are considering.

            \n\n\n\n

            Now is an important time for BuddyPress site owners to give input on the future of the project, whether through block recommendations or via the new 2020 BuddyPress Survey. It includes 17 questions, which take approximately 7-10 minutes to complete. Most of the questions are centered around how you are using BuddyPress on production sites, but one interesting question asks about the prospect of breaking up the plugin’s features to make it more modular:

            \n\n\n\n

            BuddyPress is a large plugin with optional components (3MB zipped). There’s a proposal to reconstitute BuddyPress as core + members only and improved upon with new functionalities and API’s among others for new BP plugins to hook into. The current optional components like groups, friends, private messaging, etc. can be migrated into separate plugins which can be activated as needed. What do you think?

            \n\n\n\n

            Survey respondents have the opportunity to choose between keeping BuddyPress as is with core + members and optional components, or break it down to put the components into BP plugins. Feedback on this proposal and other important survey questions will help the BP core team know how to prioritize features for the next release and long-term roadmap.

            \n\n\n\n

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 18 May 2020 22:06:11 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:10;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:71:\"WPTavern: WordPress Theme Review Team Changes Name, Now the Themes Team\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99570\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:185:\"https://wptavern.com/wordpress-theme-review-team-changes-name-now-the-themes-team?utm_source=rss&utm_medium=rss&utm_campaign=wordpress-theme-review-team-changes-name-now-the-themes-team\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6243:\"

            Last week, the official Theme Review Team (TRT) decided to change its name. The re-branding was mostly about fixing a naming mistake for a team with multiple responsibilities outside of reviews. The hope is that it also shifts the public perception about what the team does.

            \n\n\n\n

            The idea isn’t new. The team has tossed the concept of a name change around for a few years. It was always going to become the Themes Team unless another naming idea came around and stole the spotlight.

            \n\n\n\n

            The original concept of changing the name was about inviting others in. To most, the team had been little more than the gatekeepers to the theme directory. However, its members and the work they do for the community reach beyond that scope. Few know or recognize its role outside of reviewing themes, which makes it tougher to bring people on board.

            \n\n\n\n

            “We realized that we are doing all these theme-related things — work on Twenty Twenty, coding standards, meta stuff, reviews, helping out with full-site editing in any capacity we can, etc. — that being just the Theme Review Team just didn’t make any sense,” said Denis Žoljom, the team’s automation representative. “So we discussed that idea with Josepha [Haden]. In principle, she had nothing against it, so we decided to just go ahead and do the name change.”

            \n\n\n\n

            The team is in the process of renaming some things, such as its GitHub organization. It will take a little time to get everything in order.

            \n\n\n\n

            The Themes Team’s primary mission is not changing in terms of reviewing themes. They will continue taking on that role of making sure themes meet coding and security standards, which is a vital and oftentimes thankless task.

            \n\n\n\n

            “We are reviewing themes as usual, but we are more experimenting with full-site editing,” said Žoljom. “I’m playing with Gutenberg outside of the editor context in my own projects, so that also gives me a perspective to see what things will change. We are still maintaining the WPThemeReview. Theme Check has seen tons of improvements by Carolina [Nymark], which should be merged on .ORG soon. Ari [Stathopoulos] is working on some Gutenberg-related projects. I have the GitHub review flow that I’d like to explore soon.”

            \n\n\n\n

            Žoljom recently dropped the Theme Sniffer plugin, which was a useful tool for theme authors to check their theme against the WPThemeReview coding standards. He did not have the help from the larger theme developer community to continue working on it. Developers can still use the CLI to check their themes. The plugin was a nice stepping stone for theme authors who are less savvy at typing commands, but projects live and die based on participation.

            \n\n\n\n

            The team representatives want to bring new contributors to the team. “Reviewing themes is an exhausting and complicated process,” said Žoljom, “and, unfortunately, most people give up very fast.” The team also needs fresh blood so that it can rotate through reps. Few people have the necessary experience to fill this role, and the current reps will eventually burn out.

            \n\n\n\n

            “We want to work on more interesting projects that will bring new people who are willing to help with them,” said Žoljom. “Especially around full-site editing that is coming to core soon. It’s a big change, and the more contributors we have to help and test things the better.”

            \n\n\n\n

            The Evolving Team

            \n\n\n\n

            Ari Stathopoulos, the theme packages representative, pointed out the elephant in the room. The name of the team represented a public perception issue. In part, the team name did not make an appealing case for a newcomer to join the team. On the other side of the aisle, it meant the team was sometimes left out on the .ORG side of things, such as not being brought in on key decisions that affect themes.

            \n\n\n\n

            “People don’t know that we do all the things we do,” said Stathopoulos. “They believe that all this team does is reviews because that’s what the name of the team was. The truth is that if something has to do with themes, we work on it. There are cases that we don’t, but that’s usually because of miscommunication. People don’t think of consulting with ‘reviewers’ before making changes that have an impact on themes. Hopefully, this re-branding of the team will eventually lead to better communication and understanding. It may take some time, but we’ll get there.”

            \n\n\n\n

            The Themes Team is beginning to take on even more responsibility. It has been holding block-based themes meetings every two weeks in an attempt to keep everyone updated with the rapid theme-related changes happening in the Gutenberg project. The Make Themes blog will also be receiving weekly updates to help those who are unable to attend the meetings and offer another line of communication.

            \n\n\n\n

            Arguably, the Themes Team will become one of the most important teams over the next year or so. It must bring in new volunteers to help the community transition to a different theme development experience.

            \n\n\n\n

            “There is a definite shift of focus, and future themes should be easier to review, leaving this team more time and energy to focus on actions that will have more impact for the community,” said Stathopoulos. “So changing the name was not only correcting an old mistake but also paving the way for future actions we want to take.”

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 18 May 2020 19:29:50 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:11;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:85:\"WPTavern: iA Writer Adds Expanded Support for IndieWeb Tools and WordPress Publishing\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99636\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:215:\"https://wptavern.com/ia-writer-adds-expanded-support-for-indieweb-tools-and-wordpress-publishing?utm_source=rss&utm_medium=rss&utm_campaign=ia-writer-adds-expanded-support-for-indieweb-tools-and-wordpress-publishing\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2360:\"\n\n\n\n

            iA Writer has been delighting users with its minimal writing experience for nearly a decade, racking up more than 3 million downloads. The most recent version 5.5 release for Mac and iOS moves the bar higher for competing writing apps with new support for previewing PDFs and improved support for publishing to self-hosted WordPress sites.

            \n\n\n\n

            In 2019, MacStories selected iA Writer as App of the Year, describing it as “a case study on how to build a desktop-class iOS/iPadOS app in 2019 that understands the traits of each platform while offering an opinionated, sophisticated design at the same time.” MacStories’ writeup details many reasons why the app continues to find success in 2020.

            \n\n\n\n

            This week’s update introduces support for Micropub, which allows users to publish to Micro.blog and other IndieWeb tools. It also expands the availability of the the IndieAuth system for publishing to WordPress. Users are no longer limited to using Jetpack to authenticate their self-hosted sites.

            \n\n\n\n

            iA Writer users can now use the more lightweight IndieAuth plugin to publish to their self-hosted sites. The plugin acts as an extension to OAuth, allowing the user’s website to be their own OAuth server. This option is helpful for iA Writer users who were reluctant to install Jetpack just to hook up their accounts for publishing.

            \n\n\n\n

            Continued support for WordPress publishing comes as no surprise, not just because of its ubiquity on the web, but also because the iA company website and blog rely on WordPress.

            \n\n\n\n

            iA Writer 5.5 also improves account management for connected services, allowing for the use and reordering of multiple accounts for WordPress, Medium, Ghost and Micropub. Check out the release post for a more detailed look at the Mac and iOS-specific updates in this release.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 15 May 2020 21:46:19 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:12;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:92:\"WPTavern: Gutenberg 8.1 Includes Block Copying, Testimonials Pattern, and Patterns UI Update\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99703\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:225:\"https://wptavern.com/gutenberg-8-1-includes-block-copying-testimonials-pattern-and-patterns-ui-update?utm_source=rss&utm_medium=rss&utm_campaign=gutenberg-8-1-includes-block-copying-testimonials-pattern-and-patterns-ui-update\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6337:\"

            On Wednesday, the Gutenberg team released version 8.1.0 of the plugin. The update includes a new block-copying feature, block pattern search, testimonials pattern, and API changes. The new version does not add a lot of major user-facing changes but improves the experience overall.

            \n\n\n\n

            The update included two dozen bug fixes and nearly as many enhancements. This release feels more like a solid update that addresses many minor items and nit-picks, such as the addition of black and white colors for the default color palette. The ability to paste a document into the post title input, which gets transformed into proper blocks, works great too.

            \n\n\n\n

            One nice improvement is the ability to transform the HTML block to the Code block and vice versa. File this one under why has this not already been possible?

            \n\n\n\n

            If you are following along with the Gutenberg plugin, there are some definite improvements to look forward to in this release, particularly around the block patterns feature.

            \n\n\n\n

            Copy Blocks with Ease

            \n\n\n\nCopying a pullquote block.\n\n\n\n

            Admittedly, this is quickly becoming one of my favorite features of Gutenberg 8.1. The editor toolbar now has a copy button, which allows end-users to copy one or more blocks at the click of a button. It is tucked under the “more rich text controls” dropdown menu.

            \n\n\n\n

            To use the new copy feature, simply select the block or blocks you want to copy. Then, click the copy button. From that point, the block can be pasted back into the editor.

            \n\n\n\n

            For theme authors, plugin developers, or anyone who wants to share the code for a block, copying a block also produces the HTML that can be pasted into a text editor. No more switching to the code view of the editor and hunting down the HTML you want to copy. For example, the pullquote copied from the post in the above screenshot produced the following HTML when pasting into my text editor:

            \n\n\n\n
            <!-- wp:pullquote {\"align\":\"wide\"} -->\n<figure class=\"wp-block-pullquote alignwide\"><blockquote><p><span class=\"rtex-highlighter-0\">What has the Duke of Devonshire? The only great instance that I have ever known of the enjoyment of wealth was, that of Jamaica Dawkins...</span></p></blockquote></figure>\n<!-- /wp:pullquote -->
            \n\n\n\n

            This should make it easy for developers to copy the code of their custom block patterns.

            \n\n\n\n

            Testimonials Pattern

            \n\n\n\nNew pattern for testimonials.\n\n\n\n

            The team added to its growing collection of block patterns with the addition of the Testimonials pattern. The new pattern brings the library to eight in total. It is unclear which patterns will launch when the feature lands in WordPress core. It is still under heavy development and is experimental.

            \n\n\n\n

            The Testimonials pattern is one of the more complex patterns the team has introduced. It is a mix of groups, columns, images, and paragraphs. At points, the blocks are six levels deep.

            \n\n\n\n

            Overall, it worked well among the various themes I tested it against with custom block styles. Visually, it is not inspiring, at least in comparison to what a good designer can do with a testimonials section, but it is a solid stepping stone on the way to more interesting layouts.

            \n\n\n\n

            Inserter UI Adds Search and Titles

            \n\n\n\nSearch for block patterns via the inserter section.\n\n\n\n

            Crossing off two out of three big wish list items from my Gutenberg 8.0 post, the team added search functionality and reintroduced the pattern titles below each pattern in the inserter. These are major improvements. The only item left on my list is for the team to introduce a categorization system for patterns.

            \n\n\n\n

            The search box switches from searching for blocks to patterns once clicking on the patterns tab. The one issue is the search label and placeholder reads “Search for a block” in both instances. Instead, it should read “Search for a pattern” when searching patterns.

            \n\n\n\n

            With my wish list nearly fulfilled for block patterns, I have one more item to add. I would like to see the team introduce slash commands to insert patterns. Typing /testimonials should provide users the option to insert the new Testimonials pattern without clicking the inserter button.

            \n\n\n\n

            Developers: Block Patterns API Changes

            \n\n\n\n

            The Block Patterns API methods of registering and unregistering patterns have changed. In previous versions, developers used the register_pattern() and unregister_pattern() functions. These have been deprecated. Beginning with 8.1.0, developers should update their code to use the register_block_pattern() and unregister_block_pattern() functions.

            \n\n\n\n

            This API change is welcome. It is needed for clarity. However, this sort of API change, even on an experimental feature, is one of the many things that frustrates developers who are attempting to keep up with the project. It is especially frustrating when the discussion was originally opened when the feature was first merged. Naming things is hard. It is one of the hardest things to do in programming, but good naming schemes can also be the difference between great software and poor software. There should be more careful thought and thorough explanations when these issues pop up in tickets.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 15 May 2020 20:04:15 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:13;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:66:\"WPTavern: Google Patches Critical Vulnerability in Site Kit Plugin\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99654\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:177:\"https://wptavern.com/google-patches-critical-vulnerability-in-site-kit-plugin?utm_source=rss&utm_medium=rss&utm_campaign=google-patches-critical-vulnerability-in-site-kit-plugin\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2865:\"

            In late April Wordfence discovered a critical vulnerability in Google’s Site Kit plugin for WordPress that would make it possible for any user on the site to gain full access to the Google Search Console without verifying ownership. Google patched the vulnerability and released the fix in version 1.8.0 on May 7, 2020.

            \n\n\n\n

            Wordfence published a timeline of the vulnerability, describing it as a proxySetupURL disclosure:

            \n\n\n\n

            In order to establish the first connection with Site Kit and Google Search Console, the plugin generates a proxySetupURL that is used to redirect a site’s administrator to Google OAuth and run the site owner verification process through a proxy. Due to the lack of capability checks on the admin_enqueue_scripts action, the proxySetupURL was displayed as part of the HTML source code of admin pages to any authenticated user accessing the /wp-admin dashboard.

            \n\n\n\n

            The other aspect of the vulnerability is related to the site ownership verification request, which used a registered admin action that was missing capability checks. As a result, any authenticated WordPress user was capable of initiating the request.

            \n\n\n\n

            Wordfence identified several ways a malicious attacker might use this vulnerability to the detriment of the site’s ranking and reputation, including manipulating search engine results, requesting removal of a competitor’s URLs from the search engine, modifying sitemaps, viewing performance data, and more.

            \n\n\n\n

            The security fixes are not detailed in the plugin’s changelog on GitHub. It does, however, include a note at the top that states, “This release includes security fixes. An update is strongly recommended.” Google has not published a post to notify users on the news section of the plugin’s official website. Without Wordfence’s public disclosure, users may not know about the importance of the update.

            \n\n\n\n

            Google’s Site Kit plugin has more than 400,000 active installs, according to WordPress.org. Details of the 1.8.0 update are not available to users in the admin, since the plugin’s changelog is hosted on GitHub. There is no way for users to know that the update includes security fixes without clicking through to research. Due to the great deal of sensitive information to which attackers could gain access, users are advised to update the plugin as soon as possible.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 14 May 2020 22:39:24 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:14;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:45:\"BuddyPress: BuddyPress 6.0.0 โ€œiovineโ€™sโ€\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:32:\"https://buddypress.org/?p=311679\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:48:\"https://buddypress.org/2020/05/buddypress-6-0-0/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:9955:\"

            This major release introduces the first two BuddyPress Blocks!!

            \n\n\n\n\n\n\n\n
            \n\n\n\n

            We are very excited to announce the immediate availability of BuddyPress 6.0.0 code-named “iovine’s“. You can get it clicking on the above button, downloading it from theย WordPress.org plugin directory or checking it out from our Subversion repository.

            \n\n\n\n

            If you’re upgrading from a previous version of BuddyPress, it’s always a good idea to back-up your WordPress database and files ahead of time.

            \n\n\n\n

            You can review all of the changes in this 6.0.0 release in the release notes. Below are a few of the key features we know you are going to love!

            \n\n\n\n
            \n\n\n\n

            BP Blocks

            \n\n\n\n
            \"\"
            \n\n\n\n

            BuddyPress 6.0.0 comes with two awesome new blocks for your WordPress Editor: Members and Groups. Made available from the BuddyPress blocks category of your WordPress Block menu, these lovely blocks let you insert a rich content block featuring a specific Member or Group from your community site inside any WordPress Post or Page.

            \n\n\n\n

            If you’re an Advanced BuddyPresser and wish to fine-tune the BuddyPress blocks for your community site, learn more in this section of our development note about these new blocks.

            \n\n\n\n
            \n\n\n\n

            The BP REST API is now complete!

            \n\n\n\n
            \n\n\n\n

            In 5.0.0, we introduced the first REST API endpoints and provided reference documentation for them. In 6.0.0, we are adding the 6 remaining endpoints you were waiting for: Blogs, Blog avatar, Friends, Group Cover Image, Member Cover Image, and User Signups. You can now build full-featured applications using the BuddyPress REST API!

            \n\n\n\n
            \n\n\n\n

            BP Nouveau has been improved

            \n\n\n\n
            \"\"
            \n\n\n\n

            Does your theme support wide layouts? Awesome! The BP Nouveau template-pack now supports wide (and really, really wide) content areas! This is the first of the many improvements we are bringing to our default set of styling components. It never looked so beautiful in your theme.

            \n\n\n\n
            \n\n\n\n

            Under the hood

            \n\n\n\n
            \n\n\n\n

            6.0.0 includes more than 80 changes to improve your BuddyPress experience as users, as contributors to our code and as contributors to our translations. The biggest change moves local avatar management to the Members component. Read more about it in this development note.

            \n\n\n\n
            \n\n\n\n

            We want to hear your voice

            \n\n\n\n
            \n\n\n\n
            \n\n\n\n\n\n\n\n
            \n\n\n\n

            Knowing how you use BuddyPress and getting your point of view about future BuddyPress development is very important to us. Please, take some time to help us decide what’s best for the BuddyPress project.

            \n\n\n\n
            \n\n\n\n

            Many thanks to our 42 contributors to 6.0.0

            \n\n\n\n
            \n\n\n\n
            \n\n\n\n

            This BuddyPress release is only possible thanks to the contributions of the community. Special thanks to the following folks who contributed code, translations, and testing to the release: Adil Oztaser (oztaser), Amit Dudhat (wpamitkumar), Andrea Tarantini (dontdream), Ankit Panchal (ankitmaru), Arslan Ahmed (passoniate), Boone B Gorges (boonebgorges), Brajesh Singh (sbrajesh), Bunty (bhargavbhandari90), Dan Caragea (dancaragea), David Cavins (dcavins), Dominik Schilling (ocean90), etatus, Fayaz Gabol (fayazgabol), Hugo Ashmore (hnla), Jb Audras (audrasjb), Jennifer Burnett (jenfraggle), John James Jacoby (johnjamesjacoby), Justin Tadlock (greenshady), Kashif Gabol(kashifgabol), laudag, Mario Badilla (marbaque), Mathieu Viet (imath), mattjones2207, mercime, mo3aser, modemlooper, Morteza Geransayeh (man4toman), Mukesh Panchal (mukesh27), Paul Gibbs (DJPaul), Pooja N Muchandikar (pooja1210), r-a-y, Renato Alves (espellcaste), santiazpi2, shanebp, Sharaz Shahid (sharaz), sjregan, Stephen Edgar (netweb), Tammie Lister (karmatosed), Tor-Bjorn Fjellner (tobifjellner), Towhidul Islam (itowhid06), twmcmahan, Zishan (zishanj).

            \n\n\n\n
            \n\n\n\n
            \"\"
            \n

            BuddyPress iovine’s

            \n\n\n\n

            If you come to Paris (France), you’ll probably want to visit the Louvre Museum. The greatest Pizza restaurant around is Nicola Iovine’s place. You’ll fall in love with how he cares to respect culinary traditions, share authentic flavors, select great quality products imported from Italy and use the real neapolitan pizza dough.

            \n\n\n\n

            Simply delicious, just like BuddyPress 6.0.0 \"?\"

            \n\n\n\n
            \n\n\n\n

            Photo credits: iovine’s

            \n
            \n\n\n\n
            \n\n\n\n

            Feedback is always welcome <3

            \n\n\n\n
            \n\n\n\n
            \n\n\n\n

            Receiving your feedback and suggestions for future versions of BuddyPress genuinely motivates and encourages our contributors. Please share your feedback about this version of BuddyPress in the comments area of this post. And of course, if you’ve found a bug: please tell us about it into our Support forums.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 14 May 2020 22:30:07 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:12:\"Mathieu Viet\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:15;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:65:\"WPTavern: Envato Launches Template Kits Marketplace for Elementor\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99632\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:175:\"https://wptavern.com/envato-launches-template-kits-marketplace-for-elementor?utm_source=rss&utm_medium=rss&utm_campaign=envato-launches-template-kits-marketplace-for-elementor\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6906:\"

            Watch out block patterns. There is an old player in town making the hard sell before you have even rolled out of bed. Envato just dropped a massive library of template kits for Elementor in your front yard.

            \n\n\n\n

            Not to worry, the company plans to open things up for the block editor in the future. The Elementor page builder just makes the most sense right now. It was the first to market. It is mature and has a backing of 5 million users, many of whom will be accustomed to commercial upsells, and $15 million in recent funding. Financially, it is the smart play. The company can also test the waters of this new category of products before opening it to other page builders and the block editor in a proven market.

            \n\n\n\n

            Envato, the company behind ThemeForest and other marketplaces for creators, launched over 200 template kits today to its large audience of end-users and site builders. The kits cover a wide range of niches. Everything from book authors to medical practices to restaurants is covered.

            \n\n\n\n

            “Launching template kits is our latest response to the growing demand for page builders and customers looking for design inspiration that is simple and easy to apply to their website,” said Cameron Gough, General Manager of Envato’s Content team.

            \n\n\n\n

            While this is not an official partnership between Envato and Elementor, at least not on paper, it further broadens the appeal of the Elementor page builder. It is sure to spur massive growth beyond its current 5 million users. If there is one thing Envato knows how to do and do well, it is selling products. When we questioned whether page builders would be able to compete in the long term with the block editor, the largest third-party theme marketplace is betting at least this one particular page builder can.

            \n\n\n\n

            The marketplace is completely open. “We’re encouraging new and existing authors in the Envato community to create their own template kits and upload them,” said Gough. “It’s a great way to break into this market, especially at this early point.”

            \n\n\n\n

            For site designers who have worked with Elementor, now is a great opportunity to submit a kit. You can set your own price — most kits range between $15-$30. The great thing is that designers are not responsible for building a full WordPress theme from scratch. Instead, they can essentially create multiple templates with a page builder, bundle them via the Template Kit – Export plugin, and cash in.

            \n\n\n\n

            The interesting aspect here is that people with an eye for design and the skillset to build those designs in Elementor can sell their creations without learning to code.

            \n\n\n\n

            What Are Template Kits?

            \n\n\n\n
            \n\n
            Template kits walk-through.\n\n\n\n

            “A template kit is a collection of page and block templates or layouts, each with a similar visual style and typically focused on a particular niche,” said Gough. “See some of the examples in our launch collection like a restaurant, or a gym, or a web/design agency. You could liken it sort of the demo content layer that you can find in some premium themes.”

            \n\n\n\n

            Currently, end-users must have a theme installed that integrates with the Elementor page builder for these template kits to work. After purchasing and downloading a kit, users can simply upload templates to their sites via the Template Kit – Import plugin.

            \n\n\n\n

            Kits are merely a starting point. Users will need to fill in their custom content. They also have the power to change the design through Elementor’s built-in tools.

            \n\n\n\n

            Envato launched the template kits marketplace on its ThemeForest website. The current 200+ kits are broken down into 22 categories, the most popular of which are Business Services, Food and Drink, and Technology Apps.

            \n\n\n\n
            Example template kit screenshots.\n\n\n\n

            Sales are already starting to roll in on launch day. There are no clear favorites at the moment with the top sellers hitting only two sales thus far. This should change in the coming days and weeks. The highest-priced kits tend to contain dozens of templates. Some kits, like Spring Watercolor and Floral, contain over 100 in the collection.

            \n\n\n\n

            “We know many WordPress professionals that want a pre-packaged, fully functional website template may continue to favor our existing collection of WordPress themes,” said Gough. “But we increasingly see customers wanting to develop websites from a page builder foundation rather than a full WordPress theme. For these customers, template kits provide a leg up on design, and it’s important we continue to support those changing needs.”

            \n\n\n\n

            For the launch, there is at least one free template kit called SaaSy. It is a SaaS and app landing page kit that includes 10 page templates and 26 block templates. It will be available for free until May 31.

            \n\n\n\nSaaSy Template Kit – Live Preview\n\n\n\n

            “We know that the WordPress world continues to evolve and respond exceptionally well to the changing needs of the wider web design industry, and you only have to look at Gutenberg as one example of how the platform is evolving to meet the increasing demand for easier tools that provide a leg up on website design,” said Gough.

            \n\n\n\n

            “Couple this with the strength of page builders such as Elementor and others, plus a vibrant and active community of developers, hosting providers, and more, we think there’s never been a better time to provide a new and easier way to bring WordPress websites to life.”

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 14 May 2020 20:03:10 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:16;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:114:\"WPTavern: WordPress Contributor Andy Fragen Shares His Experience as a Trauma Surgeon During the COVID-19 Pandemic\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99619\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:273:\"https://wptavern.com/wordpress-contributor-andy-fragen-shares-his-experience-as-a-trauma-surgeon-during-the-covid-19-pandemic?utm_source=rss&utm_medium=rss&utm_campaign=wordpress-contributor-andy-fragen-shares-his-experience-as-a-trauma-surgeon-during-the-covid-19-pandemic\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:3546:\"\n\n\n\n

            Last weekend I had the opportunity to interview Andy Fragen, a longtime member of the WordPress community and core contributor. He is also the author of the GitHub Updater plugin, which allows developers to enable automatic updates to their GitHub, Bitbucket, GitLab, or Gitea hosted WordPress plugins, themes, and language packs. In the video below, Fragen gives us a window into his world on the frontlines as an acute care surgeon.

            \n\n\n\n

            After working his shifts at the hospital, Fragen returns home and voluntarily keeps himself in semi-isolation from his wife and kids. He spends his time working on his plugins and contributing to WordPress. In addition to improving GitHub Updater, he also recently became a maintainer for the core Site Health component and the WordPress Beta Tester plugin.

            \n\n\n\n

            “I look at computer programming and stuff like that as puzzle solving,” Fragen said. “It’s an interesting way to occupy time and figure out something to do. We have a little aphorism in surgery: the enemy of good is better. I don’t necessarily stick to that in plugin development, because otherwise we’d be at a standstill. Things would never get better and never improve.”

            \n\n\n\n

            During normal times when there isn’t a pandemic going on, Fragen enjoys attending local WordCamps in LA, Orange County, Riverside, San Diego, and Phoenix. When he first started getting involved with WordPress he decided if he was ever going to meet any of the people who make the software, he would have to get involved in some community events. He started sponsoring WordCamps so he could have the opportunity to meet the speakers and contributors, and then he was hooked.

            \n\n\n\n

            When he’s not stitching people back together, Fragen can be sometimes be found leading the the core Site Health meeting. He tries to pop into the core development meeting when his schedule permits.

            \n\n\n\n

            Durning our interview Fragen offered some good tips on navigating the many claims and conspiracy theories that are swirling around with the pandemic. The rampant misinformation campaigns have so far not affected his outlook as a healthcare worker.

            \n\n\n\n

            “For the most part, when we’re working, we’re working, and we don’t necessarily pay attention to all the extraneous things that are going on around,” he said. “You’re in the moment and doing what you need to do to get the work done and take care of the patient.”

            \n\n\n\n

            It has been months since he has been able to hug his wife and kids, but Fragen is maintaining a sense of normal by continuing his hobbies in isolation. Despite the increased requirements for PPE and vigilance at work, he said his training has prepared him for this time.

            \n\n\n\n

            “It’s amazing what you can get used to,” Fragen said. “A lot of these things affect people in different ways. For better or for worse, some of these things never bothered me. The training is hard enough. Because of that, you learn to adapt a little bit better, I guess. When there are things happening, as I like to say, ‘If I’m having a bad day, someone else is having a worse one.’ You are there to take care of them and to fix them as best they can be fixed, if they can be fixed.”

            \n\n\n\n
            \n\n
            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 14 May 2020 05:11:19 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:17;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:64:\"Post Status: On static WordPress, with Miriam Schwab of Strattic\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"https://poststatus.com/?p=78861\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:40:\"https://poststatus.com/static-wordpress/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:1112:\"

            Miriam Schwab is co-founder and CEO of Strattic, a business making a big bet on the future of WordPress โ€” and in particular for using it to create static websites.

            \n\n\n\n

            They recently raised $6.5 million dollars in an oversubscribed round. Strattic aims to enable the power and flexibility of a dynamic WordPress website like we all know, with the security and speed of a completely static website.

            \n\n\n\n

            In this interview, Cory Miller talks to Miriam about her journey to this moment, the Strattic product, raising money, and more.

            \n\n\n\n\n\n\n\n

            Partner: Yoast

            \n\n\n\n

            This episode is brought to you by Yoast, the best WordPress SEO solution, hands down. You can upgrade to Yoast SEO premium, or take advantage of their great bundles that include outstanding training resources so you can fully take advantage of all the awesome tools Yoast SEO provides.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 13 May 2020 23:16:43 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:15:\"Brian Krogsgard\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:18;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:61:\"WPTavern: Where Gutenberg Went Wrong: Theme Developer Edition\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99568\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:165:\"https://wptavern.com/where-gutenberg-went-wrong-theme-developer-edition?utm_source=rss&utm_medium=rss&utm_campaign=where-gutenberg-went-wrong-theme-developer-edition\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:9283:\"Themes with block editor styles on WordPress.org.\n\n\n\n

            With full-site editing just around the bend, it is a fair question to ask whether the WordPress ecosystem is prepared for such a transition, particularly on the theme development side of things.

            \n\n\n\n

            It is no secret that theme developers have struggled to keep up with the barrage of changes between Gutenberg plugin updates and, ultimately, major WordPress versions. It is also a fair question to ask who is steering the ship. Where are the site developers, theme authors, and other designers who spend every day crafting the front end of the web? Where are the forward-thinking solutions that make sure the project maintains backward compatibility?

            \n\n\n\n

            There have been some efforts to mend the broken divide between the Gutenberg project and theme developers such as the fortnightly block-based themes meetings. However, those meetings, by and large, are general updates on things the Gutenberg team has already developed or will ship soon. Those meetings are a good stepping stone toward better communication, but the project needs a project planner with both the vision of the future landscape and a sense of the day-to-day issues that theme authors contend with.

            \n\n\n\n

            The reality is that there are only 132 themes out of 7,455 that list block editor styles as a feature in the official repository. We are a year and a half into the lifespan of the block editor officially merging into WordPress, yet the face of the platform is made up mostly of themes that have shoehorned some basic block styles into mediocre designs. The themes that truly stand out with full block-editor support are few and far between. Many of those are also bidding heavily on Elementor or other page builders.

            \n\n\n\n

            Whether you like the block editor is of little consequence when there is no buy-in from theme authors. Every week, I check the theme directory for new themes, hoping to find a hidden gem. Every week, I am disappointed to see new themes dropping in 2020 with no support for the block editor. There is an entire segment of users who might enjoy the editor if only they had something more than Twenty Twenty to play around with — it is a fine theme but is not everyone’s cup of tea.

            \n\n\n\nThemeForest’s listing of block-styled themes.\n\n\n\n

            ThemeForest sellers are besting free WordPress.org theme authors 18 to 1 in terms of support with over 2,300 themes listed as Gutenberg-optimized. Granted, themes from the massive marketplace are known to have every feature they can in an attempt to one-up the competition. Also, many of them either have built-in page builders or support third-party solutions.

            \n\n\n\n

            Still, for the flagship feature of the platform, end-users should expect something more from the official theme directory. A third-party marketplace should not be the only game in town. At the moment, much of the offerings on WordPress.org feel lackluster at best. The handful that go the extra mile, such as the Rosa 2 and Go themes, have mature businesses funding the effort.

            \n\n\n\n\n\n\n\n

            There is some broken trust between theme authors and WordPress at the moment. Some shout it loudly (as folks can attest from WP Tavern comments section). Others are more quietly trying to figure all this out.

            \n\n\n\n

            Even Carolina Nymark, one of the representatives for the official Themes Team, shared some concern. “How do all of you theme authors keep up with the changes to Gutenberg?” she asked in a tweet. When the team leads are not up to speed, it is not good for the project as a whole.

            \n\n\n\n

            “I don’t,” replied Anders Norén, the primary developer behind Twenty Twenty, to Nymark’s question. “I wait until something breaks (in the beta releases) and try to fix it then. Trying to support changes in the Gutenberg plugin while maintaining support for the block editor in Core is bad for your health.”

            \n\n\n\n

            There is a major concern from theme authors about the future. It is hard to get excited about the current possibilities when there is uncertainty over what theme development will look like in 12 months. There is no clear and detailed roadmap about how things will work, and many theme designers feel like they are playing catchup from week to week. Instead, they should be able to more clearly look ahead and push early ideas into play.

            \n\n\n\n

            My ultimate fear is that the Themes Team will one day flip the switch and require all themes going into the directory to support the block editor like it had to do with the customizer in 2015. If theme authors do not organically make the transition such a day may come. The team will be stuck as the bad guys in the middle.

            \n\n\n\n

            Where Do We Go from Here?

            \n\n\n\n

            It is easy to identify some of the major pain points for theme authors. Changes between updates will inevitably break something with the theme design.

            \n\n\n\n

            Breaking HTML changes.

            \n\n\n\n

            Breaking CSS changes.

            \n\n\n\n

            Missing class names.

            \n\n\n\n

            Different methods of handling alignment, depending on the block.

            \n\n\n\n

            Dealing with inline styles after years of being taught to avoid them.

            \n\n\n\n

            All of these issues are roadblocks for theme authors. And, when things get in the way of theme authors doing their jobs, they trickle down to end-users.

            \n\n\n\n

            This is not the WordPress of the last decade. The WordPress that promised to not break things with updates. The WordPress where a one-off theme by a non-professional designer still worked four months later.

            \n\n\n\n

            The Gutenberg project is still in its infancy. It can be fun to play with, but it can also be messy. I am as much of an evangelist for the block editor as anyone, but I can recognize when there is a clear and present issue of trust between theme authors and the developers of the project.

            \n\n\n\n

            Currently, theme authors who are attempting to cover all of their bases are designing for at least a couple of versions of WordPress, multiple versions of Gutenberg, and the classic editor plugin. It is a dizzying array of testing for one theme. Those with a dozen or more themes…well, it is not an ideal situation.

            \n\n\n\n

            A holistic approach needs to be taken toward theme and site design. Theme authors need to see the details of the roadmap and contribute to it, carving the features they see as relevant into stone for the coming years. They need to know that the buttons block design they sweated over for hours this past week will continue working next week.

            \n\n\n\n

            It all starts at the project management level.

            \n\n\n\n

            If a breaking HTML change needs to happen, theme authors need more than, “X change needs to happen for Y feature to work.” They need to see ownership of the mistake in the initial planning phase for X, backward-compatible code solutions, and a path toward fewer of the same mistakes happening.

            \n\n\n\n

            Theme designers still need some sort of design framework. The current utility classes are like a poor man’s version of Tailwind that is being pieced together as the project adds new features without the foresight to look at the future landscape. Maybe the upcoming Global Styles feature can tackle that on a larger scale that provides compatibility across themes.

            \n\n\n\n

            Ultimately, there needs to be more communication between the Gutenberg team and theme authors who are building themes for the official WordPress theme directory. Perhaps there should even be a new team or sub-team formed focused solely on theming in the block era and working directly with Gutenberg developers to identify pain points. Whatever happens, someone needs to inspire the next generation of themes into being. Until then, most theme authors are stuck wondering what they will need to fix next.

            \n\n\n\n

            Up next: block/plugin development edition?

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 13 May 2020 20:19:28 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:19;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:48:\"WPTavern: GitHub Adds Account Successors Feature\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99556\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:141:\"https://wptavern.com/github-adds-account-successors-feature?utm_source=rss&utm_medium=rss&utm_campaign=github-adds-account-successors-feature\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2635:\"

            Yesterday, GitHub added a new setting to user-owned repositories called “Account Successors.” It allows users to designate repository access to another user to maintain ownership continuity in the event of any kind of personal disruption.

            \n\n\n\n

            “Open source maintainers, you can now invite a trusted user to manage your open source projects in the event that you are unable to do so yourself,” GitHub Senior Product Manager Ben Balter said in an announcement on Twitter. “Help ensure the future of your work (and the work of others) by inviting an account successor today.”

            \n\n\n\n

            The new feature can be found under the Settings » Account » Successor Settings menu in GitHub. Successors will not be given the ability to log into accounts but will have the following permissions:

            \n\n\n\n
            • Archive your public repositories.
            • Transfer your public repositories to their own user owned account.
            • Transfer your public repositories to an organization where they can create repositories.
            \n\n\n\n

            Successors cannot be set on a per-project or per-organization basis yet, but Balter said that is something GitHub would like to build.

            \n\n\n\n

            This new setting complements GitHub’s Deceased User Policy, in which the company will work with the deceased person’s next of kin, a pre-designated successor, or other authorized individual to determine the future of the account.

            \n\n\n\n

            GitHub began testing the Account Successors feature last week, taking suggestions from the greater community. Public feedback from testers has been positive so far. Users hope not to need the feature anytime soon, though some said it is a real worry they have regarding their projects on GitHub. Setting up a successor is now the easy part, where identifying a trusted individual may prove more difficult for some.

            \n\n\n\n

            Account Successors is a timely addition to the platform, as the pandemic continues to sweep the globe, although the feature can be useful for many other types of scenarios. Given the high fevers that can accompany COVID-19 and the rapid decline often associated with the worst outcomes, identifying a successor while still feeling healthy is an important precaution to ensure the continuity of your project.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 12 May 2020 22:51:27 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:20;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:77:\"WPTavern: Highlight, Underline, and Control Font Size with RichText Extension\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99566\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:195:\"https://wptavern.com/highlight-underline-and-control-font-size-with-richtext-extension?utm_source=rss&utm_medium=rss&utm_campaign=highlight-underline-and-control-font-size-with-richtext-extension\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:3560:\"

            Last week, Tetsuaki Hamano contributed his first plugin to the official WordPress plugin repository. RichText Extension grants additional options for inline text in the block editor.

            \n\n\n\n

            RichText is a component in the editor that allows end-users to add and edit text. Typically, users may think of this component when dealing with paragraphs. However, it also applies to headings, lists, quotes, image captions, and any other area where textual content can be added.

            \n\n\n\n

            Many plugins add settings on the block level. This means when you apply a particular style, it applies to the entire block. Inline text refers to the individual characters and words within the block. By default, WordPress allows end-users to control inline text by adding links, creating italic or bold characters, changing the text color, and more. Superscript and subscript inline options have already landed in the Gutenberg plugin, which should ship with WordPress 5.5.

            \n\n\n\n

            RichText Extension extends the editor toolbar to add new options for highlighting, underlining, and changing the font size of inline text. It also adds an option to clear all formatting.

            \n\n\n\n

            Overall, the plugin is a solid outing for a first-time contributor to the plugin directory. With luck, we will get to see more of Hamano’s work in the future.

            \n\n\n\n

            Plugin Features

            \n\n\n\n

            The primary feature of RichText Extension is its highlighter option, which allows users to highlight text. The plugin adds a paintbrush icon to the toolbar. Once clicked, it opens four highlighting options. By default, users can add a red or yellow marker effect or background directly behind a piece of text. This feature can be useful for adding a bit of flair to make specific words or characters to stand out.

            \n\n\n\nUsing the marker highlight in a pullquote.\n\n\n\n

            The plugin also adds a font size option to the toolbar. I am unsure how useful changing the font size for inline text is for the average end-user. Typically, this is best left to the block level. However, there may be some edge cases that others will want to use it for.

            \n\n\n\n

            Along with the core editor’s inline options in the toolbar’s dropdown menu, RichText extension adds Clear Format and Underline options. The former allows users to clear all inline formatting. The latter underlines text.

            \n\n\n\n

            Each of the plugin’s features can be configured via the plugin’s settings screen. Users can change the highlight colors, their thickness, and transparency. The four available font sizes can be adjusted. It also allows users to enable or disable each feature.

            \n\n\n\nRichText Extension’s settings screen.\n\n\n\n

            It would be nice to see the plugin’s highlighting and font-size features use the theme-defined color palette and font sizes, respectively. The plugin could further allow users to define custom colors and sizes outside of those added by the theme.

            \n\n\n\n

            More than anything, I would like to see a fully-featured plugin tackle every conceivable inline text option with the ability to enable or disable each. This would give end-users ultimate flexibility over how they write their content. Perhaps RichText Extension can be that plugin in the future. Otherwise, another developer may step in and do the job.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 12 May 2020 19:51:51 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:21;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:83:\"WPTavern: WordPress Accessibility Team to Host 24-Hour Online Event October 2, 2020\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99528\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:209:\"https://wptavern.com/wordpress-accessibility-team-to-host-24-hour-online-event-october-2-2020?utm_source=rss&utm_medium=rss&utm_campaign=wordpress-accessibility-team-to-host-24-hour-online-event-october-2-2020\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2464:\"\n\n\n\n

            The WordPress Accessibility Team is organizing a new online event called WP Accessibility Day that will take place on October 2, 2020. The event will feature 24 hours of educational sessions that focus on the intersection between WordPress and web accessibility.

            \n\n\n\n

            Inspired by the Polyglots’ Global Translation Day, which greatly expanded the team’s base of contributors and fueled a record number of translations, the Accessibility Team aims to raise awareness about its work. Organizers will be featuring a variety of topics, including theme and plugin accessibility, writing accessible content, accessibility testing, current standards, and more from a diverse group of global speakers.

            \n\n\n\n

            Accessibility consultant and WordPress contributor Joe Dolson proposed the event use a model similar to the ID24 (Inclusive Design 24) conference, with one 30-40 minute talk per hour. This format merges aspects of virtual WordCamps and WordSesh, running a single-track of sessions over the span of 24 hours with live emcees to manage interviews and Q&A segments.

            \n\n\n\n

            Even though many events are going virtual due to the pandemic, accessibility contributors have been evaluating the possibility of hosting an online-only event since mid-2019 and have been planning this one since December. The small size of the team and the travel expenses associated with larger WordCamps made it nearly impossible to scale the in-person collaboration happening at events.

            \n\n\n\n

            WP Accessibility Day has its own website where those who are interested can sign up to be notified about the call for speakers, sponsors, and other news. Organizers and volunteers are meeting in the #accessibility-events channel on WordPress’Slack. They will be discussing the event, along with other accessibility topics, during an online panel on Thursday, May 21st, 2020, for Global Accessibility Awareness Day.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 11 May 2020 20:17:04 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:22;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:66:\"WPTavern: Simple Photoblogging with the Instapress WordPress Theme\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99532\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:177:\"https://wptavern.com/simple-photoblogging-with-the-instapress-wordpress-theme?utm_source=rss&utm_medium=rss&utm_campaign=simple-photoblogging-with-the-instapress-wordpress-theme\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:4059:\"

            It is not often that I come across a free WordPress theme that instantly impresses me. Far too often, I spend half an hour or more just getting to know a theme, checking its options, and figuring out how long it will take to recreate something that looks remotely like the demo. However, every now and then I come across one of those diamonds in the rough that makes me a taker a deeper look.

            \n\n\n\n

            Instapress is one of those themes. It is yet another reason I am in favor of a curated featured themes list. These types of unique themes tend to get lost in the crowd, and without the backing of a major company to market them, they usually go unnoticed by most WordPress users.

            \n\n\n\n

            What drew me to Instapress was its take on presenting posts on the front end. It is a photoblogging theme that is mostly good at showing individual photos but little else. It also has some of the old-school simplicity from the early WordPress theme era.

            \n\n\n\n

            Instapress is the first and only theme that Anton Lukin has submitted to the official WordPress theme directory. He runs the theme on his personal blog, in which he shares photos from the places he travels.

            \n\n\n\n

            Beautiful Simplicity

            \n\n\n\n

            The theme is truly a photoblogging-only theme. It is not ideal for long-form, textual content or many other types of sites. Fair warning: if your plan is to do anything other than post photos, you should look elsewhere.

            \n\n\n\n

            This narrow design is what makes the theme stand out. On the blog page and other archive-type pages, the theme presents the featured image with an interesting JSON-style output of the post metadata such as the date, title, and author.

            \n\n\n\nPosts page display from Instapress.\n\n\n\n

            Instapress has a few customizer options. Along with a custom footer description, end-users can decide whether to show the post author and any custom meta in post summaries on blog and archive pages. Custom meta in this sense means all public custom fields, which may not be desirable for everyone, depending on what metadata is assigned to the post. However, it can be useful for photobloggers who include location data, such as latitude and longitude for their posts.

            \n\n\n\n

            As shown in the following screenshot, Lukin includes the coordinates on his post (latlng):

            \n\n\n\nCustom metadata from Baikal post.\n\n\n\n

            Themes rarely get much simpler than Instapress. It is intentionally lightweight. The stylesheet comes in under 20 kb, which is what any photoblogger should look for in a theme. The theme should not be the bottleneck for page speed on image-heavy websites.

            \n\n\n\n

            Areas to Improve

            \n\n\n\n

            While being a fan of the theme, some small things could drastically improve its appeal to end-users. I would not want the theme to add too many extra options. Its simplicity is part of its charm. However, a couple of home/archive views that offer a wider photo layout or grid would add a nice touch without bloating the theme.

            \n\n\n\n

            Typically, I would deduct massive points for a theme that has no block editor styles, particularly in 2020. It is such a huge user base to leave out. But, the biggest loss for this theme is not taking advantage of the built-in, image-related blocks. They provide theme authors with a ton of design freedom. Throw in a few custom styles and you can do something special for photoblogs. Even just supporting wide and full-width alignment goes a long way in providing users better options for photos.

            \n\n\n\n

            The other missing piece of the puzzle for this theme is that it has no site title output. End-users can shoehorn it into the nav menu or customizable footer description, but it would be nice to see it as part of the theme header, even if disabled by default.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 11 May 2020 19:52:03 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:23;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:132:\"WPTavern: WordCamp Spain 2020 Q&A: Matt Mullenweg Discusses Virtual Events, Decoupled WordPress, and the Future of Page Builders\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99452\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:293:\"https://wptavern.com/wordcamp-spain-2020-qa-matt-mullenweg-discusses-virtual-events-decoupled-wordpress-and-the-future-of-page-builders?utm_source=rss&utm_medium=rss&utm_campaign=wordcamp-spain-2020-qa-matt-mullenweg-discusses-virtual-events-decoupled-wordpress-and-the-future-of-page-builders\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6424:\"

            Matt Mullenweg joined Matías Ventura at WordCamp Spain yesterday for a lively Q&A session. The virtual event drew 5,000 registered users, and attendees came prepared with some thought-provoking questions about the future of WordPress. Here are a few highlights on some recent topics of interest.

            \n\n\n\n

            WordCamps around the globe have been going virtual, embracing the challenge of keeping communities connected through the screen. Mullenweg shared thoughts on how WordCamps have changed during the pandemic and what might be worthwhile to maintain after things go back to normal:

            \n\n\n\n

            WordCamps were always exclusionary. If you couldn’t make it to be in a physical point at a physical time, you couldn’t be there. Tickets were cheap but travel and other costs could be expensive. To our mission of democratizing publishing, if we could radically open up some of the value of WordCamps, not just the talks because the talks you could always watch later online, but some of that person-to-person connection and relationship-building that would happen at WordCamps – if we can recreate that online I feel like that could be something that would be amazing for the WordPress community. I feel like we used our in-person events as a crutch, actually. Because they were so good, and I love them, we overweighted towards them. This time allows us to reflect and also try new things that we might not have been pushed to otherwise. I hope that we don’t stop any of these new things. I hope there are more WordCamp events in every language.

            \n\n\n\n

            Large regional events like WordCamp Europe and WordCamp US will be going virtual in the coming months and it will be interesting to see how they work to reproduce the intimate, in-person connections that are often forged at these events.

            \n\n\n\n

            One of the first questions was regarding Automattic’s recent investment in Frontity. Does Automattic’s interest mean that React might be implemented in the public part of WordPress? Mullenweg highlighted a few of the positive and negative aspects of decoupled WordPress setups but also confirmed that a React frontend is not on the roadmap for core:

            \n\n\n\n

            I’m excited to be able to support Frontity. Automattic tries to support as many of the WordPress ecosystem companies as possible. If there is a company doing something interesting in WordPress, we would love to invest and support it. In terms of a React theme in default WordPress, I think that to me that stays in plugin and theme territory for the foreseeable future. The downside of that approach is that you lose all the capabilities of the decades of WordPress plugins and themes and integrations and everything when you move to that more decoupled React frontend. I don’t know if what you gain is that much better for a normal content website. In fact, so many single page applications in React when they get to version 2 or 3 usually work on server side rendering. We have server side rendering by default, and it’s really fast and really good, especially when you layer in AMP or some other things that can speed it up. It can actually be probably the best possible thing for content driven sites, the best practice, versus application driven sites where something like React might be better. If you take a really optimized PHP-served AMP page, performance-wise versus the same thing going through React, it’s hard for me to imagine the React page being faster. In fact, I think it would be much slower. That’s how I think about the defaults. But for people who are building more advanced applications or have some sort of constraint on their website where they need the React frontend, I think the decoupled use case of WordPress is stronger than ever. I don’t know why anyone would use a proprietary backend, like Contentful or something like that, when you have all the open source security, scalability, and robustness of WordPress available in a decoupled infrastructure as well.

            \n\n\n\n

            Ventura noted that just because WordPress uses these technologies in the backend, doesn’t mean it has to be used on the frontend as well. Based on these comments, it doesn’t seem likely that WordPress will be adopting a React-based default theme anytime in the near future.

            \n\n\n\n

            The fate of page builders in the Gutenberg era is always a popular topic during Q&A sessions and WordCamp Spain was no exception. The general concern is whether Gutenberg’s full site editing capabilities will make these plugins obsolete, but Mullenweg seemed optimistic about WordPress leaving page builders a piece of the market:

            \n\n\n\n

            I’m really excited for the future of page builders. Before every single page builder would have to do a fair amount of work to recreate their version of blocks. There was a lot of wasted effort with many talented and great developers all over the world essentially rebuilding the wheel or recreating the block over and over. Now that we have these rails in the core of this block infrastructure, it’s been widely adopted and implemented with thousands of blocks being created and many more to come, they don’t have to create that core fundamental infrastructure and can instead innovate on top of it, because there are so many cool things you can do in page builders that are out of scope of where we want to take Gutenberg.

            \n\n\n\n

            Mullenweg also said he anticipates that page builders that are not built with Gutenberg in mind will likely be used less and less over time. However, it should be reassuring that there will still be a place in the WordPress ecosystem for products that build on top of the core standard.

            \n\n\n\n

            The Q&A session included many more questions on topics of interest, including when multi-language is coming to core, the future of themes, the present and future of the WP REST API, and what new business options may be coming to the WordPress ecosystem. Check out the recorded session embedded below to find out what Matt and Matías would improve in WordPress if they had a magic wand.

            \n\n\n\n
            \n\n
            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 08 May 2020 22:41:48 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:24;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:51:\"WPTavern: Drag and Drop Nav Menu Items in WordPress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99477\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:147:\"https://wptavern.com/drag-and-drop-nav-menu-items-in-wordpress?utm_source=rss&utm_medium=rss&utm_campaign=drag-and-drop-nav-menu-items-in-wordpress\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2941:\"

            Earlier this week, Sajjad Hossain Sagor released the first version of his Drag & Drop Menu Items plugin in the WordPress plugin repository. The plugin is a one-off, single-use plugin that does exactly what its name describes — it allows end-users to drag menu items from the meta boxes on the nav menu screen to the menu they are currently editing.

            \n\n\n\n

            Sagor is a freelance web developer from Bangladesh. Drag & Drop Menu Items is the latest of his 18 contributions to the free plugin directory.

            \n\n\n\n

            The plugin is simple in nature and does its one job well. To use it, users merely need to open the Appearance > Menus screen in the WordPress admin. Menu items from the meta boxes under the “Add menu items” section can then be dragged into the menu under the “Menu structure” section.

            \n\n\n\nDragging an item into a custom menu.\n\n\n\n

            When dragging a menu item over, a drop-box appears between each of the existing items in the menu. It is worth noting that you cannot drag items into a sub-menu slot directly from the meta boxes. This is on par with the default functionality and could be a limitation of WordPress. However, sub-menu organization works as usual.

            \n\n\n\n

            The Drag & Drop Menu Items plugin is limited to the Menus screen in the WordPress admin. It does not work in the customizer, which sports a different interface and method of adding menu items.

            \n\n\n\n

            The plugin code is minimal and does not appear to have any issues. The additional JavaScript, at less than 4 kb, should not add much weight to the page either.

            \n\n\n\n

            By default, WordPress requires two mouse clicks to add an item to a menu: one click to tick the checkbox and a button click to add the item. However, the default method also allows users to append multiple items at once.

            \n\n\n\n

            On the whole, the plugin is a good option for users who prefer the drag-and-drop method of adding items or those who prefer to have both methods at their disposal. It adds a nice touch that would make sense as an existing part of WordPress.

            \n\n\n\n

            An Uncertain Future

            \n\n\n\nExperimental Navigation screen from the Gutenberg plugin.\n\n\n\n

            Eventually, Drag & Drop Menu Items may no longer function. The Gutenberg plugin team has already built an early experimental version of a new Navigation screen in the admin. The plan is to incorporate this new screen into core WordPress in the future.

            \n\n\n\n

            The new screen will work within the block system and likely use the work that has gone into the existing Navigation block. This will provide consistency in how menus are added across the site.

            \n\n\n\n

            For now, if you would like the ability to drag and drop menu items, this plugin is a solid solution.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 08 May 2020 19:15:45 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:25;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:67:\"WPTavern: Bringing Back Blogs in the Age of Social Media Censorship\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99380\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:179:\"https://wptavern.com/bringing-back-blogs-in-the-age-of-social-media-censorship?utm_source=rss&utm_medium=rss&utm_campaign=bringing-back-blogs-in-the-age-of-social-media-censorship\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:8292:\"

            You’ve probably never heard of Robert B. Strassler. That’s OK, you’re not alone.

            \n\n\n\n

            Early in his career, Strassler worked in oil fields, but he always had an interest in the classics (the formal designation for the studies of ancient Greek and Roman civilizations). Eventually, Strassler’s hobby became an obsession. He went so far as to author his own translation of Thucydides, the Athenian historian of the Peloponnesian War.

            \n\n\n\n

            The problem was nobody wanted to read Strassler’s book. This was in the 1990s. It was more difficult to publish to the web and there was no social media. Strassler approached every Ivy League institution he could find. Nobody was interested in reading a manuscript about Thucydides penned by an oilman with no formal credentials. That was the situation until Strassler contacted Victor Davis Hanson, a classicist professor in Fresno, California. Hanson agreed to look at the manuscript and was astounded by Strassler’s work: a brilliant, highly readable translation of Thucydides including maps, diagrams, and charts. Hanson helped the disconnected oilman get in touch with a literary agent. Strassler’s landmark edition became the standard translation of Thucydides. Still read today, The Landmark Thucydides: A Comprehensive Guide to the Peloponnesian War is as successful as any book on the classics can be—in the age of Twitter.

            \n\n\n\n
            \n\n\n\n

            Those of us who take the idea of democratic publishing seriously rejoice at how the field has opened to include anyone who has something to say and is willing to write it down. That’s why we should be more alarmed when we see social media companies crowd the spaces once occupied by blogs and do-it-yourself content creators. We see a decline in diverse opinions as the web quickly becomes less free and more autocratic.

            \n\n\n\n

            How many Robert B. Strasslers are being stifled today by biased algorithms and arbitrary “community guidelines”?

            \n\n\n\n

            In March, as COVID-19 exploded into a worldwide panic, the web gatekeepers we’ve come to rely on quickly massed around a singular interpretation of events and stifled dissenting voices—even mild ones.

            \n\n\n\n

            YouTube, the second largest search engine in the world, demonetized all videos that mentioned “COVID-19,” “Coronavirus,” or any term related to the pandemic, and herded viewers away from content creators and toward the Center for Disease Control (CDC) — the same CDC that first advised against wearing masks. Even medical practitioners who deviated slightly from the prevailing vision were removed from the platform after gaining millions of views.

            \n\n\n\n

            Experienced journalists who questioned official decrees (surely, the role journalists are expected to perform) were targeted with hit pieces and character assassination by their own peers.

            \n\n\n\n

            As author/professor Cal Newport noted in an op-ed for Wired, much of the dissenting viewpoints and on-the-ground data have become part of the mainstream conversation even after being suppressed by a small group of decision-makers:

            \n\n\n\n

            We don’t necessarily want to trust engineers at one company to make the decisions about what topics the public should and should not be able to read about.

            \n\n\n\n

            How many times have you clicked on a link in a tweet and received a message as shown in the following screenshot?

            \n\n\n\nTwitter unsafe link warning.\n\n\n\n

            Adults should be trusted to determine what kind of content is harmful (if such a thing exists) without the assistance of Twitter employees and their “partners.” And, are these warnings actually meant to protect people or simply to shield Twitter from corporate liability? I think we can guess what the answer is.

            \n\n\n\n

            It’s not only those without official-sounding credentials who are being barred from sharing content. Creators who clearly have experience in their fields of study are also facing arbitrary censorship.

            \n\n\n\n

            The Great Courses Plus, a streaming service that produces college-level video courses taught by actual professors, was threatened with a ban from Google if they did not remove COVID-19-related content from their app. In an email to subscribers, the team wrote:

            \n\n\n\n

            Google informed us they would ban The Great Courses apps if we continued to make [Covid-19] in-app content available. We are working with Google to ensure that they understand our content is factual, expert-led, and thoroughly vetted, so that we can remedy this misunderstanding as soon as possible.

            \n\n\n\n

            The videos in question included content from Dr. Roy Benaroch, Adjunct Assistant Professor of Pediatrics at the Emory University School of Medicine; Dr. David Kung, Professor of Mathematics at St. Mary’s College of Maryland; and Dr. Kevin Ahern, Professor of Biochemistry and Biophysics at Oregon State University. How or why these scholars were found unworthy of Google’s imprimatur is a mystery. As the public does not presume to give Google programming advice, perhaps Google could return the favor by not pretending to be experts on epidemiology, immunology, and virology.

            \n\n\n\n

            The only way to see these offending videos is on the Great Courses website, where Google’s authority is not absolute. It happens to be a WordPress-powered site. For intellectuals and laymen who value free expression, having your own website is becoming the only way to make sure you can keep it.

            \n\n\n\n

            The problem of pitting credentials against experience in a zero-sum conflict is fixable, and WordPress is a big part of the solution.

            \n\n\n\n

            WordPress allows capable scientists, economists, and medical professionals in other fields to write at length about their ideas without fear of being blocked by arbitrary restrictions. Also, the five-minute install (which does take a little more than five minutes for many people) imposes enough of a barrier to entry to discourage cranks.

            \n\n\n\n

            We like to think of the internet as a true egalitarian system, where every voice is given equal consideration, but deep down we know that’s not exactly how it works. Network effects tend to form hubs of concentrated influence around a handful of websites. This isn’t always a bad thing. A recipe blog with poor taste and no pictures deserves fewer readers than a blog with great-tasting recipes and high-resolution images.

            \n\n\n\n

            There is still room enough in the network for certain nodes to grow in size and influence based on the quality of their content. A node with enough backlinks, good organic search rankings, and high-quality content will gain an audience, and be able to keep it, without fear of corporate reprisals or aggressive algorithm updates.

            \n\n\n\n

            If we really care about democratizing publishing, we won’t always like what we read. There will be disagreements, but democracy requires a literate population eager for debate. We can challenge, discuss, and learn.

            \n\n\n\n

            There are a lot of Robert B. Strasslers out there in the network, waiting patiently to be heard.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 08 May 2020 15:41:24 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Chris Maiorana\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:26;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:89:\"WPTavern: WP Engine Launches Genesis Pro Add-On for Customers, More Features in the Works\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99440\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:221:\"https://wptavern.com/wp-engine-launches-genesis-pro-add-on-for-customers-more-features-in-the-works?utm_source=rss&utm_medium=rss&utm_campaign=wp-engine-launches-genesis-pro-add-on-for-customers-more-features-in-the-works\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6549:\"

            Managed web hosting company WP Engine launched the new Genesis Pro add-on for customers of its hosting service today. The add-on brings additional block editor features for users who are using a Genesis-based WordPress theme.

            \n\n\n\n

            Genesis is a parent theme developed by StudioPress. WP Engine acquired the theme development company in 2018. Later that year, the company took the first steps toward adding compatibility with the block editor for Genesis customers, becoming an early adopter of the new editing experience.

            \n\n\n\n

            “Beyond just being ‘compatible,’ Genesis will play a big role in being Gutenberg-First,” Jason Cohen, CTO of WP Engine, said of future plans nearly two years ago. “That means not only supporting the software and ideals of Gutenberg but using them for new features. In doing so, it’s our intention to light the way for the countless agencies and developers who use WordPress to fuel incredible digital experiences that are made even easier with Gutenberg.”

            \n\n\n\n

            Today’s Genesis Pro launch is another step on that journey. WP Engine is currently rolling out the add-on as part of its managed hosting service. The cost is $30/month ($360/year) for an unlimited number of sites.

            \n\n\n\n

            The current plan is to also make the Genesis Pro plugin available via the StudioPress website in the early summer. The company is not formally committing to that timeframe yet, but users not on WP Engine’s hosting service should expect it this year. The price for Genesis Pro will be available for $360/year, which is at the same rate as the hosting add-on.

            \n\n\n\n

            The reason behind the early launch for web hosting clients seems to be twofold based on the announcement post. David Vogelpohl, VP of Web Strategy for WP Engine, said the company could launch the product faster and increment with the launch for its hosting customers. They are also able to make sure the payment system scales, which StudioPress now uses.

            \n\n\n\n

            “Genesis Pro’s capabilities are expressed in a single plugin today, but may be provided in multiple plugins, WP adjacent services, or other means in the future based on architectural decisions of any particular feature,” said Vogelpohl.

            \n\n\n\n

            Watch a quick video on Genesis Pro:

            \n\n\n\n
            \n
            \n
            \n\n\n\n

            Genesis Pro Features

            \n\n\n\nExample layout from the Genesis Pro add-on.\n\n\n\n

            The add-on includes a robust set of options that are primarily aimed at helping users build their webpages with custom blocks and designs. The following features are the foundation of the add-on:

            \n\n\n\n
            • Block Library: Includes 17 custom blocks, such as a testimonial and pricing block.
            • Page Layouts: Offers 22 full layouts for product, portfolio, team, and other pages.
            • Content Sections: Adds 38 customizable content sections.
            • Permissions System: Allows admins to set editing permissions on a per-block basis.
            • Customization: Users can create and share custom sections and layouts with content creators.
            \n\n\n\n

            Most of the options seem to be under a pop-up modal on the post-editing screen that should allow users to insert blocks directly into their post or page content. More blocks, sections, layouts, and other content-creation tools are currently in the works.

            \n\n\n\nLayout selector from the Genesis Pro add-on.\n\n\n\n

            The add-on features are mostly standard fare in comparison to many of the block libraries and suites available throughout the WordPress ecosystem. Of course, these will have the StudioPress spin on them and likely be of high quality based if past work is any indication. With the launch out of the way and the foundation in place, it should be much easier for the team to churn out more customization options for end-users.

            \n\n\n\n

            The most unique feature is probably around the block permissions system, which few companies have truly tackled. For site administrators who work with multiple creators, setting up editing permissions for individual blocks can be useful. If the user experience for this system works well, it will be a huge selling point for some site owners.

            \n\n\n\nBlock permissions settings for Genesis Pro.\n\n\n\n

            Genesis X

            \n\n\n\n

            Vogelpohl teased another project the team has been working on titled “Genesis X,” which is separate from the Genesis Pro project. It is an experimental plugin version of Genesis that will be available to StudioPress customers at no additional charge. The work thus far has centered on what Genesis will look like in a world where full-site editing is available through WordPress itself.

            \n\n\n\n

            “The current version of Genesis X focuses on helping site creators easily manage global styles across their site, customize and manage blocks, as well as other capabilities to help users win with full-site editing in WordPress core,” said Vogelpohl. “Genesis X is being built core-adjacent and is not a replacement for the block editor. It is designed to work with the block editor.”

            \n\n\n\n

            Vogelpohl said the first objective of the project is to provide analogs for features in Genesis that would not work in a parent theme structure within the full-site editing context. “After achieving that parity in ways that make sense, we will be focused on the advanced block capabilities as well as other features currently on our roadmap,” he said.

            \n\n\n\n

            The company is putting a lot of weight and resources behind the transition from pre-block WordPress and the upcoming features that WordPress will offer via the block system. Right now, they have a team of 15 employees working on solutions with Genesis.

            \n\n\n\n

            “The overarching theme is that Genesis X is being architected not to just help the Genesis community adapt to full-site editing in core, but for any user of WordPress to adopt full-site editing in a way that sets them up for the best chance of success,” said Vogelpohl.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 07 May 2020 20:52:20 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:27;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:74:\"WPTavern: GitHub Introduces Codespaces IDE, Discussions, and Code Scanning\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99374\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:189:\"https://wptavern.com/github-introduces-codespaces-ide-discussions-and-code-scanning?utm_source=rss&utm_medium=rss&utm_campaign=github-introduces-codespaces-ide-discussions-and-code-scanning\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:4529:\"

            GitHub Satellite, the company’s annual product and community event, went virtual this year for the first time but marched forward with the usual major product announcements. GitHub is ramping up its offerings with four new products: an IDE, a discussion platform, code scanning, and private instances.

            \n\n\n\n

            Codespaces is the platform’s new built-in IDE that lets users code in the browser with minimal setup. The product is based on the VS Code editor and includes terminal access, support for code completion, and extensions:

            \n\n\n\n

            Codespaces can be configured to load your code and dependencies, developer tools, extensions, and dotfiles. Switching between environments is simple—you can navigate away at any time, and when you switch back, your codespace is automatically reopened.

            \n\n\n\n

            The IDE was created to facilitate contribution but it also enables better development on mobile devices. GitHub design lead Joel Califa shared a demo of how he uses Codespaces on his iPad:

            \n\n\n\n
            \n

            People have been asking about using Codespaces on the iPad. Here\'s what it looks like: pic.twitter.com/5UQHtzMwZh

            — Joel Califa (@notdetails) May 6, 2020
            \n
            \n\n\n\n

            GitHub plans to implement a pay-as-you-go pricing model for Codespaces, but it will be free during the limited beta. This product should complement the recent launch of GitHub’s mobile apps for iOS and Android in March, which allows users to manage projects, tasks, feedback, and pull requests.

            \n\n\n\n

            Discussions is a new feature that stands to have a more meaningful impact on open source communities. GitHub issues and pull requests have long been the home of most conversations, but oftentimes this type of collaboration would be better served with features more tailored to a knowledge base. Discussions offer a threaded format where questions can be marked as answered. Participation in discussions counts towards users’ contribution graphs. GitHub plans to put the feature into beta for public repositories soon.

            \n\n\n\n\n\n\n\n

            GitHub also announced code scanning, powered by CodeQL, a semantic analysis engine trained to find vulnerabilities. When code scanning is enabled, every `git push` is inspected by CodeQL for potential vulnerabilities and the results are displayed in the pull request. Code scanning is free for open source software.

            \n\n\n\n

            Secret scanning, which has been enabled on public repositories since 2018, is now available for private repositories. It scans code for known secret formats and notifies developers upon finding something. At the beginning. of 2019, GitHub announced that it was giving free users access to unlimited private repositories. Adding secret scanning to private repositories is the next natural step, as these have likely grown in number after being added to the free tier.

            \n\n\n\n

            While many of GitHub’s new features are aimed at free users and open source communities, this week’s announcements also include a new enterprise product called Private Instances:

            \n\n\n\n

            Today we introduced our plans for GitHub Private Instances, a new, fully-managed option for our enterprise customers. Private Instances provides enhanced security, compliance, and policy features including bring-your-own-key encryption, backup archiving, and compliance with regional data sovereignty requirements. 

            \n\n\n\n

            After Microsoft acquired GitHub for $7.5 billion in 2018, the company has aggressively worked to make its product more compelling in the highly competitive space of code sharing platforms, starting with the free tier. Pricing has not yet been finalized for any of the revenue-generating products announced this week, as GitHub may be testing the waters to gauge the community’s reaction before launch.

            \n\n\n\n

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 07 May 2020 14:42:59 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:28;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:67:\"WPTavern: Apply to Speak at the JavaScript for WordPress Conference\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99026\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:179:\"https://wptavern.com/apply-to-speak-at-the-javascript-for-wordpress-conference?utm_source=rss&utm_medium=rss&utm_campaign=apply-to-speak-at-the-javascript-for-wordpress-conference\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2066:\"

            The third annual JavaScript for WordPress Conference is gearing up for three days of online talks and workshops on July 8-10, 2020. The event is free to attend and organizer Zac Gordon is working to put together a diverse speaker lineup.

            \n\n\n\n

            Day 1 will be devoted to workshops that help beginners get up and running with JavaScript and React. Day 2 will focus on building Gutenberg blocks and block-based themes. Day 3 will include topics and projects that use WordPress as a Headless CMS.

            \n\n\n\n

            “Last year we did 4 tracks all at once.” Gordon said. “That was a lot. So this year we’re doing two days, one track each day. We decided on Blocks and Headless as our two tracks, because that seems to be where most of the JavaScript development is happening at the moment in the WordPress space.”

            \n\n\n\n

            Previous editions of the conference have pulled in approximately 1,000 viewers, similar to the size of a large WordCamp. Gordon said the event is open for all JavaScript-related topics related to WordPress beyond Gutenberg and headless setups and they are trying to encourage new speakers.

            \n\n\n\n

            “Each year we’re trying to do more to have the conference reflect a range of speakers, and this year we’re hoping that a few of the brilliant and industrious younger folks coding or building with WordPress might speak,” he said.

            \n\n\n\n

            Registration is free on the event website and applications for speakers will be open until June 1.

            \n\n\n\n

            “I’m not sure how many speakers we will do exactly, but we will have a few folks leading workshops day one and then maybe 5-8 speakers the two other days,” Gordon said. “It will be fewer speakers than last year, but hopefully still a lot of quality focused talks. The applications we’ve seen come in so far are exciting.”

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 06 May 2020 21:43:21 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:29;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:88:\"WPTavern: ACF Blocks Provides Assortment of Blocks Built from Advanced Custom Fields Pro\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99376\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:221:\"https://wptavern.com/acf-blocks-provides-assortment-of-blocks-built-from-advanced-custom-fields-pro?utm_source=rss&utm_medium=rss&utm_campaign=acf-blocks-provides-assortment-of-blocks-built-from-advanced-custom-fields-pro\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:8487:\"

            Over the weekend, Munir Kamal released version 2.0 of his ACF Blocks plugin, a project that creates a suite of blocks for the editor. The plugin offers 18 custom blocks in its free version and 15 more in the pro upgrade. It is built on top of Advanced Custom Fields Pro (ACF Pro).

            \n\n\n\n

            The latest update of the plugin added support for typography, including options for using various Google Fonts for in-block text. Kamal also included base styling options for design features like margin and padding for every block in the plugin.

            \n\n\n\n

            With ACF Pro as a hard dependency, it limits the audience of ACF Blocks. In large part, this plugin will be useful for agencies and freelancers who need to quickly build features for clients within their budget. For that purpose, the plugin does a solid job.

            \n\n\n\n

            The tight coupling with ACF Pro hurts the user experience for the plugin. However, the ideas behind ACF Blocks and its custom options make up for the shortcomings of relying on its dependent parent plugin. Decoupling the two is unlikely, but it would make for a smoother experience and open the plugin to a wider audience.

            \n\n\n\n

            Kamal took inspiration for the plugin from ACF and its pro version. He described the process of building blocks with the framework “super easy,” even for an intermediate-level developer. “It has been such an amazing WordPress framework for years to create custom fields,” he said. “And when [Elliot Condon] announced the block creation feature in ACF, that quickly triggered me to build this collection of ready-to-use ACF Blocks.”

            \n\n\n\n

            The biggest technical limitation is that Kamal cannot build nested blocks, which is a current limitation of ACF. “I have already discussed it with [Condon], and he is already working on bringing that functionality hopefully soon,” he said. “Once that comes to ACF, we may create more amazing and powerful Gutenberg Blocks.”

            \n\n\n\n

            Watch a short walkthrough of how the plugin works:

            \n\n\n\n
            \n\n
            \n\n\n\n

            Useful Assortment of Blocks

            \n\n\n\n

            While primarily testing the free version of ACF Blocks, I found that it has several useful blocks that could immediately address common needs for end-users. With 18 free blocks available, users have plenty to work with before deciding whether they want to move along the upgrade path to the pro version.

            \n\n\n\n

            One of the best blocks in the collection is the Photo Collage block. It is ACF Blocks’ answer to the core Gallery block. The grid options for this block alone make this plugin worth checking out. The block offers between 2 and 15 grid layouts, depending on the grid option the user selects.

            \n\n\n\nSetting the grid for the Photo Collage block.\n\n\n\n

            My second favorite of the assortment is the Testimonial block. Coupled with the typography options, which are available for all blocks, you can have a lot of fun designing a testimonial section.

            \n\n\n\nTinkering with Google Fonts in the Testimonial block.\n\n\n\n

            This is a small sampling of what the plugin can do. The Price List block can help restaurant sites set up their menu. The Pricing Box block, particularly when nested into the core Columns block, makes it easy to set up a pricing section with multiple product options. And, the Team block makes it simple to create profile sections on a company’s team/about page.

            \n\n\n\n

            The following blocks are available in the free version (with several more in the pro version):

            \n\n\n\n
            1. Scrollable Image Block
            2. Tab Block
            3. Toggle Block
            4. Accordion Block
            5. Image Slider Block
            6. Social Sharing Block
            7. Photo Collage Block
            8. Posts Block
            9. Testimonial Block
            10. Team Block
            11. Multi Buttons Block
            12. Pricing Box Block
            13. Price List Block
            14. Start Rating Block
            15. Progress Bar Block
            16. Counter Number Block
            17. Click to tweet Block
            18. Business Hours Block
            \n\n\n\n

            Kamal’s favorite blocks from the overall suite are Image Hotspot, which allows users to set an image background with “pointers” to pop up content; Before After Image, which lets users compare two images using a sliding bar; and Photo Collage, the plugin’s grid-based gallery block. The first two are available only in the pro version of the plugin. The plugin creator said he thinks all the blocks are useful but these were the most fun to build.

            \n\n\n\n

            Room for Improvement

            \n\n\n\n

            ACF Blocks is a nice concept. It gets a lot of things right. However, there are minor issues that dampen the experience of working with its blocks. These issues are not insurmountable, and I expect Kamal will address them in upcoming versions based on familiarity with his past work and drive toward building great products for users.

            \n\n\n\n

            The most immediate issue and likely the simplest to fix is the plugin’s styles for left and right margins on every block. The plugin resets these margins to 0 by default. Depending on the active theme on a site, this could shift the blocks to the edge of the screen instead of the content area on the front end. Some themes use left/right margins to align content. This is not an issue with only ACF Blocks. It is prevalent among plugins with front-end output.

            \n\n\n\n

            One quick solution for the margin issue is to wrap any of the plugin’s blocks within the core Group block. This will put margins back under the theme’s control.

            \n\n\n\n

            Editing block content happens in the block options panel instead of directly in the block. I am unsure if this is a limitation of using the ACF Pro framework or a design decision on Kamal’s part. It feels odd to jump between editing content in the content area to editing content in the sidebar.

            \n\n\n\n

            One example of my confusion with block content was with the Photo Collage block. I clicked on the block, hoping to have the media library appear for uploading. Nothing happened. I clicked again because, well, maybe I did not get a good click in that first time. Nothing happened. I eventually found the image upload button under the block’s option panel on the right.

            \n\n\n\n

            Setting block options can feel a little sluggish at times with the block output in the editor not reflecting changes immediately. This is primarily because ACF Blocks relies on the server-side rendering capabilities of ACF Pro. It is unlikely this can be addressed in the blocks plugin. Some users may find the delayed rendering to be tedious when editing multiple options.

            \n\n\n\n

            Final Thoughts

            \n\n\n\n

            Kamal has put together a useful set of blocks that will help many end-users build sections of content they cannot create out of the box. Between the free and pro versions, there is a total of 33 blocks. The creator is committed to adding more blocks over time based on user feedback. In the immediate future, he plans to keep hacking away at bug fixes and improving the code.

            \n\n\n\n

            I still feel like how ACF Pro works is a hindrance to how good this plugin could be if built from scratch. With that said, the framework helped make Kamal’s plugin a reality. ACF Blocks is a showcase in what is possible via ACF Pro, which should inspire other developers who are looking for solutions built on top of one of the most widely-used frameworks in the WordPress ecosystem.

            \n\n\n\n

            Kamal understands that some ACF Pro users may try their hands at creating similar blocks but feels like his team’s knowledge and dedication to offering support are the most important parts of the equation. “ACF Blocks saves time and effort for creating blocks yourself for the most common web design elements,” he said.

            \n\n\n\n

            Note: this plugin review and feedback were requested by the plugin author. Read our post about honest feedback based on genuine experiences for more information on how reviews are handled.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 06 May 2020 20:36:46 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:30;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:51:\"WPTavern: Jetpack 8.5 Adds New Podcast Player Block\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99327\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:145:\"https://wptavern.com/jetack-8-5-adds-new-podcast-player-block?utm_source=rss&utm_medium=rss&utm_campaign=jetack-8-5-adds-new-podcast-player-block\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:3066:\"

            Jetpack 8.5 was released today with a new podcast player block for sharing audio content. Configuring the block is as simple as entering the podcast RSS feed URL. This will automatically bring in the cover art and recent episodes. Block options allow for further customization of the display, including the number of episodes, colors, and the ability to show/hide cover art and episode descriptions.

            \n\n\n\n\n\n\n\n

            Jetpack’s new podcast player has arrived just in time, as podcasting has gotten a little boost in recent months due to the large numbers of people under stay-at-home orders. iHeartRadio, an American audio company with more than 350 podcasts, reports that listenership for its podcasting network is up 6% month-over-month, with California and New York jumping 13% and 8% respectively. iHeartRadio’s insights also showed that certain genres are more popular than others:

            \n\n\n\n

            During a time of economic uncertainty, Americans are listening to more business and finance podcasts – for which downloads and streams are up 78 percent week-over-week among the iHeartRadio Original podcasts. Listeners are also turning to music, entertainment and comedy during this time, where iHeartPodcasts have shown an increase in listening as well.

            \n\n\n\n

            Selling ads and marketing a new podcast may be more of a struggle during this economic downturn, but those with extra time on their hands may have an easier time producing and publishing episodes. Jetpack’s new block makes it easy to share your own episodes or podcasts you enjoy from other websites.

            \n\n\n\n

            The 8.5 release also includes significant improvements to the new Search feature, which is powered by Elasticsearch, to provide better indexing and a simpler onboarding experience.

            \n\n\n\n

            Automattic developer Brandon Kraft published a post today that details recent changes to the Publicize feature. In the past, Publicize would attach an image from the post when sending out its automatic tweet to Twitter. This has now been changed for Jetpack and WordPress.com sites so that Publicize no longer attaches a picture but defaults to allowing Twitter to display its Twitter card instead. Developers can use a filter to return the plugin to its previous behavior, if necessary.

            \n\n\n\n

            Jetpack 8.5 also makes more widgets and embed tools AMP-compatible, expands options for the Revue block, and fixes layout issues with several other blocks. Check out the changelog on WordPress.org for a full list of the enhancements and bug fixes.

            \n\n\n\n

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 05 May 2020 23:09:36 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:31;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:52:\"WPTavern: Need to Smile Today? Stay WordPress Strong\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99333\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:147:\"https://wptavern.com/need-to-smile-today-stay-wordpress-strong?utm_source=rss&utm_medium=rss&utm_campaign=need-to-smile-today-stay-wordpress-strong\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:5173:\"
            \n\n
            Lyrics: Zack Katz, Jonathan Mann | Music: Jonathan Mann
            Video licensed under Creative Commons – Attribution\n\n\n\n

            For the first time, at least 19 people from the WordPress community can literally call themselves WordPress rock stars without it sounding like an outdated marketing gimmick.

            \n\n\n\n

            GravityView dropped a community music video and website named WordPress Strong earlier today. It is fun. It is inspirational. It will leave a smile on your face. The video features a wide range of faces, voices, and musical talent from around the planet.

            \n\n\n\n

            Much of the world is looking for small ways to cope with the ongoing COVID-19 pandemic. Each day is about finding the things we should be thankful for while waiting for life to feel like normal. The WordPress community has been a beacon of hope for many. It has continued providing purpose to people despite their daily lives being upended. This project is one more way to show the strength of our community.

            \n\n\n\n

            “People were scrambling to adjust to the new reality of living in a pandemic, and there was a rush of uncertainty,” said Zack Katz, the creator of GravityView, on starting the project. “In the middle of all that uncertainty, I felt lucky to be part of the WordPress community: doing what we do, working on an open and thriving platform, with a culture of people who are kind to each other and support each other.”

            \n\n\n\n

            Many GravityView customers began using the plugin to enable COVID-19 responses, such as sites like Support Redditch, which coordinates relief efforts. “I sensed a movement of coming together to help each other, and I wanted to get the word out: if you need help, ask the community,” said Katz. “We’re here for you. We’ll get through this together.”

            \n\n\n\n

            A total of 19 volunteers contributed to the music video, including WordPress co-founder Matt Mullenweg. However, the true star of the group was Tracy Apps, the owner of tracy apps design, who laid down the beat on the drums.

            \n\n\n\n

            “It involved asking a lot of people!” said Katz of finding willing subjects. “I get why people are reluctant. I even waited until the last minute to record my video! Something special happens when people are invited to go beyond their comfort zone, especially when it comes to creative endeavors. It was moving to have the emails come in with their videos. People were willing to share a different part of themselves.”

            \n\n\n\n

            The #WordPressStrong hashtag is open for anyone to contribute to on Twitter. The project is calling for volunteers to join in on the fun. If you can sing, play an instrument, or dance — or if you can’t — you can be a part of this movement for our community to become stronger. If nothing else, it will give you something to do to pass the time. Tag yourself doing something and share it. I am certain it will brighten at least one person’s day.

            \n\n\n\n

            The WordPress Strong Project

            \n\n\n\n

            Katz began the project in March. He shared some initial lyric ideas with Jonathan Mann who then wrote and recorded WordPress Strong. The GravityView team reached out to members of the WordPress community and asked them to lend their voices.

            \n\n\n\n

            “I deeply respect [Mann] as a musician and how he exposes himself through his music,” said Katz. “His album I Used to Love My Body was my soundtrack for last year.”

            \n\n\n\n

            Mann is the voice of the GravityView brand and has previously created a song for the product. Katz and Mann also worked on the WordPress Wiggle song in 2017.

            \n\n\n\n

            “When creating WordPress Strong, I shared a poem with [Mann] and expressed the tone that I wanted to convey,” said Katz. “The email had the subject line ‘WordPress Hope Song.’ He wrote and recorded WordPress Strong, and I think you agree, it’s a great WordPress Hope Song.”

            \n\n\n\n

            The plan for the WordPress Strong website goes beyond releasing a song. Katz wants to expand the site to be a place where people from the community can ask and receive help during the pandemic. The team is currently working on a part of the site where community members can request assistance or offer help anonymously.

            \n\n\n\n

            “I was hoping artists of all stripes would be interested in sharing their work on the WordPress Strong website,” said Katz. “Sharing creativity together empowers us to be vulnerable in our despair as well as our hope. I would like to help foster that.”

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 05 May 2020 20:36:58 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:32;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:56:\"Mark Jaquith: WordPress/Jetpack Driver for Laravel Valet\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:40:\"http://markjaquith.wordpress.com/?p=7213\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:88:\"https://markjaquith.wordpress.com/2020/05/05/wordpress-jetpack-driver-for-laravel-valet/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:1082:\"

            Recently I’ve found myself using Laravel Valet for local PHP development on my Mac. I love how fast and low-maintenance it is.

            \n\n\n\n

            One thing that is a little tricky about Valet is that you can’t really write custom Nginx configs. That means that I couldn’t use my favorite technique of routing missing images to the production site, via Jetpack’s Site Accelerator (formerly “Photon”) CDN.

            \n\n\n\n

            Normally, when doing local development on a WordPress site, you need three things: the codebase, a copy of the database, and the wp-content/uploads directory. But if you just redirect missing image files to your production site, you don’t need to laboriously copy all those files and clutter up your local machine.

            \n\n\n\n

            I found myself really missing that technique today, so I wrote a driver for Laravel Valet that handles it!

            \n\n\n\n

            You can get it here: WordPress Jetpack Valet Driver.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 05 May 2020 19:11:43 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:12:\"Mark Jaquith\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:33;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:75:\"WPTavern: Find My Blocks Plugin Shows All Blocks in Use on a WordPress Site\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=98953\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:195:\"https://wptavern.com/find-my-blocks-plugin-shows-all-blocks-in-use-on-a-wordpress-site?utm_source=rss&utm_medium=rss&utm_campaign=find-my-blocks-plugin-shows-all-blocks-in-use-on-a-wordpress-site\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:3144:\"

            How do you know what blocks are in use on a WordPress site? I recently saw a tweet asking this question in regards to knowing whether it is safe to turn off a plugin. This seems like it could become a common question, especially for those who have hundreds or thousands of blog posts as well as those using WordPress as a CMS.

            \n\n\n\n
            \n

            How hard would it be to create a plugin that let\'s me know how many and which blocks I\'m using site wide? Sometimes I wonder if I can deactivate a block plugin but I don\'t know if I\'m using a block it provides.

            — Nick Hamze (@NickHamze) April 23, 2020
            \n
            \n\n\n\n

            When looking at content in the editor, it isn’t immediately evident which blocks are in use. You can click on the block navigation at the top of the editor, but that will only show you the blocks in use on that particular page. If you have a lot of plugins installed and many pages of content to wade through, figuring out if it’s safe to remove a plugin can be a time-consuming process.

            \n\n\n\n

            Fortunately, there is already a plugin that will give you a quick overview of where blocks are being used on your site. Find My Blocks is the one that was suggested to Nick Hamze in response to the question in his tweet. I had not heard of it before, so I took it for a test drive today.

            \n\n\n\n

            Find My Blocks is basically a utility plugin that lists the blocks being used on your WordPress site, along with the posts/pages where they are in use. It includes core blocks and blocks from third-party plugins. The plugin’s settings also give the option to sort the block menu display alphabetically or by most/least popular.

            \n\n\n\n
            \n\n\n\n

            Frontend developer Eddy Sims created Find My Blocks to solve one of his own problems and released it on WordPress.org in January.

            \n\n\n\n

            “I was working on a site that required a few custom Gutenberg blocks,” Sims said. “After a week, updating became a hassle. I didn’t know where the blocks were used. Find My Blocks is a plugin I created to hopefully help someone else with this issue.” So far it has received several five-star reviews in the plugin directory.

            \n\n\n\n

            “We’ve been using this plugin to help us figure out where we’ve used blocks on pages so we can deprecate them and replace them with shiny new blocks!” WordPress developer Tammy Lee said. “This plugin makes tracking down blocks really easy! I don’t want to think about how much time it would have taken us, otherwise.”

            \n\n\n\n

            Find My Blocks is a plugin you may want to add to your favorites on WordPress.org for the next time you inherit a site that you didn’t build, or for cleaning out your own installed plugins.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 04 May 2020 22:54:44 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:34;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:67:\"WPTavern: The Future of WordPress: The Block Editor Is Here to Stay\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99271\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:177:\"https://wptavern.com/the-future-of-wordpress-the-block-editor-is-here-to-stay?utm_source=rss&utm_medium=rss&utm_campaign=the-future-of-wordpress-the-block-editor-is-here-to-stay\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6577:\"

            It is inevitable that when we publish a story on the Tavern that is remotely related to the block editor or the Gutenberg project, we receive negative comments. Despite sprinting along in its second year as part of core WordPress, there are still those who liken posts on the editor to Soviet-style mind manipulation and propaganda for certain unnamed companies.

            \n\n\n\n

            It is not all negative. Far more comments are from people who are ecstatic about the current editor and the upcoming features that will expand the block system to other areas of WordPress.

            \n\n\n\n

            However, I felt the need to address a recent request that we stop covering the block editor. While I cannot speak for our entire staff, there are two simple truths about why I write about blocks.

            \n\n\n\n

            Truth #1: Blocks are Here to Stay

            \n\n\n\n

            The block system is not going anywhere. WordPress has moved beyond the point where we should consider the block editor as a separate entity. It is an integral part of WordPress and will eventually touch more and more areas outside of the editing screen.

            \n\n\n\n

            Frankly, it would be poor journalism to not cover stories related to blocks.

            \n\n\n\n

            Some of the most exciting things happening in the WordPress ecosystem is around what developers are doing with blocks. Whether it is a fun T-rex game, a block-ready theme, or a team of block developers being hired by a major company, there is always something interesting happening in the world of blocks.

            \n\n\n\n

            Every day, more users are embracing the block editor. Even the percentage of holdouts still running WordPress 4.9, which was the last version without the block editor, is decreasing. Currently, only 12.8% of WordPress installs are on 4.9. Nearly 73% are running WordPress 5.0 or newer. Some of those users are running plugins like Classic Editor, which has maintained a steady growth rate in the neighborhood of 0.5% – 1.0% in recent months. Currently, the plugin has over 5 millions installs, which is a drop in the ocean in comparison to total WordPress sites.

            \n\n\n\n

            At the moment, WordPress.com and self-hosted Jetpack users are creating content via blocks on 44.5 million WordPress sites. Yesterday, those users wrote 302,000 posts in the block editor.

            \n\n\n\n

            Blocks are the future of the platform. What we need to do as a community is avoid putting our heads in the sand or railing against the powers-that-be. Instead, we should ask ourselves what we could do to continue improving the system. How can we move forward? How can we present our ideas, even dislikes, in a constructive manner? How can we create better software?

            \n\n\n\n

            Criticism of the editor is fair. Make it constructive so we can dissect and address that criticism. That is an essential part of building great software.

            \n\n\n\n

            Truth #2: Love of Blocks

            \n\n\n\n

            Believe it or not, I actually love blocks. While I may criticize some decisions about the editor, summoning an internal facepalm emoji at times, this is the most excited I have been about WordPress in years. But, it is not about me. I have enough familiarity with dozens of editors that I can live with even the most mediocre of experiences. And, if I am not satisfied, I can build my own.

            \n\n\n\n

            What it is about is seeing the face of an inexperienced WordPress user light up for the first time because they get it.

            \n\n\n\n

            For years, I helped an older family member run an outdoors site. I had no interest in hunting, fishing, or most other topics covered on the blog. However, he was passionate about what he was doing. I wanted to help fuel that passion in any way I could. The problem? He simply never learned how WordPress worked. He never had that lightbulb moment. His face never glowed when he finally figured out how to lay out his content in the editor.

            \n\n\n\n

            He had big ideas and no way to accomplish them.

            \n\n\n\n

            At the time, most page builders were little more than shortcode soup, which I knew would eventually mean I would be the one to clean up the mess. There were few options other than the classic editor. My older cousin stuck it out for longer than most. After a few years, he finally let the site go.

            \n\n\n\n

            Even some of what I would consider the most basic of things were too frustrating for him. It was also frustrating for me because I could not understand why he could never learn what I was teaching.

            \n\n\n\n

            However, the block editor changed things. He was thinking of starting a new site but was asking about non-WordPress platforms. I spun up a demo install and a basic block-ready theme for him not long ago. Suddenly, this guy who routinely broke links and accidentally made all of his blog post content bold — twice — was piecing together media-filled content with few issues. That initial passion that he had all those years ago seemed to come back. Maybe, just maybe, WordPress might now be the CMS for him.

            \n\n\n\n

            I am fully aware that this is not everyone’s experience. However, what I have found working with new and less-than-tech-savvy users is that the block editor is a stepping stone toward them being able to create the sites they want more easily. Right now, those users have far more control over their content than ever before. In the future, they will have that control over their entire site.

            \n\n\n\n

            When I share a story about blocks, it is because I am excited about them. More so, I want to share that excitement with others who are on this journey. Whether they want something on the wacky and weird side of things or want to build custom patterns for reuse in their posts, I want them to find those tools.

            \n\n\n\n

            If I am a bit optimistic about the future at times, I will not apologize for that. I look forward to the next block-related story that we have the opportunity to cover here at the Tavern.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 04 May 2020 20:52:38 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:35;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:54:\"WordPress.org blog: The Month in WordPress: April 2020\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8571\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:69:\"https://wordpress.org/news/2020/05/the-month-in-wordpress-april-2020/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:8157:\"

            April continued to be a challenging time for the WordPress community, with many under stay-at-home recommendations. However, it was also an exciting month in which we created new ways to connect with and inspire each other! This month, amazing contributors moved more WordCamps online and shipped new releases for WordPress and Gutenberg. For the latest, read on.ย 

            \n\n\n\n
            \n\n\n\n

            WordPress 5.4.1 released

            \n\n\n\n

            On April 24th,  WordPress 5.4.1 Release Candidate 1 (RC1) was released for testing, quickly followed by the official release of WordPress 5.4.1 on April 29th. This security release features 17 bug fixes and seven security fixes, so we recommend updating your sites immediately. To download WordPress 5.4.1, visit your Dashboard, click on Updates, then Update Now, or download the latest version directly from WordPress.org. For more information, visit this post, review the full list of changes on Trac, or check out the version 5.4.1 HelpHub documentation page.

            \n\n\n\n

            Want to get involved in building WordPress Core? Follow the Core team blog, and join the #core channel in the Making WordPress Slack group.

            \n\n\n\n

            Gutenberg 7.9 and 8.0 released

            \n\n\n\n

            It was another exciting month for Gutenberg, with the release of 7.9 and 8.0! Version 7.9 brought new block design tools, three new patterns, and improved block markup. Gutenberg 8.0 continued to refine the new block patterns feature, with additional options for inline formatting, and extending the functionality of the Code Editor. In addition to these new features, both releases included new enhancements and APIs, along with a number of bug fixes, performance improvements, some experiments, and more! You can read all the details about the latest Gutenberg releases in the announcement posts for 7.9 and 8.0

            \n\n\n\n

            Want to get involved in building Gutenberg? Follow the Core team blog, contribute to Gutenberg on GitHub, and join the #core-editor channel in the Making WordPress Slack group.

            \n\n\n\n

            BuddyPress 6.0.0

            \n\n\n\n

            BuddyPress 6.0.0-beta2 was released for testing in mid-April, leading to the BuddyPress 6.0.0 Release Candidate, announced on April 29. This is an important step before  the final release of BuddyPress 6.0.0, which is slated for Thursday, May 14. Changes and new features in this release include moving the profile photo and user cover image under the BP Members component, and a new BP Rest API. Additionally, this release will introduce the first round of BuddyPress Blocks! Last, but not least, BuddyPress 6.0.0 will require at least PHP 5.6 and WordPress 4.8. 

            \n\n\n\n

            Want to get involved? Test the 6.0.0-RC here! You can also help by translating BuddyPress into another language, or let the team know of any issues you find, either in the support forums and/or in their development tracker

            \n\n\n\n

            WordCamp US goes online, apply to speak!

            \n\n\n\n

            WordCamp US will take place online due to the COVID-19 pandemic. The event still runs from October 27-29, 2020, and will be free to anyone who wishes to attend. The team plans to offer  what WCUS has historically brought to the community in person: sessions and workshops, Contributor Day, a hallway track, and of course, State of the Word. 

            \n\n\n\n

            Interested in speaking at WCUS? The Call for Speakers is still open! You can apply to speak on the speaker application site until May 31, 2020 at 11:59 pm CDT (UTC-5). 

            \n\n\n\n

            Additionally, the Call for Cities is also open. If your community is interested in hosting WordCamp US in 2021 & 2022, please fill out this application

            \n\n\n\n

            For the latest information about WordCamp US, sign up for updates on the website, or follow Facebook, Twitter, or Instagram

            \n\n\n\n

            WordCamp Europe 2020 goes virtual 

            \n\n\n\n

            Last month, WordCamp Europe decided to postpone its Porto event to 2021. This April, the WCEU organizing team announced that the 2020 WordCamp will be online! WordCamp Europe 2020 Online will take place from June 4-6, 2020, and tickets will be free. There will be a virtual Contributor Day on June 4, and then two half days of live-streamed talks and workshops. To participate, get your free ticket here

            \n\n\n\n

            To get the latest news for WordCamp Europe 2020 Online, follow on Facebook, Twitter, LinkedIn, or on Instagram

            \n\n\n\n
            \n\n\n\n

            Further Reading

            \n\n\n\n\n\n\n\n

            Have a story that we should include in the next โ€œMonth in WordPressโ€ post? Please submit it here.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 04 May 2020 09:31:22 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:10:\"Angela Jin\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:36;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:48:\"BuddyPress: BuddyPress 6.0.0 Release Candidate 2\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:32:\"https://buddypress.org/?p=311439\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:68:\"https://buddypress.org/2020/05/buddypress-6-0-0-release-candidate-2/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2943:\"

            Hello,

            \n\n\n\n

            The secondย release candidate for BuddyPress 6.0.0ย is now available for an ultimate round of testing!

            \n\n\n\n

            Since the first release candidate and thanks to the WordPress Polyglots Team (Many thanks to @tobifjellner & @ocean90), we’ve found an issue involving the translation of our new BuddyPress Blocks. The BP Blocks are using JavaScript i18n functions and a specific task of our build process was preventing GlotPress from identifying the strings needing to be translated.

            \n\n\n\n

            We believe we’ve fixed this issue and this new release candidate will help us confirm it.

            \n\n\n\n

            BuddPress 6.0.0 is still slated for release on Thursday, May 14, and if you havenโ€™t tried 6.0.0 yet, it’s probably your last chance to do so!

            \n\n\n\n

            You can test theย 6.0.0-RC2ย pre-release in 4 ways :

            \n\n\n\n\n\n\n\n

            A detailed changelog will be part of our official release note, but you can get a quick overview by reading the post about the 6.0.0 Beta1 release.

            \n\n\n\n
            \n\n\n\n

            Polyglots contributors, there’s some extra work.

            \n\n\n\n

            This release candidate should introduce around 50 new strings to translate (the ones that were not included previously due to the issue), so thanks in advance for your comprehension and for your help .

            \n\n\n\n
            \n\n\n\n

            As usual, if you think youโ€™ve found a bug, please let us know reporting it on the support forums and/or on our development tracker.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Sun, 03 May 2020 04:45:07 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:12:\"Mathieu Viet\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:37;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:99:\"WPTavern: FOSS Responders Group Brings Financial Help to Open Source Ecosystem Affected by COVID-19\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99213\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:243:\"https://wptavern.com/foss-responders-group-brings-financial-help-to-open-source-ecosystem-affected-by-covid-19?utm_source=rss&utm_medium=rss&utm_campaign=foss-responders-group-brings-financial-help-to-open-source-ecosystem-affected-by-covid-19\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2003:\"

            The pandemic has caused economic hardships and upheaval in nearly every industry. Open source communities and contributors have been affected in a myriad of ways – whether it’s a loss of donations, the burden of nonrefundable travel expenses for canceled conferences, or severely diminished business and fundraising opportunities.

            \n\n\n\n

            FOSS Responders is a working group of volunteers that aims to future-proof the open source infrastructure we rely on by helping sustain those who maintain the software. The group’s website allows those in need to apply for emergency funds. FOSS Responders is raising money on Open Collective and 100% of donations go to open source technologists in need. So far the group has an estimated annual budget of $8,145.05. Open Collective is also waiving its platform fees on COVID-19 solidarity collectives until the end of June.

            \n\n\n\n

            On May 22, FOSS Responders plans to host a virtual funding event to provide financial support for organizations affected by the profound economic disruptions caused by the pandemic. Organizers have a $5,000 goal for ticket revenue from general event ticket sales.

            \n\n\n\n

            In addition to providing emergency funds, the FOSS Responders group is aiming to address non-financial needs. Open source projects that relied heavily on events for fundraising need help amplifying their projects and recruiting volunteers. FOSS Responders is also creating a Resource Center for projects to find tips and tricks on how to manage fully virtual community interactions and events. Anyone with a skill or service to volunteer can get in touch on the FOSS Responders website and the team will work as matchmakers to connect experts with projects that need help.

            \n\n\n\n

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 01 May 2020 23:04:29 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:38;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:79:\"WPTavern: Block Lab Team Joins WP Engine, Looks to the Future of Block Building\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=98935\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:201:\"https://wptavern.com/block-lab-team-joins-wp-engine-looks-to-the-future-of-block-building?utm_source=rss&utm_medium=rss&utm_campaign=block-lab-team-joins-wp-engine-looks-to-the-future-of-block-building\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:5636:\"

            The three-person Block Lab team of Luke Carbis, Ryan Kienstra, and Rob Stinson is joining WP Engine to work on the company’s block editor projects. WP Engine approached the team members after seeing how successful the Block Lab project had grown and made them an offer. The team will be able to continue building projects with solid financial backing.

            \n\n\n\n

            Block Lab is a plugin that was created to allow other developers to build blocks without needing to wade through the depths of complex JavaScript programming. It is a way to get your feet wet in the block development pool without diving in head first. The plugin has built a solid reputation based on user reviews. Out of 39 submissions, it has received 38 five-star ratings.

            \n\n\n\n

            “From the start, Block Lab has been our answer to the question of ‘how can I lower the barrier to entry for creating custom blocks,\'” said Stinson. He said the plugin has done two important things for developers. It has given them an easy-to-use admin interface to work from and a simplified templating experience that is aligned with traditional workflows. “It’s helped folk who haven’t had the time to summit the JS-all-the-things mountain or simply provide those that are looking for a standardized system that does a lot of the heavy lifting for them.”

            \n\n\n\n

            The Block Lab plugin is being phased out, but the team assures that the plugin’s current users will not be left in the dust. The plan is to continue supporting the plugin through bug and compatibility fixes for the next year. Pro users will also receive the same support until their license expires. In the long term outlook, the team plans to build a migration path to the new tools they will be building under the WP Engine banner.

            \n\n\n\n

            Stinson said that the plugin should work well for a long time to come because it was built by Carbis and Kienstra, two of the best engineers he has worked with. However, he stresses that the work they will be doing with WP Engine will exceed anything they have done with Block Lab.

            \n\n\n\n

            “We’ll be working on technology there that is focused on the Block Editor though, and a part of that will be taking what we’ve done with Block Lab and introducing the feature set to the WP Engine suite of products,” he said. “The alignment will be close and will offer existing Block Lab users an easy migration experience.”

            \n\n\n\n

            While the Block Lab plugin will see an end, the features the team has worked on will live on in some form.

            \n\n\n\n

            A New Beginning

            \n\n\n\n

            Before taking on roles with WP Engine, each member of the Block Lab team was paying the bills through agency and freelance work. Block Lab was merely a side project they were handling in their free time, but it was slowly growing both in scale and financially.

            \n\n\n\n

            “Getting to a place where we could give it full-time focus was easily two to three years away though,” said Stinson, “and we have always been incredibly conscious of the things we wanted to be doing with it and how much the time factor was a limitation. With WP Engine, we’re equipped to take the product vision we had for Block Lab and basically strap a rocket to it. Not only are we able to devote our full attention, but we also have the incredible support and resources of WP Engine behind us.”

            \n\n\n\n

            Stinson is looking forward to the transition within the state of the current WordPress ecosystem. The team can walk into a fresh beginning with the full weight of a major company behind them. “Between the classic way of building with WordPress and this new block-first frontier, being set up right now to build and contribute is incredible!” he said.

            \n\n\n\n

            The team had an existing roadmap and backlog of features they wanted to develop. However, with Block Lab being only a side project, it meant those features would have taken much longer to build. They can now pursue them full time.

            \n\n\n\n

            “We saw what Block Lab has currently as a necessary baseline for a plugin that equipped folks to create custom blocks, but what we have planned and are dreaming about goes so much further,” said Stinson. “Joining WP Engine unleashes us to chase down that work faster and with more focus. Another really exciting piece of this is that with our focus we are better positioned to offer insights and contribution to the larger block editor project through core and community contributions.”

            \n\n\n\n

            The team now has the opportunity to be a pioneer in the years to come. They have proved they can build a useful tool on top of the block editor. The next step is seeing where they take it and whether they can get more developers to join them into a world of building blocks.

            \n\n\n\n

            “The shift in thinking around how a website is structured towards one that is powered by ‘blocks’ is a journey that the majority of the WP community is still on,” said Stinson. “A big part of my vision is having a larger portion of the community up to speed and onboard with this. With more people operating within that zone, more great work and tooling will be produced. By lowering the barrier to entry through Block Lab and what we have planned at WP Engine, it will help to get more people in that zone.”

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Fri, 01 May 2020 17:16:06 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:39;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:63:\"WPTavern: WordCamp US 2020 Goes Online, Cancels In-Person Event\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99149\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:169:\"https://wptavern.com/wordcamp-us-2020-goes-online-cancels-in-person-event?utm_source=rss&utm_medium=rss&utm_campaign=wordcamp-us-2020-goes-online-cancels-in-person-event\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:3758:\"

            WordCamp US 2020 organizers have cancelled the in-person event in favor of hosting it as an online-only conference. With more than a million confirmed coronavirus cases in the U.S. today, 63,000+ deaths, and 31 states set to partially reopen this weekend, the pandemic’s trajectory throughout the country has become increasingly uncertain.

            \n\n\n\n

            Many statewide stay-at-home orders are expiring tomorrow, despite no state having met the federal guidelines for reopening. Some businesses are opting to reopen in a limited capacity, but the general populace is still wary of returning to their previous way of life. In the state of Missouri, where WordCamp US was to be hosted in 2020, there will be no limitations on social gatherings as of May 4, as long as individuals maintain social distancing. It’s not yet possible to predict what will be happening in the area in October or how it might impact an event with international attendees.

            \n\n\n\n

            After organizers extended the WCUS speaker application deadline for another 1.5 months on April 17, it seemed the general disinclination towards traveling and gathering in large groups had already taken hold. Booking hotels and travel arrangements five months in advance is still too much of a gamble for speakers and attendees.

            \n\n\n\n

            The WCUS organizing team emphasized the longterm health and safety of the WordPress community as their primary concern in today’s announcement about moving to an online-only event:

            \n\n\n\n

            The WCUS organizing team has been working with WordCamp Central and local health authorities to try to make sense of the current COVID-19 pandemic and what it means for our event in St. Louis this October. Throughout this, we have held the longterm health and safety of the WordPress community as the highest priority of our event. To move forward in a way that honors what is best for our community – both locally and globally – we have made the hard choice to convert WordCamp US 2020 to an online only event. 

            \n\n\n\n

            WCUS will still happen on the originally scheduled dates, October 27th – 29th. Organizers plan to run sessions, workshops, and a virtual Contributor Day, along with the annual State of the Word address from Matt Mullenweg. They are also putting together a hallway track, some form of swag, and creative ways for attendees to connect, which will be announced at a later date.

            \n\n\n\n

            WCUS is now free for anyone who wants to attend. Without the necessity to rent a venue, provide lunches, and other physical aspects of the event, sponsorships are easily able to cover the cost of streaming to an unlimited number of attendees.

            \n\n\n\n

            The call for speakers is open until May 31, 2020 at 11:59 pm CDT. WCUS is still accepting sponsorships and will be publishing a set of unique sponsorship packages for the virtual event. Organizers plan to put out a call for volunteers in the near future.

            \n\n\n\n

            WordCamp US follows other major regional WordCamps in Asia and Europe that have canceled in-person events due to the pandemic. Several other upcoming WordCamps, including events in Spain, Kent, Denver, and Minneapolis / Saint Paul, have also announced that they are transitioning to online-only events.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 30 Apr 2020 22:49:16 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:40;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:103:\"WPTavern: Gutenberg 8.0 Merges Block and Pattern Inserter, Adds Inline Formats, and Updates Code Editor\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99130\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:247:\"https://wptavern.com/gutenberg-8-0-merges-block-and-pattern-inserter-adds-inline-formats-and-updates-code-editor?utm_source=rss&utm_medium=rss&utm_campaign=gutenberg-8-0-merges-block-and-pattern-inserter-adds-inline-formats-and-updates-code-editor\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:5033:\"

            The team behind the Gutenberg plugin shipped version 8.0 yesterday. The update adds some nice user-facing changes, including a merged block and pattern inserter, new inline formatting options, and visual changes to the code editor. Over two dozen bug fixes were included in the release, along with several enhancements.

            \n\n\n\n

            Designers on the project updated the welcome box illustrations to match the current UI. Because the welcome modal should already be dismissed for current users, only new users should see these changes.

            \n\n\n\n

            For theme authors, the post title and placeholder paragraph text for the block appender will inherit body font styles. Previously, they had specific styles attached to them in the editor. The current downside is that the post title is not an <h1> element so it cannot automatically inherit styles for that element. However, that will change once the post title becomes a true block in the editor.

            \n\n\n\n

            The editor also now clears centered blocks following a floated block. This is an opinionated design change, but it should not negatively affect most themes. However, theme authors should double-check their theme styles to be sure.

            \n\n\n\n

            Updated Block and Pattern Inserter

            \n\n\n\nPatterns available in the inserter.\n\n\n\n

            The development team added patterns to the existing inserter. Now, both blocks and patterns have an individual tab within a unified interface. This is yet another step in the evolution of the pattern system that should land in core WordPress this year.

            \n\n\n\n

            Right now, the experience is a two-steps-forward-one-step-back deal. The inserter’s behavior has improved and it is great to see patterns merged into it. However, all blocks and patterns are within long lists that require scrolling to dig through. Block categories are no longer tabbed in version 8.0, which is a regression from previous versions. I am certain this will be resolved soon enough, but it is a little frustrating locating a block in the list at the moment.

            \n\n\n\n

            Merging patterns into the inserter is an ongoing process. There is still a lot of work to do before the final product is polished and included in core WordPress.

            \n\n\n\n

            The following are some key items that need to be addressed in upcoming versions of Gutenberg:

            \n\n\n\n
            • Patterns should be categorized the same as blocks.
            • The block search box should switch to a pattern search box when viewing patterns.
            • Pattern titles should be reintroduced in the interface (removed in 8.0).
            \n\n\n\n

            Of course, there is a host of other minor and major issues the team will need to cover to nail down the user experience. For now, the interface for patterns continues to improve.

            \n\n\n\n

            Subscript and Superscript Formats

            \n\n\n\nAdding superscript text to the editor.\n\n\n\n

            Gutenberg developers added two new inline formatting options to the editor toolbar: subscript and superscript. These options allow users to add text such as X2 and X2. They work the same as bold, italic, inline code, and other options.

            \n\n\n\n

            The two formatting options represent their respective inline HTML tags, <sub> for subscript and <sup> for superscript. With the addition of the elements, the toolbar now covers most of the widely-used inline HTML tags. The only other tags that are low on my wish list are <abbr>, <del>, and <ins>, but I could live with those remaining firmly in plugin territory.

            \n\n\n\n

            Improved Code Editor

            \n\n\n\nUpdated code-editing view.\n\n\n\n

            The code editor received a much-needed overhaul in the 8.0 update. Everything from the post title to the content is set in a monospace font, and the width of the code editing box spans the editing area. It should be a welcome change for those who need to switch to code view once in a while.

            \n\n\n\n

            The next step to polishing the code editor (and the HTML block) would be to add syntax highlighting. In the current version, the HTML output is plain text. Given the extra markup that the block editor produces, it can be a bit of a jumbled mess to wade through. Basic syntax highlighting would improve the experience several times over. There is a GitHub ticket for adding the feature, but it has not seen any movement in several months.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 30 Apr 2020 19:48:34 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:41;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:46:\"BuddyPress: BuddyPress 6.0.0 Release Candidate\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:32:\"https://buddypress.org/?p=311340\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:66:\"https://buddypress.org/2020/04/buddypress-6-0-0-release-candidate/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:3360:\"

            Hello BuddyPress community members!

            \n\n\n\n

            The first release candidate for BuddyPress 6.0.0 is now available for a last round of testing!

            \n\n\n\n

            This is an important milestone as we progress toward the BuddyPress 6.0.0 final release date. โ€œRelease Candidateโ€ means that we think the new version is ready for release, but with more than 200,000 active installs, hundreds of BuddyPress plugins and Thousands of WordPress themes, itโ€™s possible something was missed.

            \n\n\n\n
            \"\"
            \n\n\n\n

            BuddPress 6.0.0 is slated for release on Thursday, May 14, but we need your help to get thereโ€”if you havenโ€™t tried 6.0.0 yet, now is the time!

            \n\n\n\n

            You can test the 6.0.0-RC pre-release in 4 ways :

            \n\n\n\n\n\n\n\n

            A detailed changelog will be part of our official release note, but you can get a quick overview by reading the post about the 6.0.0 Beta1 release.

            \n\n\n\n
            \n\n\n\n

            Plugin and Theme Developers

            \n\n\n\n

            Please test your plugins and themes against BuddyPress 6.0.0. If you find compatibility problems, please be sure to post to this specific support topic so we can figure those out before the final release. We strongly advise you to have a look at the 6.0.0 development notes to figure out what to focus on during your testing.

            \n\n\n\n
            \n\n\n\n

            Polyglots, we need you!

            \n\n\n\n

            Do you speak a language other than English?ย Help us translate BuddyPress into many languages!ย This release also marks theย string freezeย point of the 6.0.0 release schedule. For your information, we are now using WP CLI to generate the buddypress.pot file and you’ll see we’ve paid attention to add translators comments to all the strings needing some.

            \n\n\n\n

            If you think youโ€™ve found a bug, please let us know reporting it on the support forums and/or on our development tracker.

            \n\n\n\n

            Thanks in advance for giving the release candidate a test drive!

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Thu, 30 Apr 2020 00:45:06 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:12:\"Mathieu Viet\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:42;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:76:\"WPTavern: WordPress 5.4.1 Addresses 7 Security Issues and Fixes Several Bugs\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99123\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:197:\"https://wptavern.com/wordpress-5-4-1-addresses-7-security-issues-and-fixes-several-bugs?utm_source=rss&utm_medium=rss&utm_campaign=wordpress-5-4-1-addresses-7-security-issues-and-fixes-several-bugs\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:5888:\"

            WordPress 5.4.1, a security and maintenance release, dropped today. The release addresses seven security issues, which were all responsibly disclosed to the WordPress security team. Core developers also included several fixes for code regressions in the previous version 5.4 release and ported bug fixes to the block editor from the Gutenberg plugin.

            \n\n\n\n

            End-users with automatic updates enabled should begin seeing their sites updated shortly. Other users should update as soon as possible to make sure they are running a version of WordPress with the latest security fixes.

            \n\n\n\n

            The WordPress support team has published the full release documentation for those who wish to view it.

            \n\n\n\n

            Security fixes were added to every major version of WordPress from 5.4 back to 3.7. The following vulnerabilities were addressed:

            \n\n\n\n
            • Password reset tokens were not correctly invalidated.
            • Some private posts could be viewed without authentication.
            • Two cross-site scripting (XSS) vulnerabilities in the customizer.
            • XSS issue in the search block.
            • XSS issue in the WordPress object cache.
            • XSS issue with file uploads.
            • XSS issue in the block editor for WordPress 5.4 Release Candidates 1 and 2 (fixed in 5.4 RC5).
            \n\n\n\n

            Block Editor Updates

            \n\n\n\n

            Several fixes were high priority enough from the Gutenberg plugin to port to the WordPress 5.4.1 release. The biggest user-facing issues were a broken block duplication keyboard shortcut, misaligned buttons blocks, and odd scrolling behavior when attempting to edit text in a long block.

            \n\n\n\n

            The following is a full list of the issues the development team addressed:

            \n\n\n\n
            • Fixed the Ctrl + Shift + D keyboard shortcut for duplicating a block, which no longer throws an error.
            • Adds correct margins when aligning the buttons block left or right.
            • Prevents the editor from scrolling to the top when clicking to edit a large block, such as a long list.
            • No longer hides the toolbar for plugins that have text inputs in the toolbar.
            • Stops a JavaScript crash with the latest posts block when an image has missing dimensions.
            • Escapes the HTML class for the RSS and search blocks to prevent malformed markup.
            \n\n\n\n

            To review the code changes to the block editor in-depth, see the full ticket list.

            \n\n\n\n

            Other Core WordPress Changes

            \n\n\n\n

            Users who run their browsers in dark mode can rejoice if they also use the core WordPress favicon. The team introduced an updated favicon with a light background so that it no longer washes out. It is a minor fix but makes the famed WordPress logo look more professional.

            \n\n\n\n

            The heading level, which was previously set to <h3>, has been bumped up one level on the WordPress admin freedoms screen (wp-admin/freedoms.php). This change provides the proper heading level and should help screen-reading users better navigate the page.

            \n\n\n\n

            For users on the Edge or iOS Safari browsers who could not select files in the media library, it was due to a CSS issue that hid the input. This should no longer be an issue in the new update.

            \n\n\n\n

            WordPress 5.4.1 addressed some regressions from the previous version. One revolves around posting by email when no post title was added. In that scenario, the email subject should have been used as the title, but this was broken by a code change in WordPress 5.4. For developers, the category_link and tag_link filter hooks were mistakenly deprecated previously and are now once again good to use without throwing a notice.

            \n\n\n\n

            Plugin developers have a few bug fixes to look forward to. The WP_Site_Health object is now instantiated after the plugins_loaded and after_setup_theme hooks, which means they can perform necessary actions before the site health is checked. The deprecated wp_get_user_request_data() function is now correctly loaded on the front end, which was causing errors with plugins such as BuddyPress.

            \n\n\n\n

            In a larger design change, plugin authors who add custom content to the privacy policy guide can use more HTML elements. In WordPress 5.4, the guide design was updated to add a white background behind the suggested text. However, the new code only applied to paragraphs. Now, the design supports tables, lists, and other elements that are commonly used. Unordered lists also have bullet points to distinguish them from paragraphs.

            \n\n\n\n

            The development team fixed two issues with the REST API. The first corrected an issue with the get_item permissions check. The second fixed the _fields filtering. The core code now uses the rest_is_field_included() function to determine which fields to include to permit filtering by nested field properties.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 29 Apr 2020 20:39:42 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:43;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:35:\"WordPress.org blog: WordPress 5.4.1\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:34:\"https://wordpress.org/news/?p=8553\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:51:\"https://wordpress.org/news/2020/04/wordpress-5-4-1/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:6919:\"

            WordPress 5.4.1 is now available!

            \n\n\n\n

            This security and maintenance release features 17 bug fixes in addition to 7 security fixes. Because this is a security release, it is recommended that you update your sites immediately. All versions since WordPress 3.7 have also been updated.

            \n\n\n\n

            WordPress 5.4.1 is a short-cycle security and maintenance release. The next major release will be version 5.5.

            \n\n\n\n

            You can download WordPress 5.4.1 by downloading from WordPress.org, or visit your Dashboard โ†’ Updates and click Update Now.

            \n\n\n\n

            If you have sites that support automatic background updates, theyโ€™ve already started the update process.

            \n\n\n\n

            Security Updates

            \n\n\n\n

            Seven security issues affect WordPress versions 5.4 and earlier. If you havenโ€™t yet updated to 5.4, all WordPress versions since 3.7 have also been updated to fix the following security issues:

            \n\n\n\n
            • Props to Muaz Bin Abdus Sattar and Jannes who both independently reported an issue where password reset tokens were not properly invalidated.
            • Props to ka1n4t for finding an issue where certain private posts can be viewed unauthenticated.
            • Props to Evan Ricafort for discovering an XSS issue in the Customizer
            • Props to Ben Bidner from the WordPress Security Team who discovered an XSS issue in the search block.
            • Props to Nick Daugherty from WordPress VIP / WordPress Security Team who discovered an XSS issue in wp-object-cache.
            • Props to Ronnie Goodrich (Kahoots) and Jason Medeiros who independently reported an XSS issue in file uploads.
            • Props to Weston Ruter for fixing a stored XSS vulnerability in the WordPress customizer.
            • Additionally, an authenticated XSS issue in the block editor was discovered by Nguyen The Duc (ducnt) in WordPress 5.4 RC1 and RC2. It was fixed in 5.4 RC5. We wanted to be sure to give credit and thank them for all of their work in making WordPress more secure.
            \n\n\n\n

            Thank you to all of the reporters for privately disclosing the vulnerabilities. This gave the security team time to fix the vulnerabilities before WordPress sites could be attacked.

            \n\n\n\n

            For more information, browse the full list of changes on Trac, or check out the version 5.4.1 HelpHub documentation page.

            \n\n\n\n

            In addition to the security researchers mentioned above, thank you to everyone who helped make WordPress 5.4.1 happen:

            \n\n\n\n

            Alex Concha, Andrea Fercia, Andrew Duthie, Andrew Ozz, Andy Fragen, Andy Peatling, arnaudbroes, Chris Van Patten, Daniel Richards, DhrRob, Dono12, dudo, Ehtisham Siddiqui, Ella van Durpe, Garrett Hyder, Ian Belanger, Ipstenu (Mika Epstein), Jake Spurlock, Jb Audras, John Blackbourn, John James Jacoby, Jonathan Desrosiers, Jorge Costa, K. Adam White, Kelly Choyce-Dwan, MarkRH, mattyrob, Miguel Fonseca, Mohammad Jangda, Mukesh Panchal, Nick Daugherty, noahtallen, Paul Biron, Peter Westwood, Peter Wilson, pikamander2, r-a-y, Riad Benguella, Robert Anderson, Samuel Wood (Otto), Sergey Biryukov, Sรธren Brรธnsted, Stanimir Stoyanov, tellthemachines, Timothy Jacobs, Toro_Unit (Hiroshi Urabe), treecutter, and yohannp.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 29 Apr 2020 19:56:47 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Jake Spurlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:44;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:71:\"Akismet: Version 4.1.5 of the Akismet WordPress Plugin is Now Available\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"http://blog.akismet.com/?p=2068\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:99:\"https://blog.akismet.com/2020/04/29/version-4-1-5-of-the-akismet-wordpress-plugin-is-now-available/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:1339:\"Version 4.1.5 of the Akismet plugin for WordPress is now available. It contains the following changes:\n\n\n
              \n
            • Based on user feedback, we have dropped the in-admin notice explaining the availability of the “privacy notice” option in the AKismet settings screen. The option itself is available, but after displaying the notice for the last 2 years, it is now considered a known fact.
            • \n
            • Updated the “Requires at least” to WP 4.6, based on recommendations from https://wp-info.org/tools/checkplugini18n.php?slug=akismet
            • \n
            • Moved older changelog entries to a separate file to keep the size of this readme reasonable, also based on recommendations from https://wp-info.org/tools/checkplugini18n.php?slug=akismet
            • \n
            \n\n\nTo upgrade, visit the Updates page of your WordPress dashboard and follow the instructions. If you need to download the plugin zip file directly, links to all versions are available in the WordPress plugins directory.\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 29 Apr 2020 13:12:48 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Stephane Daury\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:45;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:108:\"WPTavern: Tectonic Shifts in Retail Industry are Creating Unprecedented Opportunities for Independent Stores\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=98957\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:261:\"https://wptavern.com/tectonic-shifts-in-retail-industry-are-creating-unprecedented-opportunities-for-independent-stores?utm_source=rss&utm_medium=rss&utm_campaign=tectonic-shifts-in-retail-industry-are-creating-unprecedented-opportunities-for-independent-stores\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:12689:\"

            Major retailers that are part of the critical infrastructure for distributing household essentials, healthcare items, and shelf-stable food, are raking in the cash during this pandemic. While consumer spending at bars, restaurants, and places of entertainment has dropped precipitously, spending at Amazon and Walmart has increased considerably in the past few weeks. The companies cannot hire workers fast enough to meet consumer demand.

            \n\n\n\n

            According to a report from Facteus, a firm that provides data from billions of transactions from over 1,000 financial services companies, Amazon and Walmart’s year-over-year growth recently hit 80% and 18%, respectively in the past few weeks.

            \n\n\n\n
            \n\n\n\n

            The pandemic has worked as a catalyst for pre-existing trends, “accelerating the retail reckoning,” as Derek Thompson predicts in his recent article on how The Pandemic Will Change American Retail Forever. Brick and mortar storefronts are rapidly becoming obsolete in a world that is forcibly consigned to shopping from home.

            \n\n\n\n

            There are still many uncertainties about SARSCoV-2 and how humanity will safely find its way out of lockdown. Recovery from the virus may not confer long-term immunity and a vaccine may be more than a year away, likely pushing social distancing measures into 2021. Consumer behavior may be forever altered by this experience, as many people may continue to avoid in-person browsing at stores long after the worst is over.

            \n\n\n\n

            While it might seem like the retail titans are still uncontested in their domination, there are tectonic shifts happening in the retail industry that are giving smaller, independent stores an unprecedented opportunity to gain new customers online. Merchants that can adapt and excel at getting products to a homebound population stand to be the most resilient during this pandemic.

            \n\n\n\n

            In order to keep up with demand, Amazon has had to delay shipments of non-essential items by up to a month in some cases, prioritizing household basics and medical supplies. Major grocery retailers are competing against one another to hire furloughed workers in order to keep up with the demand for groceries with so many people eating at home. Independent stores that can be found online have the opportunity to step up and fill in the gaps where major retailers cannot meet the demand fast enough.

            \n\n\n\n

            People are more inclined to support small businesses right now in light of current circumstances. Amazon’s severely strained relationship with buyers, sellers, affiliates, and employees is also contributing to consumers’ eagerness to support independent stores.

            \n\n\n\n

            On April 21, Amazon slashed commission rates nearly in half for most product categories, negatively impacting media companies and publishers that have not diversified their affiliate revenue sources.

            \n\n\n\n

            Amazon’s essential workers are planning to join others from Instacart, Whole Foods, Walmart, Target, and FedEx in a strike on Friday. They are protesting their employers’ record corporate profits which they say have come at the expense of workers’ health and safety. Many consumers have already grappled with a question of conscience in continuing to shop on Amazon after hearing reports of grueling labor conditions for years.

            \n\n\n\n

            Another major development in the retail industry has come to light as the result of a recent Wall Street Journal investigation, which revealed that Amazon is using data from its sellers to launch competing products. Merchants selling successfully on Amazon are not safe from having their products copied and their businesses effectively cannibalized.

            \n\n\n\n

            Documents obtained by the WSJ, along with interviews from more than 20 former employees of Amazon’s private-label business, described how the marketplace operator uses third-party sellers’ data to gain a competitive advantage:

            \n\n\n\n

            In one instance, Amazon employees accessed documents and data about a bestselling car-trunk organizer sold by a third-party vendor. The information included total sales, how much the vendor paid Amazon for marketing and shipping, and how much Amazon made on each sale. Amazon’s private-label arm later introduced its own car-trunk organizers.

            \n\n\n\n

            The WSJ exposé details the great pressure that Amazon executives are under to deliver successful private-label products:

            \n\n\n\n

            Former executives said they were told frequently by management that Amazon brands should make up more than 10% of retail sales by 2022. Managers of different private-label product categories have been told to create $1 billion businesses for their segments, they said.

            \n\n\n\n

            This practice of launching competing products with access to third-party sellers’ data has been happening for years but is an especially hostile tactic to employ in a time when Amazon’s revenue is skyrocketing and small businesses are struggling to stay afloat. It is a sobering reminder of the value of hosting your own online store and the importance of owning your own data.

            \n\n\n\n

            There are some positive developments in the industry that should give small business owners confidence in maintaining independence from the dominant forces in online retail.

            \n\n\n\n

            Wired published an article this week titled The Coronavirus Pandemic Is Changing How People Buy Books by Kate Knibbs. She describes how one indie bookseller’s e-commerce startup has found unlikely success in positioning itself as “an easy way to buy books online without further enriching Jeff Bezos:”

            \n\n\n\n

            Bookshop went from a well-intentioned startup facing an uphill battle to one of the most popular ways to buy books online in a matter of weeks. The New York Times, BuzzFeed, Vox, and The New Republic are all affiliate partners now. Its headcount has doubled in size. Hunter expects to hit $6 million in sales by May, eons ahead of its loftiest projections from January. If the company’s performance holds steady, it could do $60 million in sales a year, although Hunter is assuming post-quarantine life will be different. “I’m sure that when things open back up, our sales will drop, maybe even cut in half,” he says. “But even then, we’re still one of the top 10 bookstores in the US.”

            \n\n\n\n

            Yesterday, Shopify launched its new Shop app, touting modularized, distributed marketplaces as the future of e-commerce. The app allows shoppers to browse local merchants and make purchases. It provides a new vehicle of exposure for the company’s 1m+ merchants on its platform. Businesses do not have to pay to have access to the app, nor do they pay commissions on the sales it generates.

            \n\n\n\n

            Google is also making it easier for smaller stores to be found on the web by opening up the Shopping tab to free listings and partnering with WooCommerce, Shopify, and BigCommerce. This essentially gives more free traffic to small businesses whose listings will break up the longstanding dominance of major online retailers in the Shopping tab.

            \n\n\n\n

            WordPress developers with e-commerce experience have the opportunity to build products and stores that will help traditional brick-and-mortar businesses start selling online quickly, so they can continue to find success in. the brave new world of online-first retail. WordPress has a plethora of plugin options for making e-commerce accessible to store owners, no matter how simple or complex the store’s requirements.

            \n\n\n\n

            Independent WooCommerce Stores Are Booming

            \n\n\n\n

            One user in the WooCommerce community’s Facebook group asked how the coronavirus is impacting members’ e-commerce stores. Responses were varied based on the types of products that the merchants were selling, but the vast majority of responses from store owners and developers were positive reports of increased sales:

            \n\n\n\n
            • “I have a client selling cleaning products. He got several pallets of hand sanitizer in and sold out in a week. He was doing about $2000 in sales a day.”
            • “My client does fruit and veg online. Went from £4k a month trickling along as a side part of his business, to £150k last month and the heading for the same this month.”
            • “We are selling plumbing and home improvement tools and items sales have quadrupled.”
            • “Positive impact. Highest sales for me on my indoor activities niche (puzzles, board games).”
            • “Sales are up more than 1000% – natural supplements”
            • “Built a cake delivery service to sell slices of cake locally…… £4K in a day and sold out. It’s crazy.”
            • “800% increase on a niche plant site I host”
            • “Compared to same month last year, up approx 250% (garden products)”
            • “3000% increase during the last month compared to monthly average over the last year. Natural health products”
            • “Our canvas printing site is up 20%”
            • “We are selling more Glass Bongs than ever. People are staying home and getting stoned.”
            \n\n\n\n

            Saad Munir, the CEO of an e-commerce marketing agency, manages 28 stores for their clients with $30-$500k sales per month in various niches.

            \n\n\n\n

            “Some of them are popular brands of their niche,” Munir said. “We have seen a drop in sales of up to 80% in non-essential and medium luxury products, and a 400% increase in essential products. However, now non-essential and daily-use products have also started getting good sales since everyone is home and sticking to their devices during this social distancing. We also have clients of furniture e-commerce stores. This means high-ticket items. They have even seen increased sales in bedsets, sofas, etc. So, for sure online sales are increasing. We also on-boarded several new clients and most of these stores are in WooCommerce.”

            \n\n\n\n

            In the WooCommerce Help & Share group, one member asked for help collating all his orders into one list after his artisan cheese business increased exponentially overnight. Another member asked for help optimizing his client’s store after their pre-COVID-19 revenue went from less than £1k/month to almost £2k sales per day.

            \n\n\n\n

            If independent self-hosted stores are able to perform well during this crisis, they have the opportunity to earn customers’ loyalty for continued business long after social distancing requirements are no longer necessary. It’s a unique opportunity that may not have been possible on such an accelerated timeline without this exact set of circumstances.

            \n\n\n\n

            These recent shifts in online retail are the first cracks in the ice towards a web that is more friendly for smaller, independent stores. The trend towards buying all of life’s necessities online has evolved overnight to include a wider spectrum of consumer demographics than ever before. Diverse independent stores are crucial for meeting this demand without losing the unique and varied shopping landscape that the pandemic has forced to be temporarily closed.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 29 Apr 2020 08:17:04 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:46;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:82:\"Post Status: Professional WordPress Plugin Development: Interview with the authors\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"https://poststatus.com/?p=78739\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:92:\"https://poststatus.com/professional-wordpress-plugin-development-interview-with-the-authors/\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:1671:\"

            Professional WordPress Plugin Development was one of the most helpful books I\'ve ever read. To see a new edition with two returning authors, nine years after the original, is very exciting.

            \n\n\n\n

            This edition of the book will be sure to offer a great resource for developer education for years to come. Brad Williams, Justin Tadlock, and John James Jacoby are each extremely talented developers and communicators. The work they can accomplish together is even greater.

            \n\n\n\n

            Cory talks to them about their histories, the book, the process, and much more. We hope you enjoy this episode of Post Status Draft.

            \n\n\n\n\n\n\n\n
            \n\n
            \n\n\n\n

            You can pre-order Professional WordPress Plugin Development now on Amazon. It is slated to be released June 10th.

            \n\n\n\n\n\n\n\n

            Episode Partner: Gravity Forms

            \n\n\n\n

            Gravity Forms is the easiest-to-use and most trusted tool for creating advanced forms for your WordPress-powered website. I use Gravity Forms on every WordPress site I own, and I know I can always rely on its power, flexibility, and reliability.

            \n\n\n\n

            Try Gravity Forms today.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Wed, 29 Apr 2020 04:27:51 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:15:\"Brian Krogsgard\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:47;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:82:\"WPTavern: David Vongries Takes Over as New Owner of the Kirki Customizer Framework\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99016\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:209:\"https://wptavern.com/david-vongries-takes-over-as-new-owner-of-the-kirki-customizer-framework?utm_source=rss&utm_medium=rss&utm_campaign=david-vongries-takes-over-as-new-owner-of-the-kirki-customizer-framework\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:8410:\"

            Ari Stathopoulos sold Kirki, his 6-year-old customizer framework, last week. The plugin is a widely-used tool for theme authors and currently has over 400,000 installations. It is also bundled as a drop-in package within an unknown number of themes, likely numbering in the hundreds. David Vongries, the owner of the Page Builder Framework theme, has taken over the project.

            \n\n\n\n

            All of Kirki’s customizer controls, including those that were previously commercial/premium, are now open under the Kirki Framework GitHub organization.

            \n\n\n\n

            Stathopoulos tweeted his decision to seek a buyer on April 8. “This is an announcement I never thought I’d make,” he wrote. “As much as it saddens me, I have decided to sell the Kirki #WordPress plugin. With 500,000+ installations and included in hundreds of themes I no longer have the ability – as an individual developer – to maintain it. And even though I had big dreams and wanted to facilitate things for the WordPress editor as well, the plugin has grown beyond me…It is no longer possible for a single person to maintain such a beast.”

            \n\n\n\n

            Between his fulltime day job, a representative role for the theme review team, and maintaining other open-source projects, Stathopoulos was pulling 16-hour days of work. Not to mention, he had the usual life elements he needed to make time for in his routine. The Kirki project was not something he could devote any extra time to. Stathopoulos said he knew that spending too much time behind the screen was detrimental to his mental and physical health. He needed to make changes for his personal well-being. Still, it was tough to let go of a project he had invested years into.

            \n\n\n\n

            “Letting go of a project like that feels extremely weird!” he said. “It’s a weird mix of sadness, stress, and relief. I feel sad because it’s out of my control. I feel stressed because it’s out of my control. And I feel relieved because it’s out of my control.”

            \n\n\n\n

            While he suspects the sadness and stress of letting go of his project will subside, he said he already feels relieved to no longer have the responsibility of managing such a huge project alone. “I am no longer responsible for the hundreds of themes that use it; it’s liberating,” he said.

            \n\n\n\n

            No Deal for the Highest Bidder

            \n\n\n\n

            Stathopoulos did not want to let this passion project go to anyone. He wanted someone with the vision to see the project evolve. He had several offers for Kirki. Over 400,000 installations can make for a lucrative opportunity for someone with the right marketing skills. It would have been easy for him to take the highest bid and jump ship, but that is not his style.

            \n\n\n\n

            “Kirki is a weird case,” he said. “It may have 400,000 installations and used by hundreds of themes both free and premium, but the actual ‘clients’ are the theme authors, not the end-users. That fact limits the potential for monetizing the plugin ethically. There were quite a few bids, some were high, some were low, but what surprised me is that a lot of them were not interested in helping the community in any way.”

            \n\n\n\n

            Stathopoulos said the majority of the offers were from buyers with no interest in growing the plugin. Most of them seemed to be looking for a quick buck. He steered clear of them because he did not want to see end-users blasted with obtrusive ads, upsells, or spam.

            \n\n\n\n

            “In the end, I didn’t go with the highest bid, which was 2.5 times the price I gave it for,” he said. “Though I admit I was seriously tempted to ‘take the money and run.’ I went with what I felt was an ethical choice, someone who actually uses the project on a daily basis, wants to evolve it, and I feel will honor the open-source spirit and the six years of sweat.”

            \n\n\n\n

            Stathopoulos decided to sell to Vongries. The two had previously worked together on multiple occasions on the Kirki project and he felt it was the right move.

            \n\n\n\n

            “Once I decided that he should get it, the process went pretty smooth, and there were no hiccups,” said Stathopoulos. “The hard part was deciding who should get it.”

            \n\n\n\n

            Vongries was almost a natural choice as a new owner. He and his team had been using Kirki since its inception. “I think it’s an incredible framework and it makes working with the WordPress customizer so much easier,” he said.

            \n\n\n\n

            He reached out to Stathopoulos immediately upon seeing it was for sale. The two had a conversation soon thereafter and shared similar visions for the plugin.

            \n\n\n\n

            “I always looked at Kirki as something special and wanted to get involved,” said Vongries. “Until recently though, I wouldn’t have had the resources to do so, but since the team around MapSteps has grown it just all happened at the right time. Being a Kirki user myself, I looked at this from both perspectives — from a developer standpoint and as someone that has been using the plugin for years.”

            \n\n\n\n

            The Future of Kirki

            \n\n\n\n

            Over the past 18 months, Stathopoulos has rewritten the plugin and split it into around 50 Composer packages. The plan was to make these packages installable as individual components for plugin and theme authors. Instead of bundling the entire Kirki library, developers can use the pieces they need. At this point, these components should be stable, but they have not been widely tested by theme authors, who are accustomed to working with the full framework.

            \n\n\n\n

            He was also excited about the potential move away from the customizer and working with full-site editing and global styles. Right now, it is unclear how the future of the Gutenberg project will impact the customizer. Many theme authors are now looking at it as a dying piece of the platform. Stathopoulos felt like there was still room to grow and transition into the new era.

            \n\n\n\n

            “My vision for Kirki was to combine some things with full-site editing, and allow themes that were using Kirki to automatically get global styles when they land in WordPress core,” he said. “That would be truly amazing, and I’m sure it will be possible to do once there is an API for global styles. If [Vongries] goes in that direction, there’s definitely potential for monetization there, while at the same time he’ll help people build better things. Can you imagine a painless transition to global styles for themes that use Kirki? That would be a great thing to see!”

            \n\n\n\n

            However, the project is out of the former owner’s hands now. It is Vongries’ vision that must lead the project moving forward.

            \n\n\n\n

            “I respect Ari a lot and he has done an amazing job with Kirki,” said Vongries. “[Stathopoulos] said he would love to continue to contribute to the project, and he is more than welcome to do so.”

            \n\n\n\n

            The immediate plan is to launch Kirki 4.0. It is nearly ready to roll out, awaiting some fine-tuning and final testing. Vongries and his team are also about to begin work on new extensions that bring more controls and functionality to the framework and, potentially, Gutenberg.

            \n\n\n\n

            “We are going to explore how we can make the connection between the existing functionality in Kirki and the upcoming features in Gutenberg and Gutenberg in general,” he said. “At this point, we have some ideas about how we can adapt Kirki to the ever-changing WordPress platform. But for now, they are only ideas. We are certain that we will be able to provide a useful tool for developers, regardless of the direction WordPress and Gutenberg goes.”

            \n\n\n\n

            The new team behind Kirki is still working on the long-term roadmap. It will be exciting to see where they take it. For now, it is still the go-to customizer framework for many theme authors. And, it is in the hands of someone who has been using the project for years.

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Tue, 28 Apr 2020 18:39:32 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:48;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:77:\"WPTavern: WordCamp Europe 2020 Online Registration Now Open: Tickets are Free\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=98976\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:197:\"https://wptavern.com/wordcamp-europe-2020-online-registration-now-open-tickets-are-free?utm_source=rss&utm_medium=rss&utm_campaign=wordcamp-europe-2020-online-registration-now-open-tickets-are-free\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:2514:\"

            WordCamp Europe 2020 is just 37 days away. Organizers announced in April that the event, which was supposed to be hosted in Porto, is moving to be 100% online this year due to the COVID-19 pandemic. WCEU will kick off with a virtual Contributor Day on June 4, followed by two half days of talks and workshops broadcasted via livestream.

            \n\n\n\n

            WordCamp Europe is one of the largest regional WordCamps on the planet and has been hosted in many magnificent venues and inspiring cities over the years. The event routinely sells out of tickets and sponsor packages, as companies and attendees rally around this unique opportunity to connect across boundaries, uniting Europe through a shared love of WordPress.

            \n\n\n\n

            For the first time in the event’s eight-year history, the European WordPress community will have to forego the in-person networking time that many have come to value as both a personal and professional highlight of the year. WCEU Organizers have worked for the better part of a decade to make it one of the most polished and efficient WordCamps. Now the team is forced to pivot and use their expertise to host a top-notch virtual event.

            \n\n\n\n

            Past local organizing teams have been successful at creating an intimate atmosphere that facilitates rewarding connections with a focus on hospitality. These in-person connections add context to remote interactions and conversations long after the event concludes. Reaching this same high level of interpersonal connectivity between attendees is going to be a challenge for this online edition, but WCEU organizers have a long track record of adapting to different environments. Dozens of other WordPress meetups, WordCamps, and educational events are currently facing the same challenges and are moving online.

            \n\n\n\n

            Registering for a ticket to WCEU is optional but attendees who want to participate in the virtual networking, Q&A sessions, and contributor day will have be registered. Organizers were expecting approximately 3,000 attendees but hosting the event online may affect those numbers in either direction. Tickets are available for free on the WCEU website, thanks to the event’s sponsors. After eight hours of open registration, there are 4,257 tickets remaining. The event will return to Porto, Portugal, on June 3-5, 2021.

            \n\n\n\n

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 27 Apr 2020 23:10:17 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:13:\"Sarah Gooding\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}i:49;a:6:{s:4:\"data\";s:13:\"\n \n \n \n \n \n \n\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";s:5:\"child\";a:2:{s:0:\"\";a:5:{s:5:\"title\";a:1:{i:0;a:5:{s:4:\"data\";s:53:\"WPTavern: Should the Block Editor Have a Grid System?\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"guid\";a:1:{i:0;a:5:{s:4:\"data\";s:29:\"https://wptavern.com/?p=99028\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:4:\"link\";a:1:{i:0;a:5:{s:4:\"data\";s:149:\"https://wptavern.com/should-the-block-editor-have-a-grid-system?utm_source=rss&utm_medium=rss&utm_campaign=should-the-block-editor-have-a-grid-system\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:11:\"description\";a:1:{i:0;a:5:{s:4:\"data\";s:5456:\"

            Laying out a webpage design and getting every element aligned perfectly can be a tough job. Even many developers rely on CSS grid frameworks. Granted, with the introduction of the flexbox and grid systems in the CSS language, such frameworks are becoming unnecessary. Whether it is getting the vertical and horizontal rhythm down or simply aligning an image next to a bit of text, page layouts are often done best via some sort of grid system.

            \n\n\n\n

            This becomes even more apparent when building a page layout visually through the WordPress block editor. The current iteration of the editor does a fine job of being a general content editor while providing the ability to insert various elements into the page.

            \n\n\n\n

            However, it is not by any means a page builder — yet.

            \n\n\n\n

            The question is, before we engage in full-site editing, global styles, block patterns, and other upcoming tools, whether a grid system should be a part of the equation. If so, how should that system work? Will it be configurable by theme authors? How will it handle tablet and mobile views? Will the grid be visible to users or a hidden thing in the background?

            \n\n\n\n

            As more block plugins are released, particularly with those that may have multiple elements that may need to be aligned, it might be time we consider a grid system. Such a system may benefit existing core blocks right now, such as Columns and Media & Text. Or, it may be better as a separate, standalone block.

            \n\n\n\n

            Including a grid system also has the additional benefit of standardizing on layout-related class names that theme authors can use in their CSS, even outside the content editor. This would bring better compatibility across the board when users inevitably switch themes.

            \n\n\n\n

            A Starting Point: Layout Grid Block

            \n\n\n\nThree-column layout with Layout Grid Block.\n\n\n\n

            Automattic, as part of its Block Experiments project, has released the Layout Grid Block plugin. It is essentially a beefed-up version of the core Columns block. The major difference is that column alignment snaps to a specific point in the grid. This grid is also displayed in the background while editing the post.

            \n\n\n\n

            The tricky thing with grids is not simple alignment in columns in desktop view. It is dealing with how those columns transform on smaller devices like tablets and smartphones. Sometimes that is a guessing game from a theme design perspective because the theme author is not privy to the actual content that needs to be aligned. In turn, designers make best-guess decisions and hope it works for most.

            \n\n\n\n

            The Layout Grid block has a “Responsive Breakpoints” tab under the block options panel that allows users to configure this based on device. Users can decide how individual columns span the grid. The grid system is based on a varying number of grid sections based on the device:

            \n\n\n\n
            • Desktop: 12 Sections
            • Tablet: 8 Sections
            • Mobile: 4 Sections
            \n\n\n\n

            Imagine wanting to display a simple image with text to the next of it. There are various ways to do this currently in the block editor. Each has its pros and cons, depending on what you want to do. From a user experience and visual standpoint, I love seeing the grid lines in place as I determine how it should be displayed.

            \n\n\n\nAligning an image and text on a grid.\n\n\n\n

            Another upside of having a grid system is consistency in design. If users can scale the width of columns based on arbitrary numbers, much like they can now do with the Media & Text block, there is no consistency with sizing items horizontally on the page. A grid system changes that.

            \n\n\n\n

            Layout Grid Block still needs some polishing at this point. There are some trivial pain points in the UI that could be improved. On the whole, my experience with this block offered a compelling argument for including a grid system in core.

            \n\n\n\n

            The plugin addresses simple one, two, three, and four columns right now. The grid system in CSS is much more powerful than basic horizontal columns. However, starting with the basics would give us a place to build from.

            \n\n\n\n

            Should Core Include a Grid?

            \n\n\n\n

            There is at least one open ticket on the Gutenberg repository for addressing a grid system. Mark Uraine, the author of the ticket, posted seven key questions:

            \n\n\n\n
            1. Should the grid system be responsive?
            2. Should there be a default Gutenberg grid system, but allow themes to register their own?
            3. Should the grid system conform to the current structure of Gutenberg blocks, or should it be its own thing that we need to restructure the blocks to in the editor?
            4. Should the grid include gutters?
            5. Should the grid include, or allow, any vertical alignment snaps?
            6. What should the grid be based on? (ie. 12 columns, pixel grid, etc.)
            7. Should the grid allow toggling on/off? And also include a setting to show, or not, when resizing objects in the editor?
            \n\n\n\n

            The ticket had some solid discussion nearly a year ago but not much as of late. Would you like to see a grid system in the editor? If so, how would you want it to work?

            \";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}s:7:\"pubDate\";a:1:{i:0;a:5:{s:4:\"data\";s:31:\"Mon, 27 Apr 2020 20:24:08 +0000\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}s:32:\"http://purl.org/dc/elements/1.1/\";a:1:{s:7:\"creator\";a:1:{i:0;a:5:{s:4:\"data\";s:14:\"Justin Tadlock\";s:7:\"attribs\";a:0:{}s:8:\"xml_base\";s:0:\"\";s:17:\"xml_base_explicit\";b:0;s:8:\"xml_lang\";s:0:\"\";}}}}}}}}}}}}}}}}s:4:\"type\";i:128;s:7:\"headers\";O:42:\"Requests_Utility_CaseInsensitiveDictionary\":1:{s:7:\"\0*\0data\";a:8:{s:6:\"server\";s:5:\"nginx\";s:4:\"date\";s:29:\"Sat, 23 May 2020 02:16:09 GMT\";s:12:\"content-type\";s:8:\"text/xml\";s:4:\"vary\";s:15:\"Accept-Encoding\";s:13:\"last-modified\";s:29:\"Sat, 23 May 2020 02:00:07 GMT\";s:15:\"x-frame-options\";s:10:\"SAMEORIGIN\";s:4:\"x-nc\";s:9:\"HIT ord 1\";s:16:\"content-encoding\";s:4:\"gzip\";}}s:5:\"build\";s:14:\"20130911040210\";}','no'),(535,'_transient_timeout_feed_mod_d117b5738fbd35bd8c0391cda1f2b5d9','1590243369','no'),(536,'_transient_feed_mod_d117b5738fbd35bd8c0391cda1f2b5d9','1590200169','no'),(537,'_transient_timeout_dash_v2_88ae138922fe95674369b1cb3d215a2b','1590243369','no'),(538,'_transient_dash_v2_88ae138922fe95674369b1cb3d215a2b','','no'),(539,'recently_activated','a:1:{s:35:\"rest-api-tester/rest-api-tester.php\";i:1590200406;}','yes'),(540,'fs_api_cache','a:2:{s:55:\"get:/v1/plugins/5347/addons.json?enriched=true&count=50\";O:8:\"stdClass\":3:{s:6:\"result\";O:8:\"stdClass\":1:{s:7:\"plugins\";a:5:{i:0;O:8:\"stdClass\":38:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:12:\"developer_id\";s:4:\"6592\";s:10:\"install_id\";s:7:\"3750911\";s:4:\"slug\";s:22:\"pods-alternative-cache\";s:5:\"title\";s:22:\"Pods Alternative Cache\";s:11:\"environment\";i:0;s:4:\"icon\";s:67:\"https://ps.w.org/pods-alternative-cache/assets/icon.svg?rev=1669115\";s:15:\"default_plan_id\";s:4:\"8670\";s:5:\"plans\";i:8670;s:8:\"features\";N;s:17:\"money_back_period\";N;s:13:\"refund_policy\";N;s:24:\"annual_renewals_discount\";N;s:22:\"renewals_discount_type\";s:0:\"\";s:11:\"is_released\";b:1;s:18:\"is_pricing_visible\";b:0;s:19:\"is_wp_org_compliant\";b:1;s:6:\"is_off\";b:0;s:24:\"is_only_for_new_installs\";b:0;s:14:\"installs_limit\";N;s:14:\"installs_count\";i:5;s:21:\"active_installs_count\";i:5;s:19:\"free_releases_count\";i:0;s:22:\"premium_releases_count\";i:0;s:15:\"total_purchases\";i:0;s:19:\"total_subscriptions\";i:0;s:14:\"total_renewals\";i:0;s:8:\"earnings\";i:0;s:10:\"commission\";s:0:\"\";s:17:\"accepted_payments\";i:0;s:7:\"plan_id\";s:1:\"0\";s:4:\"type\";s:6:\"plugin\";s:10:\"public_key\";s:32:\"pk_c51e7ff51e827ecaddb23664c050d\";s:2:\"id\";s:4:\"5348\";s:7:\"created\";s:19:\"2020-01-16 15:35:45\";s:7:\"updated\";s:19:\"2020-03-27 15:47:24\";s:4:\"info\";O:8:\"stdClass\":13:{s:9:\"plugin_id\";s:4:\"5348\";s:3:\"url\";s:16:\"https://pods.io/\";s:11:\"description\";N;s:17:\"short_description\";s:124:\"Alternative caching engine for Pods for large sites on hosts with hard limits on how much you can store in the object cache.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5348/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5348/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1352\";s:7:\"created\";s:19:\"2020-01-16 15:38:46\";s:7:\"updated\";s:19:\"2020-03-18 23:02:11\";}s:12:\"premium_slug\";s:33:\"pods-simple-relationships-premium\";}i:1;O:8:\"stdClass\":38:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:12:\"developer_id\";s:4:\"6592\";s:10:\"install_id\";s:7:\"3750927\";s:4:\"slug\";s:33:\"pods-beaver-builder-themer-add-on\";s:5:\"title\";s:18:\"Pods Beaver Themer\";s:11:\"environment\";i:0;s:4:\"icon\";s:93:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5349/icons/d31c4e5dba12faa4a77e0516c3d1e4d1.png\";s:15:\"default_plan_id\";s:4:\"8671\";s:5:\"plans\";i:8671;s:8:\"features\";N;s:17:\"money_back_period\";N;s:13:\"refund_policy\";N;s:24:\"annual_renewals_discount\";N;s:22:\"renewals_discount_type\";s:0:\"\";s:11:\"is_released\";b:1;s:18:\"is_pricing_visible\";b:0;s:19:\"is_wp_org_compliant\";b:1;s:6:\"is_off\";b:0;s:24:\"is_only_for_new_installs\";b:0;s:14:\"installs_limit\";N;s:14:\"installs_count\";i:211;s:21:\"active_installs_count\";i:171;s:19:\"free_releases_count\";i:0;s:22:\"premium_releases_count\";i:0;s:15:\"total_purchases\";i:0;s:19:\"total_subscriptions\";i:0;s:14:\"total_renewals\";i:0;s:8:\"earnings\";i:0;s:10:\"commission\";s:0:\"\";s:17:\"accepted_payments\";i:0;s:7:\"plan_id\";s:1:\"0\";s:4:\"type\";s:6:\"plugin\";s:10:\"public_key\";s:32:\"pk_d8a10a25a662419add4ff3fbcc493\";s:2:\"id\";s:4:\"5349\";s:7:\"created\";s:19:\"2020-01-16 15:37:32\";s:7:\"updated\";s:19:\"2020-05-22 19:36:55\";s:4:\"info\";O:8:\"stdClass\":13:{s:9:\"plugin_id\";s:4:\"5349\";s:3:\"url\";N;s:11:\"description\";N;s:17:\"short_description\";s:94:\"Integration with Beaver Builder Themer. Provides a UI for mapping Field Connections with Pods.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5349/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5349/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1503\";s:7:\"created\";s:19:\"2020-03-18 16:27:22\";s:7:\"updated\";s:19:\"2020-03-23 13:29:21\";}s:12:\"premium_slug\";s:41:\"pods-beaver-builder-themer-add-on-premium\";}i:2;O:8:\"stdClass\":38:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:12:\"developer_id\";s:4:\"6592\";s:10:\"install_id\";s:7:\"4151395\";s:4:\"slug\";s:8:\"pods-seo\";s:5:\"title\";s:8:\"Pods SEO\";s:11:\"environment\";i:0;s:4:\"icon\";s:93:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5753/icons/1ff03cf73fa3a9d08dc342c84c3597c7.png\";s:15:\"default_plan_id\";s:4:\"9396\";s:5:\"plans\";i:9396;s:8:\"features\";N;s:17:\"money_back_period\";N;s:13:\"refund_policy\";N;s:24:\"annual_renewals_discount\";N;s:22:\"renewals_discount_type\";s:0:\"\";s:11:\"is_released\";b:1;s:18:\"is_pricing_visible\";b:0;s:19:\"is_wp_org_compliant\";b:1;s:6:\"is_off\";b:0;s:24:\"is_only_for_new_installs\";b:0;s:14:\"installs_limit\";N;s:14:\"installs_count\";i:95;s:21:\"active_installs_count\";i:82;s:19:\"free_releases_count\";i:0;s:22:\"premium_releases_count\";i:0;s:15:\"total_purchases\";i:0;s:19:\"total_subscriptions\";i:0;s:14:\"total_renewals\";i:0;s:8:\"earnings\";i:0;s:10:\"commission\";s:0:\"\";s:17:\"accepted_payments\";i:0;s:7:\"plan_id\";s:1:\"0\";s:4:\"type\";s:6:\"plugin\";s:10:\"public_key\";s:32:\"pk_46fa00cfe39af82dd1ed03033bea4\";s:2:\"id\";s:4:\"5753\";s:7:\"created\";s:19:\"2020-03-18 16:30:02\";s:7:\"updated\";s:19:\"2020-05-21 03:00:56\";s:4:\"info\";O:8:\"stdClass\":13:{s:9:\"plugin_id\";s:4:\"5753\";s:3:\"url\";N;s:11:\"description\";s:0:\"\";s:17:\"short_description\";s:114:\"Integrates with WP SEO Analysis for custom fields and Pods Advanced Content Types with WordPress SEO XML Sitemaps.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5753/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5753/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1505\";s:7:\"created\";s:19:\"2020-03-18 16:41:19\";s:7:\"updated\";s:19:\"2020-03-18 23:05:03\";}s:12:\"premium_slug\";s:16:\"pods-seo-premium\";}i:3;O:8:\"stdClass\":38:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:12:\"developer_id\";s:4:\"6592\";s:10:\"install_id\";s:7:\"4151486\";s:4:\"slug\";s:18:\"pods-gravity-forms\";s:5:\"title\";s:18:\"Pods Gravity Forms\";s:11:\"environment\";i:0;s:4:\"icon\";s:93:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5754/icons/2360aa54db6683c6e3241985d9144201.png\";s:15:\"default_plan_id\";s:4:\"9397\";s:5:\"plans\";i:9397;s:8:\"features\";N;s:17:\"money_back_period\";N;s:13:\"refund_policy\";N;s:24:\"annual_renewals_discount\";N;s:22:\"renewals_discount_type\";s:0:\"\";s:11:\"is_released\";b:1;s:18:\"is_pricing_visible\";b:0;s:19:\"is_wp_org_compliant\";b:1;s:6:\"is_off\";b:0;s:24:\"is_only_for_new_installs\";b:0;s:14:\"installs_limit\";N;s:14:\"installs_count\";i:119;s:21:\"active_installs_count\";i:81;s:19:\"free_releases_count\";i:0;s:22:\"premium_releases_count\";i:0;s:15:\"total_purchases\";i:0;s:19:\"total_subscriptions\";i:0;s:14:\"total_renewals\";i:0;s:8:\"earnings\";i:0;s:10:\"commission\";s:0:\"\";s:17:\"accepted_payments\";i:0;s:7:\"plan_id\";s:1:\"0\";s:4:\"type\";s:6:\"plugin\";s:10:\"public_key\";s:32:\"pk_1aaaee6bf8963f2077405e84f2ac5\";s:2:\"id\";s:4:\"5754\";s:7:\"created\";s:19:\"2020-03-18 16:40:29\";s:7:\"updated\";s:19:\"2020-05-22 01:35:15\";s:4:\"info\";O:8:\"stdClass\":13:{s:9:\"plugin_id\";s:4:\"5754\";s:3:\"url\";N;s:11:\"description\";N;s:17:\"short_description\";s:90:\"Integration with Gravity Forms. Provides a UI for mapping a Form\'s submissions into a Pod.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5754/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5754/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1506\";s:7:\"created\";s:19:\"2020-03-18 22:53:21\";s:7:\"updated\";s:19:\"2020-03-23 13:27:45\";}s:12:\"premium_slug\";s:26:\"pods-gravity-forms-premium\";}i:4;O:8:\"stdClass\":38:{s:16:\"parent_plugin_id\";s:4:\"5347\";s:12:\"developer_id\";s:4:\"6592\";s:10:\"install_id\";s:7:\"4151505\";s:4:\"slug\";s:15:\"pods-ajax-views\";s:5:\"title\";s:15:\"Pods AJAX Views\";s:11:\"environment\";i:0;s:4:\"icon\";s:93:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5755/icons/9c47132b38f1b2eb3faadec3886e22c7.png\";s:15:\"default_plan_id\";s:4:\"9398\";s:5:\"plans\";i:9398;s:8:\"features\";N;s:17:\"money_back_period\";N;s:13:\"refund_policy\";N;s:24:\"annual_renewals_discount\";N;s:22:\"renewals_discount_type\";s:0:\"\";s:11:\"is_released\";b:1;s:18:\"is_pricing_visible\";b:0;s:19:\"is_wp_org_compliant\";b:1;s:6:\"is_off\";b:0;s:24:\"is_only_for_new_installs\";b:0;s:14:\"installs_limit\";N;s:14:\"installs_count\";i:22;s:21:\"active_installs_count\";i:14;s:19:\"free_releases_count\";i:0;s:22:\"premium_releases_count\";i:0;s:15:\"total_purchases\";i:0;s:19:\"total_subscriptions\";i:0;s:14:\"total_renewals\";i:0;s:8:\"earnings\";i:0;s:10:\"commission\";s:0:\"\";s:17:\"accepted_payments\";i:0;s:7:\"plan_id\";s:1:\"0\";s:4:\"type\";s:6:\"plugin\";s:10:\"public_key\";s:32:\"pk_8606e36bd5153a1faf1e041342634\";s:2:\"id\";s:4:\"5755\";s:7:\"created\";s:19:\"2020-03-18 16:43:04\";s:7:\"updated\";s:19:\"2020-05-19 01:19:42\";s:4:\"info\";O:8:\"stdClass\":13:{s:9:\"plugin_id\";s:4:\"5755\";s:3:\"url\";N;s:11:\"description\";N;s:17:\"short_description\";s:81:\"An easy way to generate cached views from AJAX when they haven\'t been cached yet.\";s:10:\"banner_url\";s:61:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5755/banner.png\";s:15:\"card_banner_url\";s:66:\"//s3-us-west-2.amazonaws.com/freemius/plugins/5755/card_banner.png\";s:15:\"selling_point_0\";N;s:15:\"selling_point_1\";N;s:15:\"selling_point_2\";N;s:11:\"screenshots\";N;s:2:\"id\";s:4:\"1507\";s:7:\"created\";s:19:\"2020-03-18 22:54:20\";s:7:\"updated\";s:19:\"2020-03-18 23:00:49\";}s:12:\"premium_slug\";s:23:\"pods-ajax-views-premium\";}}}s:7:\"created\";i:1590200170;s:9:\"timestamp\";i:1590286570;}s:53:\"get:/v1/plugins/5347/addons/pricing.json?type=visible\";O:8:\"stdClass\":3:{s:6:\"result\";O:8:\"stdClass\":1:{s:6:\"addons\";a:5:{i:0;O:8:\"stdClass\":2:{s:2:\"id\";i:5348;s:5:\"plans\";a:1:{i:0;O:8:\"stdClass\":22:{s:9:\"plugin_id\";s:4:\"5348\";s:4:\"name\";s:4:\"free\";s:5:\"title\";s:20:\"Free - WordPress.org\";s:11:\"description\";N;s:17:\"is_free_localhost\";b:1;s:17:\"is_block_features\";b:1;s:25:\"is_block_features_monthly\";b:1;s:12:\"license_type\";i:0;s:16:\"is_https_support\";b:0;s:12:\"trial_period\";N;s:23:\"is_require_subscription\";b:0;s:10:\"support_kb\";N;s:13:\"support_forum\";N;s:13:\"support_email\";N;s:13:\"support_phone\";N;s:13:\"support_skype\";N;s:18:\"is_success_manager\";b:0;s:11:\"is_featured\";b:0;s:9:\"is_hidden\";b:0;s:2:\"id\";s:4:\"8670\";s:7:\"created\";s:19:\"2020-01-16 15:35:45\";s:7:\"updated\";s:19:\"2020-03-20 15:41:17\";}}}i:1;O:8:\"stdClass\":2:{s:2:\"id\";i:5349;s:5:\"plans\";a:1:{i:0;O:8:\"stdClass\":22:{s:9:\"plugin_id\";s:4:\"5349\";s:4:\"name\";s:4:\"free\";s:5:\"title\";s:20:\"Free - WordPress.org\";s:11:\"description\";N;s:17:\"is_free_localhost\";b:1;s:17:\"is_block_features\";b:1;s:25:\"is_block_features_monthly\";b:1;s:12:\"license_type\";i:0;s:16:\"is_https_support\";b:0;s:12:\"trial_period\";N;s:23:\"is_require_subscription\";b:0;s:10:\"support_kb\";N;s:13:\"support_forum\";N;s:13:\"support_email\";N;s:13:\"support_phone\";N;s:13:\"support_skype\";N;s:18:\"is_success_manager\";b:0;s:11:\"is_featured\";b:0;s:9:\"is_hidden\";b:0;s:2:\"id\";s:4:\"8671\";s:7:\"created\";s:19:\"2020-01-16 15:37:32\";s:7:\"updated\";s:19:\"2020-03-20 15:41:12\";}}}i:2;O:8:\"stdClass\":2:{s:2:\"id\";i:5753;s:5:\"plans\";a:1:{i:0;O:8:\"stdClass\":22:{s:9:\"plugin_id\";s:4:\"5753\";s:4:\"name\";s:4:\"free\";s:5:\"title\";s:20:\"Free - WordPress.org\";s:11:\"description\";N;s:17:\"is_free_localhost\";b:1;s:17:\"is_block_features\";b:1;s:25:\"is_block_features_monthly\";b:1;s:12:\"license_type\";i:0;s:16:\"is_https_support\";b:0;s:12:\"trial_period\";N;s:23:\"is_require_subscription\";b:0;s:10:\"support_kb\";N;s:13:\"support_forum\";N;s:13:\"support_email\";N;s:13:\"support_phone\";N;s:13:\"support_skype\";N;s:18:\"is_success_manager\";b:0;s:11:\"is_featured\";b:0;s:9:\"is_hidden\";b:0;s:2:\"id\";s:4:\"9396\";s:7:\"created\";s:19:\"2020-03-18 16:30:02\";s:7:\"updated\";s:19:\"2020-03-20 15:41:01\";}}}i:3;O:8:\"stdClass\":2:{s:2:\"id\";i:5754;s:5:\"plans\";a:1:{i:0;O:8:\"stdClass\":22:{s:9:\"plugin_id\";s:4:\"5754\";s:4:\"name\";s:4:\"free\";s:5:\"title\";s:20:\"Free - WordPress.org\";s:11:\"description\";N;s:17:\"is_free_localhost\";b:1;s:17:\"is_block_features\";b:1;s:25:\"is_block_features_monthly\";b:1;s:12:\"license_type\";i:0;s:16:\"is_https_support\";b:0;s:12:\"trial_period\";N;s:23:\"is_require_subscription\";b:0;s:10:\"support_kb\";N;s:13:\"support_forum\";N;s:13:\"support_email\";N;s:13:\"support_phone\";N;s:13:\"support_skype\";N;s:18:\"is_success_manager\";b:0;s:11:\"is_featured\";b:0;s:9:\"is_hidden\";b:0;s:2:\"id\";s:4:\"9397\";s:7:\"created\";s:19:\"2020-03-18 16:40:29\";s:7:\"updated\";s:19:\"2020-03-20 15:40:55\";}}}i:4;O:8:\"stdClass\":2:{s:2:\"id\";i:5755;s:5:\"plans\";a:1:{i:0;O:8:\"stdClass\":22:{s:9:\"plugin_id\";s:4:\"5755\";s:4:\"name\";s:4:\"free\";s:5:\"title\";s:20:\"Free - WordPress.org\";s:11:\"description\";N;s:17:\"is_free_localhost\";b:1;s:17:\"is_block_features\";b:1;s:25:\"is_block_features_monthly\";b:1;s:12:\"license_type\";i:0;s:16:\"is_https_support\";b:0;s:12:\"trial_period\";N;s:23:\"is_require_subscription\";b:0;s:10:\"support_kb\";N;s:13:\"support_forum\";N;s:13:\"support_email\";N;s:13:\"support_phone\";N;s:13:\"support_skype\";N;s:18:\"is_success_manager\";b:0;s:11:\"is_featured\";b:0;s:9:\"is_hidden\";b:0;s:2:\"id\";s:4:\"9398\";s:7:\"created\";s:19:\"2020-03-18 16:43:04\";s:7:\"updated\";s:19:\"2020-03-20 15:41:22\";}}}}}s:7:\"created\";i:1590200354;s:9:\"timestamp\";i:1590286754;}}','no'),(561,'recovery_mode_email_last_sent','1590200185','yes'),(4388,'_transient_pods_pods_flush_rewrites-2.8.0-a-2','0','yes'),(4389,'_transient_pods_d3f3f2dbf193b6d098445779e259a8f1','a:0:{}','yes'),(4390,'_transient_pods_d8e3ce4baa60eade66630e19e493c3f3','a:0:{}','yes'),(4391,'_transient_pods_6257e888f4b2eb6d7a9faa31ff242a69','a:0:{}','yes'),(4392,'_transient_pods_2abbf4f63ed64d5d06243f0062f3c7f2','a:0:{}','yes'),(4393,'_transient_pods_4d929249e627acffea717a3b492feed4','a:0:{}','yes'),(4394,'_transient_pods_f0757da5559454425639fbd61a4675fa','a:0:{}','yes'),(4395,'_transient_pods_e670de92c939b6764b133008488b10e9','a:0:{}','yes'),(4396,'_transient_pods_06a1e3231c43b81af22be1d5d9ee7bfe','a:0:{}','yes'),(4397,'_transient_pods_f8cfa04346654ebaa0c44a1966bb6297','a:0:{}','yes'),(4398,'_transient_pods_d7bb64029ca2a762a37cdf03e1d7cebe','a:0:{}','yes'),(4399,'_transient_pods_6bf8bd579588e35a82b0fc03fcad66b7','a:0:{}','yes'),(4400,'_transient_pods_70a494d6af75e0f22584985e31900f24','a:0:{}','yes'),(4401,'_transient_pods_67c162dbe811ff8a4d2054759e9d0022','a:0:{}','yes'),(4402,'_transient_pods_bc31950aca724d03e721ac1d37cc7c4f','a:1:{i:0;i:94;}','yes'),(4403,'_transient_timeout_pods_pods_components_refresh-2.8.0-a-2','1590243532','no'),(4404,'_transient_pods_pods_components_refresh-2.8.0-a-2','1','no'),(4405,'_transient_pods_pods_components-2.8.0-a-2','a:12:{s:22:\"advanced-content-types\";a:25:{s:2:\"ID\";s:22:\"advanced-content-types\";s:4:\"Name\";s:22:\"Advanced Content Types\";s:9:\"ShortName\";s:22:\"Advanced Content Types\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:22:\"Advanced Content Types\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:252:\"A content type that exists outside of the WordPress post and postmeta table and uses custom tables instead. You most likely don\'t need these and we strongly recommend that you use Custom Post Types or Custom Taxonomies instead. FOR ADVANCED USERS ONLY.\";s:7:\"Version\";s:3:\"2.3\";s:8:\"Category\";s:8:\"Advanced\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:27:\"Pods_Advanced_Content_Types\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:26:\"Advanced-Content-Types.php\";}s:22:\"advanced-relationships\";a:25:{s:2:\"ID\";s:22:\"advanced-relationships\";s:4:\"Name\";s:22:\"Advanced Relationships\";s:9:\"ShortName\";s:22:\"Advanced Relationships\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:22:\"Advanced Relationships\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:187:\"Add advanced relationship objects for relating to including Database Tables, Multisite Networks, Multisite Sites, Themes, Page Templates, Sidebars, Post Type Objects, and Taxonomy Objects\";s:7:\"Version\";s:3:\"2.3\";s:8:\"Category\";s:8:\"Advanced\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:27:\"Pods_Advanced_Relationships\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:26:\"Advanced-Relationships.php\";}s:19:\"builder-integration\";a:25:{s:2:\"ID\";s:19:\"builder-integration\";s:4:\"Name\";s:19:\"Builder Integration\";s:9:\"ShortName\";s:19:\"Builder Integration\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:19:\"Builder Integration\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:169:\"Integration with the Builder theme / child themes from iThemes; Adds new modules to the Layout engine\";s:7:\"Version\";s:3:\"1.0\";s:8:\"Category\";s:11:\"Integration\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:12:\"Pods_Builder\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:29:\"pods-builder/pods-builder.php\";s:8:\"External\";b:0;s:4:\"File\";s:19:\"Builder/Builder.php\";}s:7:\"helpers\";a:25:{s:2:\"ID\";s:7:\"helpers\";s:4:\"Name\";s:7:\"Helpers\";s:9:\"ShortName\";s:7:\"Helpers\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:7:\"Helpers\";s:8:\"MenuPage\";s:31:\"edit.php?post_type=_pods_helper\";s:11:\"MenuAddPage\";s:35:\"post-new.php?post_type=_pods_helper\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:156:\"A holdover from Pods 1.x for backwards compatibility purposes, you most likely don\'t need these and we recommend you use our WP filters and actions instead.\";s:7:\"Version\";s:3:\"2.3\";s:8:\"Category\";s:8:\"Advanced\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:12:\"Pods_Helpers\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:11:\"Helpers.php\";}s:15:\"markdown-syntax\";a:25:{s:2:\"ID\";s:15:\"markdown-syntax\";s:4:\"Name\";s:15:\"Markdown Syntax\";s:9:\"ShortName\";s:15:\"Markdown Syntax\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:15:\"Markdown Syntax\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:138:\"Integration with Markdown (http://michelf.com/projects/php-markdown/); Adds an option to enable Markdown syntax for Paragraph text fields.\";s:7:\"Version\";s:3:\"1.0\";s:8:\"Category\";s:11:\"Field Types\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:13:\"Pods_Markdown\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:12:\"Markdown.php\";}s:50:\"migrate-import-from-the-custom-post-type-ui-plugin\";a:25:{s:2:\"ID\";s:50:\"migrate-import-from-the-custom-post-type-ui-plugin\";s:4:\"Name\";s:51:\"Migrate: Import from the Custom Post Type UI plugin\";s:9:\"ShortName\";s:51:\"Migrate: Import from the Custom Post Type UI plugin\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:14:\"Migrate CPT UI\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:186:\"Import Custom Post Types and Taxonomies from Custom Post Type UI (http://webdevstudios.com/plugin/custom-post-type-ui/)\";s:7:\"Version\";s:3:\"1.0\";s:8:\"Category\";s:9:\"Migration\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:18:\"Pods_Migrate_CPTUI\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:69:\"pods-migrate-custom-post-type-ui/pods-migrate-custom-post-type-ui.php\";s:8:\"External\";b:0;s:4:\"File\";s:31:\"Migrate-CPTUI/Migrate-CPTUI.php\";}s:16:\"migrate-packages\";a:25:{s:2:\"ID\";s:16:\"migrate-packages\";s:4:\"Name\";s:17:\"Migrate: Packages\";s:9:\"ShortName\";s:17:\"Migrate: Packages\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:16:\"Migrate Packages\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:121:\"Import/Export your Pods, Fields, and other settings from any Pods site; Includes an API to Import/Export Packages via PHP\";s:7:\"Version\";s:3:\"2.0\";s:8:\"Category\";s:9:\"Migration\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:21:\"Pods_Migrate_Packages\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:47:\"pods-migrate-packages/pods-migrate-packages.php\";s:8:\"External\";b:0;s:4:\"File\";s:37:\"Migrate-Packages/Migrate-Packages.php\";}s:5:\"pages\";a:25:{s:2:\"ID\";s:5:\"pages\";s:4:\"Name\";s:5:\"Pages\";s:9:\"ShortName\";s:5:\"Pages\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:9:\"Pod Pages\";s:8:\"MenuPage\";s:29:\"edit.php?post_type=_pods_page\";s:11:\"MenuAddPage\";s:33:\"post-new.php?post_type=_pods_page\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:170:\"Creates advanced URL structures using wildcards in order to enable the front-end display of Pods Advanced Content Types. Not recommended for use with other content types.\";s:7:\"Version\";s:3:\"2.3\";s:8:\"Category\";s:8:\"Advanced\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:10:\"Pods_Pages\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:9:\"Pages.php\";}s:22:\"roles-and-capabilities\";a:25:{s:2:\"ID\";s:22:\"roles-and-capabilities\";s:4:\"Name\";s:22:\"Roles and Capabilities\";s:9:\"ShortName\";s:22:\"Roles and Capabilities\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:24:\"Roles & Capabilities\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:327:\"Create and Manage WordPress User Roles and Capabilities; Uses the \'Members\' plugin filters for additional plugin integrations; Portions of code based on the \'Members\' plugin by Justin Tadlock\";s:7:\"Version\";s:3:\"1.0\";s:8:\"Category\";s:5:\"Tools\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:10:\"Pods_Roles\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:15:\"Roles/Roles.php\";}s:13:\"table-storage\";a:25:{s:2:\"ID\";s:13:\"table-storage\";s:4:\"Name\";s:13:\"Table Storage\";s:9:\"ShortName\";s:13:\"Table Storage\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:13:\"Table Storage\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:108:\"Enable a custom database table for your custom fields on Post Types, Media, Taxonomies, Users, and Comments.\";s:7:\"Version\";s:3:\"2.3\";s:8:\"Category\";s:8:\"Advanced\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:18:\"Pods_Table_Storage\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:17:\"Table-Storage.php\";}s:9:\"templates\";a:25:{s:2:\"ID\";s:9:\"templates\";s:4:\"Name\";s:9:\"Templates\";s:9:\"ShortName\";s:9:\"Templates\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:13:\"Pod Templates\";s:8:\"MenuPage\";s:33:\"edit.php?post_type=_pods_template\";s:11:\"MenuAddPage\";s:37:\"post-new.php?post_type=_pods_template\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:114:\"An easy to use templating engine for Pods. Use {@field_name} magic tags to output values, within your HTML markup.\";s:7:\"Version\";s:3:\"2.3\";s:8:\"Category\";s:8:\"Advanced\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:14:\"Pods_Templates\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:23:\"Templates/Templates.php\";}s:20:\"translate-pods-admin\";a:25:{s:2:\"ID\";s:20:\"translate-pods-admin\";s:4:\"Name\";s:20:\"Translate Pods Admin\";s:9:\"ShortName\";s:20:\"Translate Pods Admin\";s:10:\"PluginName\";s:0:\"\";s:13:\"ComponentName\";s:0:\"\";s:3:\"URI\";s:0:\"\";s:8:\"MenuName\";s:14:\"Translate Pods\";s:8:\"MenuPage\";s:0:\"\";s:11:\"MenuAddPage\";s:0:\"\";s:7:\"MustUse\";b:0;s:11:\"Description\";s:45:\"Allow UI of Pods and fields to be translated.\";s:7:\"Version\";s:3:\"0.2\";s:8:\"Category\";s:4:\"I18n\";s:6:\"Author\";s:0:\"\";s:9:\"AuthorURI\";s:0:\"\";s:5:\"Class\";s:19:\"Pods_Component_I18n\";s:4:\"Hide\";s:0:\"\";s:16:\"PluginDependency\";s:0:\"\";s:15:\"ThemeDependency\";s:0:\"\";s:13:\"DeveloperMode\";b:0;s:13:\"TablelessMode\";b:0;s:10:\"Capability\";s:0:\"\";s:6:\"Plugin\";s:0:\"\";s:8:\"External\";b:0;s:4:\"File\";s:13:\"I18n/I18n.php\";}}','yes'),(4406,'_transient_pods_16546edc9291871bba553734d9791a37','a:1:{i:0;i:122;}','yes'),(4407,'_transient_pods_32f5dc2300b999157ea784c42359519e','a:5:{i:0;i:40;i:1;i:31;i:2;i:22;i:3;i:4;i:4;i:13;}','yes'),(4408,'_transient_pods_8a31d4418646774f33e601bcf23f3a19','a:5:{i:0;i:67;i:1;i:85;i:2;i:76;i:3;i:58;i:4;i:49;}','yes'),(4409,'_transient_pods_e123a7266ace4ce22223bdf5df4f36f4','a:1:{i:0;i:104;}','yes'),(4410,'_transient_pods_aecb74c5f952fbf85fd5e50c73e40e6e','a:1:{i:0;i:94;}','yes'),(4411,'_transient_pods_2b39f8d384c5bf63370d3d1e71ee6344','a:1:{i:0;i:113;}','yes'),(4412,'_transient_pods_5a922685571b22d70f386b881c54f56b','a:0:{}','yes'),(4413,'_transient_pods_74fa6c0eea365b55b84bb73dee18e477','a:8:{i:0;i:68;i:1;i:69;i:2;i:70;i:3;i:71;i:4;i:72;i:5;i:73;i:6;i:74;i:7;i:75;}','yes'),(4414,'_transient_pods_def7d0d7fb5d41821060d3ea228197c2','a:8:{i:0;i:86;i:1;i:87;i:2;i:88;i:3;i:89;i:4;i:90;i:5;i:91;i:6;i:92;i:7;i:93;}','yes'),(4415,'_transient_pods_a81a5a6708801502d1e0bbdc64a954ee','a:8:{i:0;i:77;i:1;i:78;i:2;i:79;i:3;i:80;i:4;i:81;i:5;i:82;i:6;i:83;i:7;i:84;}','yes'),(4416,'_transient_pods_509e8c6851fdb3bf6b6571f4e412861c','a:8:{i:0;i:59;i:1;i:60;i:2;i:61;i:3;i:62;i:4;i:63;i:5;i:64;i:6;i:65;i:7;i:66;}','yes'),(4417,'_transient_pods_ad509c339c37a1f2454202f049fb6f60','a:8:{i:0;i:50;i:1;i:51;i:2;i:52;i:3;i:53;i:4;i:54;i:5;i:55;i:6;i:56;i:7;i:57;}','yes'),(4418,'_transient_pods_pods_wp_cpt_ct-2.8.0-a-2','a:3:{s:10:\"post_types\";a:2:{s:14:\"test_post_meta\";a:20:{s:5:\"label\";s:14:\"test_post_meta\";s:6:\"labels\";a:34:{s:4:\"name\";s:14:\"test_post_meta\";s:13:\"singular_name\";s:14:\"Test Post Meta\";s:9:\"menu_name\";s:0:\"\";s:14:\"name_admin_bar\";s:0:\"\";s:7:\"add_new\";s:0:\"\";s:12:\"add_new_item\";s:0:\"\";s:8:\"new_item\";s:0:\"\";s:4:\"edit\";s:0:\"\";s:9:\"edit_item\";s:0:\"\";s:4:\"view\";s:0:\"\";s:9:\"view_item\";s:0:\"\";s:10:\"view_items\";s:0:\"\";s:9:\"all_items\";s:0:\"\";s:12:\"search_items\";s:0:\"\";s:9:\"not_found\";s:0:\"\";s:18:\"not_found_in_trash\";s:0:\"\";s:6:\"parent\";s:0:\"\";s:17:\"parent_item_colon\";s:0:\"\";s:8:\"archives\";s:0:\"\";s:10:\"attributes\";s:0:\"\";s:16:\"insert_into_item\";s:0:\"\";s:21:\"uploaded_to_this_item\";s:0:\"\";s:14:\"featured_image\";s:0:\"\";s:18:\"set_featured_image\";s:0:\"\";s:21:\"remove_featured_image\";s:0:\"\";s:18:\"use_featured_image\";s:0:\"\";s:17:\"filter_items_list\";s:0:\"\";s:21:\"items_list_navigation\";s:0:\"\";s:10:\"items_list\";s:0:\"\";s:14:\"item_published\";s:0:\"\";s:24:\"item_published_privately\";s:0:\"\";s:22:\"item_reverted_to_draft\";s:0:\"\";s:14:\"item_scheduled\";s:0:\"\";s:12:\"item_updated\";s:0:\"\";}s:11:\"description\";s:0:\"\";s:6:\"public\";b:1;s:18:\"publicly_queryable\";b:1;s:19:\"exclude_from_search\";b:0;s:7:\"show_ui\";b:1;s:12:\"show_in_menu\";b:1;s:17:\"show_in_nav_menus\";b:1;s:17:\"show_in_admin_bar\";b:1;s:9:\"menu_icon\";N;s:15:\"capability_type\";s:4:\"post\";s:12:\"map_meta_cap\";b:1;s:12:\"hierarchical\";b:0;s:8:\"supports\";b:0;s:11:\"has_archive\";b:0;s:7:\"rewrite\";a:4:{s:4:\"slug\";s:14:\"test-post-meta\";s:10:\"with_front\";b:1;s:5:\"feeds\";b:0;s:5:\"pages\";b:1;}s:9:\"query_var\";s:14:\"test_post_meta\";s:10:\"can_export\";b:1;s:10:\"taxonomies\";a:2:{i:0;s:8:\"category\";i:1;s:8:\"post_tag\";}}s:15:\"test_post_table\";a:20:{s:5:\"label\";s:15:\"test_post_table\";s:6:\"labels\";a:34:{s:4:\"name\";s:15:\"test_post_table\";s:13:\"singular_name\";s:15:\"Test Post Table\";s:9:\"menu_name\";s:0:\"\";s:14:\"name_admin_bar\";s:0:\"\";s:7:\"add_new\";s:0:\"\";s:12:\"add_new_item\";s:0:\"\";s:8:\"new_item\";s:0:\"\";s:4:\"edit\";s:0:\"\";s:9:\"edit_item\";s:0:\"\";s:4:\"view\";s:0:\"\";s:9:\"view_item\";s:0:\"\";s:10:\"view_items\";s:0:\"\";s:9:\"all_items\";s:0:\"\";s:12:\"search_items\";s:0:\"\";s:9:\"not_found\";s:0:\"\";s:18:\"not_found_in_trash\";s:0:\"\";s:6:\"parent\";s:0:\"\";s:17:\"parent_item_colon\";s:0:\"\";s:8:\"archives\";s:0:\"\";s:10:\"attributes\";s:0:\"\";s:16:\"insert_into_item\";s:0:\"\";s:21:\"uploaded_to_this_item\";s:0:\"\";s:14:\"featured_image\";s:0:\"\";s:18:\"set_featured_image\";s:0:\"\";s:21:\"remove_featured_image\";s:0:\"\";s:18:\"use_featured_image\";s:0:\"\";s:17:\"filter_items_list\";s:0:\"\";s:21:\"items_list_navigation\";s:0:\"\";s:10:\"items_list\";s:0:\"\";s:14:\"item_published\";s:0:\"\";s:24:\"item_published_privately\";s:0:\"\";s:22:\"item_reverted_to_draft\";s:0:\"\";s:14:\"item_scheduled\";s:0:\"\";s:12:\"item_updated\";s:0:\"\";}s:11:\"description\";s:0:\"\";s:6:\"public\";b:1;s:18:\"publicly_queryable\";b:1;s:19:\"exclude_from_search\";b:0;s:7:\"show_ui\";b:1;s:12:\"show_in_menu\";b:1;s:17:\"show_in_nav_menus\";b:1;s:17:\"show_in_admin_bar\";b:1;s:9:\"menu_icon\";N;s:15:\"capability_type\";s:4:\"post\";s:12:\"map_meta_cap\";b:1;s:12:\"hierarchical\";b:0;s:8:\"supports\";b:0;s:11:\"has_archive\";b:0;s:7:\"rewrite\";a:4:{s:4:\"slug\";s:15:\"test-post-table\";s:10:\"with_front\";b:1;s:5:\"feeds\";b:0;s:5:\"pages\";b:1;}s:9:\"query_var\";s:15:\"test_post_table\";s:10:\"can_export\";b:1;s:10:\"taxonomies\";a:2:{i:0;s:8:\"category\";i:1;s:8:\"post_tag\";}}}s:10:\"taxonomies\";a:2:{s:13:\"test_tax_meta\";a:2:{s:10:\"post_types\";a:3:{i:0;s:4:\"post\";i:1;s:4:\"page\";i:2;s:13:\"nav_menu_item\";}s:7:\"options\";a:17:{s:5:\"label\";s:13:\"test_tax_meta\";s:6:\"labels\";a:20:{s:4:\"name\";s:13:\"test_tax_meta\";s:13:\"singular_name\";s:13:\"Test Tax Meta\";s:9:\"menu_name\";s:0:\"\";s:12:\"search_items\";s:0:\"\";s:13:\"popular_items\";s:0:\"\";s:9:\"all_items\";s:0:\"\";s:11:\"parent_item\";s:0:\"\";s:17:\"parent_item_colon\";s:0:\"\";s:9:\"edit_item\";s:0:\"\";s:11:\"update_item\";s:0:\"\";s:9:\"view_item\";s:0:\"\";s:12:\"add_new_item\";s:0:\"\";s:13:\"new_item_name\";s:0:\"\";s:26:\"separate_items_with_commas\";s:0:\"\";s:19:\"add_or_remove_items\";s:0:\"\";s:21:\"choose_from_most_used\";s:0:\"\";s:9:\"not_found\";s:0:\"\";s:8:\"no_terms\";s:0:\"\";s:10:\"items_list\";s:0:\"\";s:21:\"items_list_navigation\";s:0:\"\";}s:11:\"description\";s:0:\"\";s:6:\"public\";b:1;s:7:\"show_ui\";b:1;s:12:\"show_in_menu\";b:1;s:17:\"show_in_nav_menus\";b:1;s:13:\"show_tagcloud\";b:1;s:21:\"show_tagcloud_in_edit\";b:1;s:18:\"show_in_quick_edit\";b:1;s:12:\"hierarchical\";b:0;s:12:\"capabilities\";a:0:{}s:21:\"update_count_callback\";N;s:9:\"query_var\";s:13:\"test_tax_meta\";s:7:\"rewrite\";a:3:{s:4:\"slug\";s:13:\"test-tax-meta\";s:10:\"with_front\";b:1;s:12:\"hierarchical\";b:0;}s:17:\"show_admin_column\";b:0;s:4:\"sort\";b:0;}}s:14:\"test_tax_table\";a:2:{s:10:\"post_types\";a:3:{i:0;s:4:\"post\";i:1;s:4:\"page\";i:2;s:13:\"nav_menu_item\";}s:7:\"options\";a:17:{s:5:\"label\";s:14:\"test_tax_table\";s:6:\"labels\";a:20:{s:4:\"name\";s:14:\"test_tax_table\";s:13:\"singular_name\";s:14:\"Test Tax Table\";s:9:\"menu_name\";s:0:\"\";s:12:\"search_items\";s:0:\"\";s:13:\"popular_items\";s:0:\"\";s:9:\"all_items\";s:0:\"\";s:11:\"parent_item\";s:0:\"\";s:17:\"parent_item_colon\";s:0:\"\";s:9:\"edit_item\";s:0:\"\";s:11:\"update_item\";s:0:\"\";s:9:\"view_item\";s:0:\"\";s:12:\"add_new_item\";s:0:\"\";s:13:\"new_item_name\";s:0:\"\";s:26:\"separate_items_with_commas\";s:0:\"\";s:19:\"add_or_remove_items\";s:0:\"\";s:21:\"choose_from_most_used\";s:0:\"\";s:9:\"not_found\";s:0:\"\";s:8:\"no_terms\";s:0:\"\";s:10:\"items_list\";s:0:\"\";s:21:\"items_list_navigation\";s:0:\"\";}s:11:\"description\";s:0:\"\";s:6:\"public\";b:1;s:7:\"show_ui\";b:1;s:12:\"show_in_menu\";b:1;s:17:\"show_in_nav_menus\";b:1;s:13:\"show_tagcloud\";b:1;s:21:\"show_tagcloud_in_edit\";b:1;s:18:\"show_in_quick_edit\";b:1;s:12:\"hierarchical\";b:0;s:12:\"capabilities\";a:0:{}s:21:\"update_count_callback\";N;s:9:\"query_var\";s:14:\"test_tax_table\";s:7:\"rewrite\";a:3:{s:4:\"slug\";s:14:\"test-tax-table\";s:10:\"with_front\";b:1;s:12:\"hierarchical\";b:0;}s:17:\"show_admin_column\";b:0;s:4:\"sort\";b:0;}}}s:22:\"post_format_post_types\";a:0:{}}','yes'),(4419,'_transient_pods_f90d7b2b1768bc020161be62346c847a','a:1:{i:0;i:94;}','yes'),(4420,'_transient_pods_6363637a141d5e41f644c99aa719e27e','a:9:{i:0;i:95;i:1;i:96;i:2;i:97;i:3;i:98;i:4;i:99;i:5;i:100;i:6;i:101;i:7;i:102;i:8;i:103;}','yes'),(4421,'_transient_pods_5dcea886f28bd6ed937998e4ff66d864','a:8:{s:2:\"ID\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:2:\"ID\";s:5:\"label\";s:2:\"ID\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:6:\"number\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:1:{s:13:\"number_format\";s:7:\"9999.99\";}s:5:\"alias\";a:1:{i:0;s:2:\"id\";}}s:10:\"user_login\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:10:\"user_login\";s:5:\"label\";s:5:\"Title\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:1:{s:8:\"required\";i:1;}s:5:\"alias\";a:1:{i:0;s:5:\"login\";}}s:13:\"user_nicename\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:13:\"user_nicename\";s:5:\"label\";s:9:\"Permalink\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"slug\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:3:{i:0;s:8:\"nicename\";i:1;s:4:\"slug\";i:2;s:9:\"permalink\";}}s:12:\"display_name\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:12:\"display_name\";s:5:\"label\";s:12:\"Display Name\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:2:{i:0;s:5:\"title\";i:1;s:4:\"name\";}}s:9:\"user_pass\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:9:\"user_pass\";s:5:\"label\";s:8:\"Password\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:2:{s:8:\"required\";i:1;s:16:\"text_format_type\";s:8:\"password\";}s:5:\"alias\";a:2:{i:0;s:8:\"password\";i:1;s:4:\"pass\";}}s:10:\"user_email\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:10:\"user_email\";s:5:\"label\";s:6:\"E-mail\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:2:{s:8:\"required\";i:1;s:16:\"text_format_type\";s:5:\"email\";}s:5:\"alias\";a:1:{i:0;s:5:\"email\";}}s:8:\"user_url\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:8:\"user_url\";s:5:\"label\";s:3:\"URL\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:3:{s:8:\"required\";i:0;s:16:\"text_format_type\";s:7:\"website\";s:19:\"text_format_website\";s:6:\"normal\";}s:5:\"alias\";a:2:{i:0;s:3:\"url\";i:1;s:7:\"website\";}}s:15:\"user_registered\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:15:\"user_registered\";s:5:\"label\";s:17:\"Registration Date\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"date\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:1:{s:16:\"date_format_type\";s:8:\"datetime\";}s:5:\"alias\";a:3:{i:0;s:7:\"created\";i:1;s:4:\"date\";i:2;s:10:\"registered\";}}}','yes'),(4422,'_transient_pods_pods_field_types-2.8.0-a-2','a:20:{s:4:\"text\";a:7:{s:5:\"group\";s:4:\"Text\";s:4:\"type\";s:4:\"text\";s:5:\"label\";s:10:\"Plain Text\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:7:\"website\";a:7:{s:5:\"group\";s:4:\"Text\";s:4:\"type\";s:7:\"website\";s:5:\"label\";s:7:\"Website\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:5:\"phone\";a:7:{s:5:\"group\";s:4:\"Text\";s:4:\"type\";s:5:\"phone\";s:5:\"label\";s:5:\"Phone\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:5:\"email\";a:7:{s:5:\"group\";s:4:\"Text\";s:4:\"type\";s:5:\"email\";s:5:\"label\";s:6:\"E-mail\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:8:\"password\";a:7:{s:5:\"group\";s:4:\"Text\";s:4:\"type\";s:8:\"password\";s:5:\"label\";s:8:\"Password\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:9:\"paragraph\";a:7:{s:5:\"group\";s:9:\"Paragraph\";s:4:\"type\";s:9:\"paragraph\";s:5:\"label\";s:20:\"Plain Paragraph Text\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:7:\"wysiwyg\";a:7:{s:5:\"group\";s:9:\"Paragraph\";s:4:\"type\";s:7:\"wysiwyg\";s:5:\"label\";s:23:\"WYSIWYG (Visual Editor)\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:4:\"code\";a:7:{s:5:\"group\";s:9:\"Paragraph\";s:4:\"type\";s:4:\"code\";s:5:\"label\";s:26:\"Code (Syntax Highlighting)\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:8:\"datetime\";a:9:{s:5:\"group\";s:11:\"Date / Time\";s:4:\"type\";s:8:\"datetime\";s:5:\"label\";s:11:\"Date / Time\";s:7:\"prepare\";s:2:\"%s\";s:14:\"storage_format\";s:11:\"Y-m-d H:i:s\";s:11:\"empty_value\";s:19:\"0000-00-00 00:00:00\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:4:\"date\";a:9:{s:5:\"group\";s:11:\"Date / Time\";s:4:\"type\";s:4:\"date\";s:5:\"label\";s:4:\"Date\";s:7:\"prepare\";s:2:\"%s\";s:14:\"storage_format\";s:5:\"Y-m-d\";s:11:\"empty_value\";s:10:\"0000-00-00\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:4:\"time\";a:9:{s:5:\"group\";s:11:\"Date / Time\";s:4:\"type\";s:4:\"time\";s:5:\"label\";s:4:\"Time\";s:7:\"prepare\";s:2:\"%s\";s:14:\"storage_format\";s:5:\"H:i:s\";s:11:\"empty_value\";s:0:\"\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:6:\"number\";a:7:{s:5:\"group\";s:6:\"Number\";s:4:\"type\";s:6:\"number\";s:5:\"label\";s:12:\"Plain Number\";s:7:\"prepare\";s:2:\"%d\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:8:\"currency\";a:8:{s:5:\"group\";s:6:\"Number\";s:4:\"type\";s:8:\"currency\";s:5:\"label\";s:8:\"Currency\";s:7:\"prepare\";s:2:\"%d\";s:10:\"currencies\";a:34:{s:3:\"aud\";a:4:{s:5:\"label\";s:3:\"AUD\";s:4:\"name\";s:17:\"Australian Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"brl\";a:4:{s:5:\"label\";s:3:\"BRL\";s:4:\"name\";s:14:\"Brazilian Real\";s:4:\"sign\";s:2:\"R$\";s:6:\"entity\";s:6:\"R$\";}s:3:\"cad\";a:4:{s:5:\"label\";s:3:\"CAD\";s:4:\"name\";s:15:\"Canadian Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"chf\";a:4:{s:5:\"label\";s:3:\"CHF\";s:4:\"name\";s:11:\"Swiss Franc\";s:4:\"sign\";s:2:\"Fr\";s:6:\"entity\";s:2:\"Fr\";}s:3:\"cny\";a:4:{s:5:\"label\";s:3:\"CNY\";s:4:\"name\";s:16:\"Chinese Yen (ยฅ)\";s:4:\"sign\";s:2:\"ยฅ\";s:6:\"entity\";s:5:\"¥\";}s:4:\"cny2\";a:4:{s:5:\"label\";s:3:\"CNY\";s:4:\"name\";s:18:\"Chinese Yuan (ๅ…ƒ)\";s:4:\"sign\";s:3:\"ๅ…ƒ\";s:6:\"entity\";s:8:\"元\";}s:3:\"czk\";a:4:{s:5:\"label\";s:3:\"CZK\";s:4:\"name\";s:12:\"Czech Koruna\";s:4:\"sign\";s:3:\"Kฤ\";s:6:\"entity\";s:8:\"Kč\";}s:3:\"dkk\";a:4:{s:5:\"label\";s:3:\"DKK\";s:4:\"name\";s:12:\"Danish Krone\";s:4:\"sign\";s:3:\"kr.\";s:6:\"entity\";s:3:\"kr.\";}s:4:\"euro\";a:4:{s:5:\"label\";s:3:\"EUR\";s:4:\"name\";s:4:\"Euro\";s:4:\"sign\";s:3:\"โ‚ฌ\";s:6:\"entity\";s:6:\"€\";}s:3:\"gbp\";a:4:{s:5:\"label\";s:3:\"GBP\";s:4:\"name\";s:13:\"British Pound\";s:4:\"sign\";s:2:\"ยฃ\";s:6:\"entity\";s:7:\"£\";}s:3:\"hkd\";a:4:{s:5:\"label\";s:3:\"HKD\";s:4:\"name\";s:16:\"Hong Kong Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"huf\";a:4:{s:5:\"label\";s:3:\"HUF\";s:4:\"name\";s:16:\"Hungarian Forint\";s:4:\"sign\";s:2:\"Ft\";s:6:\"entity\";s:2:\"Ft\";}s:3:\"idr\";a:4:{s:5:\"label\";s:3:\"IDR\";s:4:\"name\";s:17:\"Indonesian Rupiah\";s:4:\"sign\";s:2:\"Rp\";s:6:\"entity\";s:2:\"Rp\";}s:3:\"ils\";a:4:{s:5:\"label\";s:3:\"ILS\";s:4:\"name\";s:18:\"Israeli New Sheqel\";s:4:\"sign\";s:3:\"โ‚ช\";s:6:\"entity\";s:8:\"₪\";}s:3:\"inr\";a:4:{s:5:\"label\";s:3:\"INR\";s:4:\"name\";s:12:\"Indian Rupee\";s:4:\"sign\";s:3:\"โ‚น\";s:6:\"entity\";s:8:\"₹\";}s:3:\"jpy\";a:4:{s:5:\"label\";s:3:\"JPY\";s:4:\"name\";s:12:\"Japanese Yen\";s:4:\"sign\";s:2:\"ยฅ\";s:6:\"entity\";s:5:\"¥\";}s:3:\"krw\";a:4:{s:5:\"label\";s:3:\"KRW\";s:4:\"name\";s:10:\"Korean Won\";s:4:\"sign\";s:3:\"โ‚ฉ\";s:6:\"entity\";s:7:\"₩\";}s:3:\"mxn\";a:4:{s:5:\"label\";s:3:\"MXN\";s:4:\"name\";s:12:\"Mexican Peso\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"myr\";a:4:{s:5:\"label\";s:3:\"MYR\";s:4:\"name\";s:17:\"Malaysian Ringgit\";s:4:\"sign\";s:2:\"RM\";s:6:\"entity\";s:2:\"RM\";}s:3:\"ngn\";a:4:{s:5:\"label\";s:3:\"NGN\";s:4:\"name\";s:14:\"Nigerian Naira\";s:4:\"sign\";s:3:\"โ‚ฆ\";s:6:\"entity\";s:7:\"₦\";}s:3:\"nok\";a:4:{s:5:\"label\";s:3:\"NOK\";s:4:\"name\";s:15:\"Norwegian Krone\";s:4:\"sign\";s:2:\"kr\";s:6:\"entity\";s:2:\"kr\";}s:3:\"nzd\";a:4:{s:5:\"label\";s:3:\"NZD\";s:4:\"name\";s:18:\"New Zealand Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"php\";a:4:{s:5:\"label\";s:3:\"PHP\";s:4:\"name\";s:15:\"Philippine Peso\";s:4:\"sign\";s:3:\"โ‚ฑ\";s:6:\"entity\";s:8:\"₱\";}s:3:\"pln\";a:4:{s:5:\"label\";s:3:\"PLN\";s:4:\"name\";s:13:\"Polish Zล‚oty\";s:4:\"sign\";s:3:\"zล‚\";s:6:\"entity\";s:8:\"zł\";}s:3:\"rub\";a:4:{s:5:\"label\";s:3:\"RUB\";s:4:\"name\";s:13:\"Russian Ruble\";s:4:\"sign\";s:3:\"โ‚ฝ\";s:6:\"entity\";s:7:\"₽\";}s:3:\"sek\";a:4:{s:5:\"label\";s:3:\"SEK\";s:4:\"name\";s:13:\"Swedish Krona\";s:4:\"sign\";s:2:\"kr\";s:6:\"entity\";s:2:\"kr\";}s:3:\"sgd\";a:4:{s:5:\"label\";s:3:\"SGD\";s:4:\"name\";s:16:\"Singapore Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"thb\";a:4:{s:5:\"label\";s:3:\"THB\";s:4:\"name\";s:9:\"Thai Baht\";s:4:\"sign\";s:3:\"เธฟ\";s:6:\"entity\";s:8:\"฿\";}s:3:\"trl\";a:4:{s:5:\"label\";s:3:\"TRL\";s:4:\"name\";s:12:\"Turkish Lira\";s:4:\"sign\";s:3:\"โ‚บ\";s:6:\"entity\";s:7:\"₺\";}s:3:\"twd\";a:4:{s:5:\"label\";s:3:\"TWD\";s:4:\"name\";s:17:\"Taiwan New Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:3:\"usd\";a:4:{s:5:\"label\";s:3:\"USD\";s:4:\"name\";s:9:\"US Dollar\";s:4:\"sign\";s:1:\"$\";s:6:\"entity\";s:5:\"$\";}s:7:\"usdcent\";a:4:{s:5:\"label\";s:7:\"USDCENT\";s:4:\"name\";s:14:\"US Dollar Cent\";s:4:\"sign\";s:2:\"ยข\";s:6:\"entity\";s:6:\"¢\";}s:3:\"vnd\";a:4:{s:5:\"label\";s:3:\"VND\";s:4:\"name\";s:15:\"Vietnamese Dong\";s:4:\"sign\";s:3:\"โ‚ซ\";s:6:\"entity\";s:7:\"₫\";}s:3:\"zar\";a:4:{s:5:\"label\";s:3:\"ZAR\";s:4:\"name\";s:18:\"South African Rand\";s:4:\"sign\";s:1:\"R\";s:6:\"entity\";s:1:\"R\";}}s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:4:\"file\";a:7:{s:5:\"group\";s:21:\"Relationships / Media\";s:4:\"type\";s:4:\"file\";s:5:\"label\";s:20:\"File / Image / Video\";s:10:\"deprecated\";b:0;s:7:\"prepare\";s:2:\"%s\";s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:6:\"avatar\";a:7:{s:5:\"group\";s:21:\"Relationships / Media\";s:4:\"type\";s:6:\"avatar\";s:5:\"label\";s:6:\"Avatar\";s:9:\"pod_types\";a:1:{i:0;s:4:\"user\";}s:10:\"deprecated\";b:0;s:7:\"prepare\";s:2:\"%s\";s:4:\"file\";N;}s:6:\"oembed\";a:7:{s:5:\"group\";s:21:\"Relationships / Media\";s:4:\"type\";s:6:\"oembed\";s:5:\"label\";s:6:\"oEmbed\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:4:\"pick\";a:11:{s:5:\"group\";s:21:\"Relationships / Media\";s:4:\"type\";s:4:\"pick\";s:5:\"label\";s:12:\"Relationship\";s:15:\"related_objects\";a:0:{}s:22:\"custom_related_objects\";a:0:{}s:12:\"related_data\";a:0:{}s:10:\"field_data\";a:0:{}s:10:\"deprecated\";b:0;s:7:\"prepare\";s:2:\"%s\";s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:7:\"boolean\";a:6:{s:4:\"type\";s:7:\"boolean\";s:5:\"label\";s:8:\"Yes / No\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:5:\"color\";a:6:{s:4:\"type\";s:5:\"color\";s:5:\"label\";s:12:\"Color Picker\";s:7:\"prepare\";s:2:\"%s\";s:10:\"deprecated\";b:0;s:9:\"pod_types\";b:1;s:4:\"file\";N;}s:4:\"slug\";a:6:{s:4:\"type\";s:4:\"slug\";s:5:\"label\";s:24:\"Permalink (url-friendly)\";s:7:\"prepare\";s:2:\"%s\";s:9:\"pod_types\";a:2:{i:0;s:3:\"pod\";i:1;s:5:\"table\";}s:10:\"deprecated\";b:0;s:4:\"file\";N;}}','yes'),(4423,'_transient_pods_d58f972953cc011177d47f8be26353d2','a:20:{i:0;s:4:\"text\";i:1;s:7:\"website\";i:2;s:5:\"phone\";i:3;s:5:\"email\";i:4;s:8:\"password\";i:5;s:9:\"paragraph\";i:6;s:7:\"wysiwyg\";i:7;s:4:\"code\";i:8;s:8:\"datetime\";i:9;s:4:\"date\";i:10;s:4:\"time\";i:11;s:6:\"number\";i:12;s:8:\"currency\";i:13;s:4:\"file\";i:14;s:6:\"avatar\";i:15;s:6:\"oembed\";i:16;s:4:\"pick\";i:17;s:7:\"boolean\";i:18;s:5:\"color\";i:19;s:4:\"slug\";}','yes'),(4424,'_transient_pods_45274eedd426efc307215e7df6a0a4b5','a:14:{i:0;i:67;i:1;i:113;i:2;i:104;i:3;i:85;i:4;i:40;i:5;i:31;i:6;i:22;i:7;i:76;i:8;i:122;i:9;i:4;i:10;i:13;i:11;i:58;i:12;i:49;i:13;i:94;}','yes'),(4425,'_transient_pods_c900e36cc29070f9248f157e261959bb','a:12:{i:0;i:123;i:1;i:124;i:2;i:125;i:3;i:126;i:4;i:127;i:5;i:128;i:6;i:129;i:7;i:130;i:8;i:131;i:9;i:132;i:10;i:133;i:11;i:134;}','yes'),(4426,'_transient_pods_pods_avatar_field-2.8.0-a-2','avatar','yes'),(4427,'_transient_pods_pods_related_objects-2.8.0-a-2','a:30:{s:13:\"custom-simple\";a:3:{s:5:\"label\";s:28:\"Simple (custom defined list)\";s:5:\"group\";s:6:\"Custom\";s:6:\"simple\";b:1;}s:12:\"pod-test_act\";a:3:{s:5:\"label\";s:19:\"test_act (test_act)\";s:5:\"group\";s:4:\"Pods\";s:13:\"bidirectional\";b:1;}s:20:\"post_type-custom_css\";a:3:{s:5:\"label\";s:23:\"Custom CSS (custom_css)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:29:\"post_type-customize_changeset\";a:3:{s:5:\"label\";s:32:\"Changesets (customize_changeset)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:22:\"post_type-oembed_cache\";a:3:{s:5:\"label\";s:31:\"oEmbed Responses (oembed_cache)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:14:\"post_type-page\";a:3:{s:5:\"label\";s:12:\"Pages (page)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:14:\"post_type-post\";a:3:{s:5:\"label\";s:12:\"Posts (post)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:24:\"post_type-test_post_meta\";a:3:{s:5:\"label\";s:31:\"test_post_meta (test_post_meta)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:25:\"post_type-test_post_table\";a:3:{s:5:\"label\";s:33:\"test_post_table (test_post_table)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:22:\"post_type-user_request\";a:3:{s:5:\"label\";s:28:\"User Requests (user_request)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:18:\"post_type-wp_block\";a:3:{s:5:\"label\";s:17:\"Blocks (wp_block)\";s:5:\"group\";s:10:\"Post Types\";s:13:\"bidirectional\";b:1;}s:17:\"taxonomy-category\";a:3:{s:5:\"label\";s:21:\"Categories (category)\";s:5:\"group\";s:10:\"Taxonomies\";s:13:\"bidirectional\";b:1;}s:22:\"taxonomy-link_category\";a:3:{s:5:\"label\";s:31:\"Link Categories (link_category)\";s:5:\"group\";s:10:\"Taxonomies\";s:13:\"bidirectional\";b:1;}s:17:\"taxonomy-post_tag\";a:3:{s:5:\"label\";s:15:\"Tags (post_tag)\";s:5:\"group\";s:10:\"Taxonomies\";s:13:\"bidirectional\";b:1;}s:22:\"taxonomy-test_tax_meta\";a:3:{s:5:\"label\";s:29:\"test_tax_meta (test_tax_meta)\";s:5:\"group\";s:10:\"Taxonomies\";s:13:\"bidirectional\";b:1;}s:23:\"taxonomy-test_tax_table\";a:3:{s:5:\"label\";s:31:\"test_tax_table (test_tax_table)\";s:5:\"group\";s:10:\"Taxonomies\";s:13:\"bidirectional\";b:1;}s:4:\"user\";a:3:{s:5:\"label\";s:5:\"Users\";s:5:\"group\";s:16:\"Other WP Objects\";s:13:\"bidirectional\";b:1;}s:4:\"role\";a:4:{s:5:\"label\";s:10:\"User Roles\";s:5:\"group\";s:16:\"Other WP Objects\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;O:14:\"PodsField_Pick\":0:{}i:1;s:10:\"data_roles\";}}s:10:\"capability\";a:4:{s:5:\"label\";s:17:\"User Capabilities\";s:5:\"group\";s:16:\"Other WP Objects\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:17:\"data_capabilities\";}}s:5:\"media\";a:3:{s:5:\"label\";s:5:\"Media\";s:5:\"group\";s:16:\"Other WP Objects\";s:13:\"bidirectional\";b:1;}s:7:\"comment\";a:3:{s:5:\"label\";s:8:\"Comments\";s:5:\"group\";s:16:\"Other WP Objects\";s:13:\"bidirectional\";b:1;}s:10:\"image-size\";a:4:{s:5:\"label\";s:11:\"Image Sizes\";s:5:\"group\";s:16:\"Other WP Objects\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:16:\"data_image_sizes\";}}s:8:\"nav_menu\";a:2:{s:5:\"label\";s:16:\"Navigation Menus\";s:5:\"group\";s:16:\"Other WP Objects\";}s:11:\"post_format\";a:2:{s:5:\"label\";s:12:\"Post Formats\";s:5:\"group\";s:16:\"Other WP Objects\";}s:11:\"post-status\";a:4:{s:5:\"label\";s:11:\"Post Status\";s:5:\"group\";s:16:\"Other WP Objects\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:15:\"data_post_stati\";}}s:7:\"country\";a:4:{s:5:\"label\";s:9:\"Countries\";s:5:\"group\";s:16:\"Predefined Lists\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:14:\"data_countries\";}}s:8:\"us_state\";a:4:{s:5:\"label\";s:9:\"US States\";s:5:\"group\";s:16:\"Predefined Lists\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:14:\"data_us_states\";}}s:11:\"ca_province\";a:4:{s:5:\"label\";s:12:\"CA Provinces\";s:5:\"group\";s:16:\"Predefined Lists\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:17:\"data_ca_provinces\";}}s:12:\"days_of_week\";a:4:{s:5:\"label\";s:23:\"Calendar - Days of Week\";s:5:\"group\";s:16:\"Predefined Lists\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:17:\"data_days_of_week\";}}s:14:\"months_of_year\";a:4:{s:5:\"label\";s:25:\"Calendar - Months of Year\";s:5:\"group\";s:16:\"Predefined Lists\";s:6:\"simple\";b:1;s:13:\"data_callback\";a:2:{i:0;r:75;i:1;s:19:\"data_months_of_year\";}}}','yes'),(4428,'_transient_pods_e16a778a5479b5a21e9e209655170f66','a:1:{i:0;i:103;}','yes'),(4429,'_transient_pods_4a51e4eb9251377f24974c56b6718ec6','a:1:{i:0;i:104;}','yes'),(4430,'_transient_pods_9358aa7e7044fd474c35b26f3a7ef326','a:0:{}','yes'),(4431,'_transient_pods_d3af4054de7871270b0861c73f1ae0a2','a:8:{i:0;i:105;i:1;i:106;i:2;i:107;i:3;i:108;i:4;i:109;i:5;i:110;i:6;i:111;i:7;i:112;}','yes'),(4432,'_transient_pods_272a0cf2aeaea2f7ab7270dde8ad17a7','a:24:{s:2:\"ID\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:2:\"ID\";s:5:\"label\";s:2:\"ID\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:6:\"number\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:1:{s:13:\"number_format\";s:7:\"9999.99\";}s:5:\"alias\";a:1:{i:0;s:2:\"id\";}}s:10:\"post_title\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:10:\"post_title\";s:5:\"label\";s:5:\"Title\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:2:{s:14:\"display_filter\";s:9:\"the_title\";s:19:\"display_filter_args\";a:1:{i:0;s:7:\"post_ID\";}}s:5:\"alias\";a:2:{i:0;s:5:\"title\";i:1;s:4:\"name\";}}s:12:\"post_content\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:12:\"post_content\";s:5:\"label\";s:7:\"Content\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:7:\"wysiwyg\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:3:{s:25:\"wysiwyg_allowed_html_tags\";s:0:\"\";s:14:\"display_filter\";s:11:\"the_content\";s:8:\"pre_save\";i:0;}s:5:\"alias\";a:1:{i:0;s:7:\"content\";}}s:12:\"post_excerpt\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:12:\"post_excerpt\";s:5:\"label\";s:7:\"Excerpt\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:9:\"paragraph\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:4:{s:20:\"paragraph_allow_html\";i:1;s:27:\"paragraph_allowed_html_tags\";s:0:\"\";s:14:\"display_filter\";s:11:\"the_excerpt\";s:8:\"pre_save\";i:0;}s:5:\"alias\";a:1:{i:0;s:7:\"excerpt\";}}s:11:\"post_author\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:11:\"post_author\";s:5:\"label\";s:6:\"Author\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"pick\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:3:{s:16:\"pick_format_type\";s:6:\"single\";s:18:\"pick_format_single\";s:12:\"autocomplete\";s:13:\"default_value\";s:10:\"{@user.ID}\";}s:5:\"alias\";a:1:{i:0;s:6:\"author\";}s:11:\"pick_object\";s:4:\"user\";}s:9:\"post_date\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:9:\"post_date\";s:5:\"label\";s:12:\"Publish Date\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:8:\"datetime\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:2:{i:0;s:7:\"created\";i:1;s:4:\"date\";}}s:13:\"post_date_gmt\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:13:\"post_date_gmt\";s:5:\"label\";s:18:\"Publish Date (GMT)\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:8:\"datetime\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:11:\"post_status\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:11:\"post_status\";s:5:\"label\";s:6:\"Status\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";s:5:\"draft\";s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"pick\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:11:\"pick_object\";s:11:\"post-status\";s:5:\"alias\";a:1:{i:0;s:6:\"status\";}}s:14:\"comment_status\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:14:\"comment_status\";s:5:\"label\";s:14:\"Comment Status\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";s:4:\"open\";s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:4:\"data\";a:2:{s:4:\"open\";s:4:\"Open\";s:6:\"closed\";s:6:\"Closed\";}}s:11:\"ping_status\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:11:\"ping_status\";s:5:\"label\";s:11:\"Ping Status\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";s:4:\"open\";s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:4:\"data\";a:2:{s:4:\"open\";s:4:\"Open\";s:6:\"closed\";s:6:\"Closed\";}}s:13:\"post_password\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:13:\"post_password\";s:5:\"label\";s:8:\"Password\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}}s:9:\"post_name\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:9:\"post_name\";s:5:\"label\";s:9:\"Permalink\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"slug\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:2:{i:0;s:4:\"slug\";i:1;s:9:\"permalink\";}}s:7:\"to_ping\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:7:\"to_ping\";s:5:\"label\";s:7:\"To Ping\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:6:\"pinged\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:6:\"pinged\";s:5:\"label\";s:6:\"Pinged\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:13:\"post_modified\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:13:\"post_modified\";s:5:\"label\";s:18:\"Last Modified Date\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:8:\"datetime\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:1:{i:0;s:8:\"modified\";}s:6:\"hidden\";b:1;}s:17:\"post_modified_gmt\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:17:\"post_modified_gmt\";s:5:\"label\";s:24:\"Last Modified Date (GMT)\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:8:\"datetime\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:21:\"post_content_filtered\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:21:\"post_content_filtered\";s:5:\"label\";s:18:\"Content (filtered)\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:9:\"paragraph\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:7:{s:20:\"paragraph_allow_html\";i:1;s:16:\"paragraph_oembed\";i:1;s:21:\"paragraph_wptexturize\";i:1;s:23:\"paragraph_convert_chars\";i:1;s:17:\"paragraph_wpautop\";i:1;s:25:\"paragraph_allow_shortcode\";i:1;s:27:\"paragraph_allowed_html_tags\";s:0:\"\";}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:11:\"post_parent\";a:21:{s:2:\"id\";i:0;s:4:\"name\";s:11:\"post_parent\";s:5:\"label\";s:6:\"Parent\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"pick\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:11:\"pick_object\";s:9:\"post_type\";s:8:\"pick_val\";s:11:\"__current__\";s:5:\"alias\";a:1:{i:0;s:6:\"parent\";}s:4:\"data\";a:0:{}s:6:\"hidden\";b:1;}s:4:\"guid\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:4:\"guid\";s:5:\"label\";s:4:\"GUID\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:10:\"menu_order\";a:17:{s:2:\"id\";i:0;s:4:\"name\";s:10:\"menu_order\";s:5:\"label\";s:10:\"Menu Order\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:6:\"number\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:1:{s:13:\"number_format\";s:7:\"9999.99\";}s:5:\"alias\";a:0:{}}s:9:\"post_type\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:9:\"post_type\";s:5:\"label\";s:4:\"Type\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:1:{i:0;s:4:\"type\";}s:6:\"hidden\";b:1;}s:14:\"post_mime_type\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:14:\"post_mime_type\";s:5:\"label\";s:9:\"Mime Type\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:4:\"text\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:13:\"comment_count\";a:18:{s:2:\"id\";i:0;s:4:\"name\";s:13:\"comment_count\";s:5:\"label\";s:13:\"Comment Count\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:6:\"number\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:0:{}s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}s:8:\"comments\";a:20:{s:2:\"id\";i:0;s:4:\"name\";s:8:\"comments\";s:5:\"label\";s:8:\"Comments\";s:11:\"description\";s:0:\"\";s:4:\"help\";s:0:\"\";s:7:\"default\";N;s:10:\"attributes\";a:0:{}s:5:\"class\";s:0:\"\";s:4:\"type\";s:7:\"comment\";s:5:\"group\";i:0;s:7:\"grouped\";i:0;s:14:\"developer_mode\";b:0;s:10:\"dependency\";b:0;s:10:\"depends-on\";a:0:{}s:11:\"excludes-on\";a:0:{}s:7:\"options\";a:1:{s:19:\"comment_format_type\";s:5:\"multi\";}s:11:\"pick_object\";s:7:\"comment\";s:8:\"pick_val\";s:7:\"comment\";s:5:\"alias\";a:0:{}s:6:\"hidden\";b:1;}}','yes'),(4433,'_transient_pods_711a4124d228379e55ac2c39c249ec23','a:10:{i:0;i:67;i:1;i:85;i:2;i:40;i:3;i:31;i:4;i:22;i:5;i:76;i:6;i:4;i:7;i:13;i:8;i:58;i:9;i:49;}','yes'),(4434,'_transient_pods__pods_pfat_the_pods-2.8.0-a-2','a:10:{s:8:\"category\";s:8:\"category\";s:8:\"nav_menu\";s:8:\"nav_menu\";s:13:\"nav_menu_item\";s:13:\"nav_menu_item\";s:4:\"page\";s:4:\"page\";s:4:\"post\";s:4:\"post\";s:8:\"post_tag\";s:8:\"post_tag\";s:14:\"test_post_meta\";s:14:\"test_post_meta\";s:15:\"test_post_table\";s:15:\"test_post_table\";s:13:\"test_tax_meta\";s:13:\"test_tax_meta\";s:14:\"test_tax_table\";s:14:\"test_tax_table\";}','yes'),(4435,'_transient_pods_13e3ad368f23e97c6adba9dc5bef9ec7','a:1:{i:0;i:67;}','yes'),(4436,'_transient_pods_dc7583c4f148b326dd95818b636b5522','a:1:{i:0;i:85;}','yes'),(4437,'_transient_pods_05fd903f9cebe106a3fe73c6783c0a34','a:1:{i:0;i:40;}','yes'),(4438,'_transient_pods_d7f9b90163553c35e07a194a38c18a70','a:1:{i:0;i:31;}','yes'),(4439,'_transient_pods_93c596805543f49072744e18e173d740','a:1:{i:0;i:22;}','yes'),(4440,'_transient_pods_bcffc3d64cbd1c1345e967cbcc4ee4a3','a:1:{i:0;i:76;}','yes'),(4441,'_transient_pods_442032d5d74dc0e3f2757310bbb11a25','a:1:{i:0;i:4;}','yes'),(4442,'_transient_pods_d7fff66eecf04d1363c8f959c38ee2d4','a:1:{i:0;i:13;}','yes'),(4443,'_transient_pods_fb4c81e216a550bebc02602087af4956','a:1:{i:0;i:58;}','yes'),(4444,'_transient_pods_06c56cbb27b911c25624b60bb6210e4a','a:1:{i:0;i:49;}','yes'),(4445,'_transient_pods__pods_pfat_auto_pods-2.8.0-a-2','a:0:{}','yes'),(4446,'_transient_pods_pods_pfat_archive_test-2.8.0-a-2','','yes'),(4447,'_transient_pods_3ff5e8c5e9be8bc6cc5bd442938ce904','a:1:{i:0;i:151;}','yes'),(4448,'_transient_pods_82010b520a19ff2aa38f271f7e8a27a2','a:1:{i:0;i:152;}','yes'),(4449,'_transient_pods_224d434432d07a309cdce3039581ce28','a:8:{i:0;i:114;i:1;i:115;i:2;i:116;i:3;i:117;i:4;i:118;i:5;i:119;i:6;i:120;i:7;i:121;}','yes'),(4450,'_transient_pods_037823634203f1e016a1163e56304545','a:1:{i:0;i:153;}','yes'),(4451,'_transient_pods_5b8a03fd78a909291cfb55d0dba185cd','a:1:{i:0;i:154;}','yes'),(4452,'_transient_pods_c9ad2afb8219ff9f386212eb453cd72e','a:1:{i:0;i:155;}','yes'),(4453,'_transient_pods_4d734c6d3e82a068ca01cd66f3ed8622','a:8:{i:0;i:41;i:1;i:42;i:2;i:43;i:3;i:44;i:4;i:45;i:5;i:46;i:6;i:47;i:7;i:48;}','yes'),(4454,'_transient_pods_0c22707f258a272d95b8fc520c180cd0','a:1:{i:0;i:156;}','yes'),(4455,'_transient_pods_882d3bb45ce1be4e2e9bc7ea86084394','a:8:{i:0;i:32;i:1;i:33;i:2;i:34;i:3;i:35;i:4;i:36;i:5;i:37;i:6;i:38;i:7;i:39;}','yes'),(4456,'_transient_pods_b73f3e47d692590454ef5e83821a7ce3','a:1:{i:0;i:157;}','yes'),(4457,'_transient_pods_65d8a5d84ced8e80d30449a482108a70','a:8:{i:0;i:23;i:1;i:24;i:2;i:25;i:3;i:26;i:4;i:27;i:5;i:28;i:6;i:29;i:7;i:30;}','yes'),(4458,'_transient_pods_0965c13111e8b845b6e3165ede43b346','a:1:{i:0;i:158;}','yes'),(4459,'_transient_pods_8a9ac4f3b660a95a0aa3307c6a246dc6','a:1:{i:0;i:159;}','yes'),(4460,'_transient_pods_ab58fae6286501bbee7d3912eff78168','a:1:{i:0;i:160;}','yes'),(4461,'_transient_pods_79edba29e374ab0691c487f835c2e535','a:8:{i:0;i:5;i:1;i:6;i:2;i:7;i:3;i:8;i:4;i:9;i:5;i:10;i:6;i:11;i:7;i:12;}','yes'),(4462,'_transient_pods_e60790f1d6c9b7fcd2c470b69281c659','a:1:{i:0;i:161;}','yes'),(4463,'_transient_pods_f9a94dfa91c5944eef8e4d16849e185e','a:8:{i:0;i:14;i:1;i:15;i:2;i:16;i:3;i:17;i:4;i:18;i:5;i:19;i:6;i:20;i:7;i:21;}','yes'),(4464,'_transient_pods_1b4473f931d935b2670d2105cf38f03d','a:1:{i:0;i:162;}','yes'),(4465,'_transient_pods_fc0ed079bbcc5d7a15cf56e8d45e9eb4','a:1:{i:0;i:163;}','yes'),(4466,'_transient_pods_fa5b537b9e7a536fc8b935e8d23507aa','a:1:{i:0;i:164;}','yes'),(4467,'_site_transient_timeout_available_translations','1590211174','no'),(4468,'_site_transient_available_translations','a:122:{s:2:\"af\";a:8:{s:8:\"language\";s:2:\"af\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-03-31 13:46:18\";s:12:\"english_name\";s:9:\"Afrikaans\";s:11:\"native_name\";s:9:\"Afrikaans\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/af.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"af\";i:2;s:3:\"afr\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:10:\"Gaan voort\";}}s:2:\"ar\";a:8:{s:8:\"language\";s:2:\"ar\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-15 22:11:28\";s:12:\"english_name\";s:6:\"Arabic\";s:11:\"native_name\";s:14:\"ุงู„ุนุฑุจูŠุฉ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/ar.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ar\";i:2;s:3:\"ara\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:16:\"ุงู„ู…ุชุงุจุนุฉ\";}}s:3:\"ary\";a:8:{s:8:\"language\";s:3:\"ary\";s:7:\"version\";s:5:\"4.7.7\";s:7:\"updated\";s:19:\"2017-01-26 15:42:35\";s:12:\"english_name\";s:15:\"Moroccan Arabic\";s:11:\"native_name\";s:31:\"ุงู„ุนุฑุจูŠุฉ ุงู„ู…ุบุฑุจูŠุฉ\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.7/ary.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ar\";i:3;s:3:\"ary\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:16:\"ุงู„ู…ุชุงุจุนุฉ\";}}s:2:\"as\";a:8:{s:8:\"language\";s:2:\"as\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-11-22 18:59:07\";s:12:\"english_name\";s:8:\"Assamese\";s:11:\"native_name\";s:21:\"เฆ…เฆธเฆฎเง€เฆฏเฆผเฆพ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/as.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"as\";i:2;s:3:\"asm\";i:3;s:3:\"asm\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:2:\"az\";a:8:{s:8:\"language\";s:2:\"az\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-11-06 00:09:27\";s:12:\"english_name\";s:11:\"Azerbaijani\";s:11:\"native_name\";s:16:\"Azษ™rbaycan dili\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/az.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"az\";i:2;s:3:\"aze\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:5:\"Davam\";}}s:3:\"azb\";a:8:{s:8:\"language\";s:3:\"azb\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-09-12 20:34:31\";s:12:\"english_name\";s:17:\"South Azerbaijani\";s:11:\"native_name\";s:29:\"ฺฏุคู†ุฆŒ ุขุฐุฑุจุงŒุฌุงู†\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/azb.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"az\";i:3;s:3:\"azb\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:3:\"bel\";a:8:{s:8:\"language\";s:3:\"bel\";s:7:\"version\";s:6:\"4.9.14\";s:7:\"updated\";s:19:\"2019-10-29 07:54:22\";s:12:\"english_name\";s:10:\"Belarusian\";s:11:\"native_name\";s:29:\"ะ‘ะตะปะฐั€ัƒัะบะฐั ะผะพะฒะฐ\";s:7:\"package\";s:63:\"https://downloads.wordpress.org/translation/core/4.9.14/bel.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"be\";i:2;s:3:\"bel\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:20:\"ะŸั€ะฐั†ัะณะฝัƒั†ัŒ\";}}s:5:\"bg_BG\";a:8:{s:8:\"language\";s:5:\"bg_BG\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-01-22 10:57:09\";s:12:\"english_name\";s:9:\"Bulgarian\";s:11:\"native_name\";s:18:\"ะ‘ัŠะปะณะฐั€ัะบะธ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/bg_BG.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"bg\";i:2;s:3:\"bul\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:12:\"ะะฐะฟั€ะตะด\";}}s:5:\"bn_BD\";a:8:{s:8:\"language\";s:5:\"bn_BD\";s:7:\"version\";s:6:\"4.8.13\";s:7:\"updated\";s:19:\"2017-10-01 12:57:10\";s:12:\"english_name\";s:20:\"Bengali (Bangladesh)\";s:11:\"native_name\";s:15:\"เฆฌเฆพเฆ‚เฆฒเฆพ\";s:7:\"package\";s:65:\"https://downloads.wordpress.org/translation/core/4.8.13/bn_BD.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"bn\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:23:\"เฆเฆ—เฆฟเงŸเง‡ เฆšเฆฒ.\";}}s:2:\"bo\";a:8:{s:8:\"language\";s:2:\"bo\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-16 06:26:18\";s:12:\"english_name\";s:7:\"Tibetan\";s:11:\"native_name\";s:21:\"เฝ–เฝผเฝ‘เผ‹เฝกเฝฒเฝ‚\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/bo.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"bo\";i:2;s:3:\"tib\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:33:\"เฝ˜เฝดเผ‹เฝ˜เฝเฝดเฝ‘เผ‹เฝ‘เฝดเผ\";}}s:5:\"bs_BA\";a:8:{s:8:\"language\";s:5:\"bs_BA\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-05-17 13:16:49\";s:12:\"english_name\";s:7:\"Bosnian\";s:11:\"native_name\";s:8:\"Bosanski\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/bs_BA.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"bs\";i:2;s:3:\"bos\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:7:\"Nastavi\";}}s:2:\"ca\";a:8:{s:8:\"language\";s:2:\"ca\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-21 11:17:36\";s:12:\"english_name\";s:7:\"Catalan\";s:11:\"native_name\";s:7:\"Catalร \";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/ca.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ca\";i:2;s:3:\"cat\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continua\";}}s:3:\"ceb\";a:8:{s:8:\"language\";s:3:\"ceb\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-03-02 17:25:51\";s:12:\"english_name\";s:7:\"Cebuano\";s:11:\"native_name\";s:7:\"Cebuano\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/ceb.zip\";s:3:\"iso\";a:2:{i:2;s:3:\"ceb\";i:3;s:3:\"ceb\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:7:\"Padayun\";}}s:5:\"cs_CZ\";a:8:{s:8:\"language\";s:5:\"cs_CZ\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-01-27 14:39:02\";s:12:\"english_name\";s:5:\"Czech\";s:11:\"native_name\";s:9:\"ฤŒeลกtina\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/cs_CZ.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"cs\";i:2;s:3:\"ces\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:11:\"Pokraฤovat\";}}s:2:\"cy\";a:8:{s:8:\"language\";s:2:\"cy\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-18 08:28:16\";s:12:\"english_name\";s:5:\"Welsh\";s:11:\"native_name\";s:7:\"Cymraeg\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/cy.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"cy\";i:2;s:3:\"cym\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Parhau\";}}s:5:\"da_DK\";a:8:{s:8:\"language\";s:5:\"da_DK\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-20 09:36:00\";s:12:\"english_name\";s:6:\"Danish\";s:11:\"native_name\";s:5:\"Dansk\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/da_DK.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"da\";i:2;s:3:\"dan\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Fortsรฆt\";}}s:5:\"de_AT\";a:8:{s:8:\"language\";s:5:\"de_AT\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-19 19:54:21\";s:12:\"english_name\";s:16:\"German (Austria)\";s:11:\"native_name\";s:21:\"Deutsch (ร–sterreich)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/de_AT.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"de\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Weiter\";}}s:5:\"de_CH\";a:8:{s:8:\"language\";s:5:\"de_CH\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-17 13:48:51\";s:12:\"english_name\";s:20:\"German (Switzerland)\";s:11:\"native_name\";s:17:\"Deutsch (Schweiz)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/de_CH.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"de\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Weiter\";}}s:14:\"de_CH_informal\";a:8:{s:8:\"language\";s:14:\"de_CH_informal\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-17 13:49:05\";s:12:\"english_name\";s:30:\"German (Switzerland, Informal)\";s:11:\"native_name\";s:21:\"Deutsch (Schweiz, Du)\";s:7:\"package\";s:73:\"https://downloads.wordpress.org/translation/core/5.4.1/de_CH_informal.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"de\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Weiter\";}}s:12:\"de_DE_formal\";a:8:{s:8:\"language\";s:12:\"de_DE_formal\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-14 12:24:16\";s:12:\"english_name\";s:15:\"German (Formal)\";s:11:\"native_name\";s:13:\"Deutsch (Sie)\";s:7:\"package\";s:71:\"https://downloads.wordpress.org/translation/core/5.4.1/de_DE_formal.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"de\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Weiter\";}}s:5:\"de_DE\";a:8:{s:8:\"language\";s:5:\"de_DE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-14 12:23:30\";s:12:\"english_name\";s:6:\"German\";s:11:\"native_name\";s:7:\"Deutsch\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/de_DE.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"de\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Weiter\";}}s:3:\"dzo\";a:8:{s:8:\"language\";s:3:\"dzo\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-06-29 08:59:03\";s:12:\"english_name\";s:8:\"Dzongkha\";s:11:\"native_name\";s:18:\"เฝขเพซเฝผเฝ„เผ‹เฝ\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/dzo.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"dz\";i:2;s:3:\"dzo\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:2:\"el\";a:8:{s:8:\"language\";s:2:\"el\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-14 16:44:30\";s:12:\"english_name\";s:5:\"Greek\";s:11:\"native_name\";s:16:\"ฮ•ฮปฮปฮทฮฝฮนฮบฮฌ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/el.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"el\";i:2;s:3:\"ell\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:16:\"ฮฃฯ…ฮฝฮญฯ‡ฮตฮนฮฑ\";}}s:5:\"en_ZA\";a:8:{s:8:\"language\";s:5:\"en_ZA\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-14 11:33:37\";s:12:\"english_name\";s:22:\"English (South Africa)\";s:11:\"native_name\";s:22:\"English (South Africa)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/en_ZA.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"en\";i:2;s:3:\"eng\";i:3;s:3:\"eng\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:5:\"en_CA\";a:8:{s:8:\"language\";s:5:\"en_CA\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-08 05:34:29\";s:12:\"english_name\";s:16:\"English (Canada)\";s:11:\"native_name\";s:16:\"English (Canada)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/en_CA.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"en\";i:2;s:3:\"eng\";i:3;s:3:\"eng\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:5:\"en_NZ\";a:8:{s:8:\"language\";s:5:\"en_NZ\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-03-31 22:29:33\";s:12:\"english_name\";s:21:\"English (New Zealand)\";s:11:\"native_name\";s:21:\"English (New Zealand)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/en_NZ.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"en\";i:2;s:3:\"eng\";i:3;s:3:\"eng\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:5:\"en_AU\";a:8:{s:8:\"language\";s:5:\"en_AU\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-03-30 09:33:04\";s:12:\"english_name\";s:19:\"English (Australia)\";s:11:\"native_name\";s:19:\"English (Australia)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/en_AU.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"en\";i:2;s:3:\"eng\";i:3;s:3:\"eng\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:5:\"en_GB\";a:8:{s:8:\"language\";s:5:\"en_GB\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 22:03:00\";s:12:\"english_name\";s:12:\"English (UK)\";s:11:\"native_name\";s:12:\"English (UK)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/en_GB.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"en\";i:2;s:3:\"eng\";i:3;s:3:\"eng\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:2:\"eo\";a:8:{s:8:\"language\";s:2:\"eo\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-13 18:06:55\";s:12:\"english_name\";s:9:\"Esperanto\";s:11:\"native_name\";s:9:\"Esperanto\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/eo.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"eo\";i:2;s:3:\"epo\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Daลญrigi\";}}s:5:\"es_CO\";a:8:{s:8:\"language\";s:5:\"es_CO\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-15 19:01:12\";s:12:\"english_name\";s:18:\"Spanish (Colombia)\";s:11:\"native_name\";s:20:\"Espaรฑol de Colombia\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_CO.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_CL\";a:8:{s:8:\"language\";s:5:\"es_CL\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 07:12:38\";s:12:\"english_name\";s:15:\"Spanish (Chile)\";s:11:\"native_name\";s:17:\"Espaรฑol de Chile\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_CL.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_PE\";a:8:{s:8:\"language\";s:5:\"es_PE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-04-04 01:49:30\";s:12:\"english_name\";s:14:\"Spanish (Peru)\";s:11:\"native_name\";s:17:\"Espaรฑol de Perรบ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_PE.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_PR\";a:8:{s:8:\"language\";s:5:\"es_PR\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-04-29 15:36:59\";s:12:\"english_name\";s:21:\"Spanish (Puerto Rico)\";s:11:\"native_name\";s:23:\"Espaรฑol de Puerto Rico\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_PR.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_VE\";a:8:{s:8:\"language\";s:5:\"es_VE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 22:04:10\";s:12:\"english_name\";s:19:\"Spanish (Venezuela)\";s:11:\"native_name\";s:21:\"Espaรฑol de Venezuela\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_VE.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_AR\";a:8:{s:8:\"language\";s:5:\"es_AR\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 22:36:30\";s:12:\"english_name\";s:19:\"Spanish (Argentina)\";s:11:\"native_name\";s:21:\"Espaรฑol de Argentina\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_AR.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_MX\";a:8:{s:8:\"language\";s:5:\"es_MX\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 23:56:55\";s:12:\"english_name\";s:16:\"Spanish (Mexico)\";s:11:\"native_name\";s:19:\"Espaรฑol de Mรฉxico\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_MX.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_ES\";a:8:{s:8:\"language\";s:5:\"es_ES\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 22:04:03\";s:12:\"english_name\";s:15:\"Spanish (Spain)\";s:11:\"native_name\";s:8:\"Espaรฑol\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/es_ES.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_CR\";a:8:{s:8:\"language\";s:5:\"es_CR\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-02-10 15:47:49\";s:12:\"english_name\";s:20:\"Spanish (Costa Rica)\";s:11:\"native_name\";s:22:\"Espaรฑol de Costa Rica\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/es_CR.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_UY\";a:8:{s:8:\"language\";s:5:\"es_UY\";s:7:\"version\";s:5:\"5.3.2\";s:7:\"updated\";s:19:\"2019-11-12 04:43:11\";s:12:\"english_name\";s:17:\"Spanish (Uruguay)\";s:11:\"native_name\";s:19:\"Espaรฑol de Uruguay\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.2/es_UY.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"es_GT\";a:8:{s:8:\"language\";s:5:\"es_GT\";s:7:\"version\";s:3:\"5.1\";s:7:\"updated\";s:19:\"2019-03-02 06:35:01\";s:12:\"english_name\";s:19:\"Spanish (Guatemala)\";s:11:\"native_name\";s:21:\"Espaรฑol de Guatemala\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/5.1/es_GT.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"es\";i:2;s:3:\"spa\";i:3;s:3:\"spa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:2:\"et\";a:8:{s:8:\"language\";s:2:\"et\";s:7:\"version\";s:9:\"5.0-beta3\";s:7:\"updated\";s:19:\"2018-11-28 16:04:33\";s:12:\"english_name\";s:8:\"Estonian\";s:11:\"native_name\";s:5:\"Eesti\";s:7:\"package\";s:65:\"https://downloads.wordpress.org/translation/core/5.0-beta3/et.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"et\";i:2;s:3:\"est\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Jรคtka\";}}s:2:\"eu\";a:8:{s:8:\"language\";s:2:\"eu\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-21 20:45:49\";s:12:\"english_name\";s:6:\"Basque\";s:11:\"native_name\";s:7:\"Euskara\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/eu.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"eu\";i:2;s:3:\"eus\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Jarraitu\";}}s:5:\"fa_IR\";a:8:{s:8:\"language\";s:5:\"fa_IR\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-15 22:41:55\";s:12:\"english_name\";s:7:\"Persian\";s:11:\"native_name\";s:10:\"ูุงุฑุณŒ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/fa_IR.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"fa\";i:2;s:3:\"fas\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:10:\"ุงุฏุงู…ู‡\";}}s:2:\"fi\";a:8:{s:8:\"language\";s:2:\"fi\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-19 11:46:35\";s:12:\"english_name\";s:7:\"Finnish\";s:11:\"native_name\";s:5:\"Suomi\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/fi.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"fi\";i:2;s:3:\"fin\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:5:\"Jatka\";}}s:5:\"fr_CA\";a:8:{s:8:\"language\";s:5:\"fr_CA\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-07 15:10:43\";s:12:\"english_name\";s:15:\"French (Canada)\";s:11:\"native_name\";s:19:\"Franรงais du Canada\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/fr_CA.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"fr\";i:2;s:3:\"fra\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuer\";}}s:5:\"fr_FR\";a:8:{s:8:\"language\";s:5:\"fr_FR\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-21 12:56:23\";s:12:\"english_name\";s:15:\"French (France)\";s:11:\"native_name\";s:9:\"Franรงais\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/fr_FR.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"fr\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuer\";}}s:5:\"fr_BE\";a:8:{s:8:\"language\";s:5:\"fr_BE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-17 12:28:19\";s:12:\"english_name\";s:16:\"French (Belgium)\";s:11:\"native_name\";s:21:\"Franรงais de Belgique\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/fr_BE.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"fr\";i:2;s:3:\"fra\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuer\";}}s:3:\"fur\";a:8:{s:8:\"language\";s:3:\"fur\";s:7:\"version\";s:5:\"4.8.6\";s:7:\"updated\";s:19:\"2018-01-29 17:32:35\";s:12:\"english_name\";s:8:\"Friulian\";s:11:\"native_name\";s:8:\"Friulian\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.8.6/fur.zip\";s:3:\"iso\";a:2:{i:2;s:3:\"fur\";i:3;s:3:\"fur\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:2:\"gd\";a:8:{s:8:\"language\";s:2:\"gd\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-08-23 17:41:37\";s:12:\"english_name\";s:15:\"Scottish Gaelic\";s:11:\"native_name\";s:9:\"Gร idhlig\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/gd.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"gd\";i:2;s:3:\"gla\";i:3;s:3:\"gla\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:15:\"Lean air adhart\";}}s:5:\"gl_ES\";a:8:{s:8:\"language\";s:5:\"gl_ES\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-19 08:38:07\";s:12:\"english_name\";s:8:\"Galician\";s:11:\"native_name\";s:6:\"Galego\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/gl_ES.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"gl\";i:2;s:3:\"glg\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:2:\"gu\";a:8:{s:8:\"language\";s:2:\"gu\";s:7:\"version\";s:5:\"4.9.8\";s:7:\"updated\";s:19:\"2018-09-14 12:33:48\";s:12:\"english_name\";s:8:\"Gujarati\";s:11:\"native_name\";s:21:\"เช—เซเชœเชฐเชพเชคเซ€\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.9.8/gu.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"gu\";i:2;s:3:\"guj\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:31:\"เชšเชพเชฒเซ เชฐเชพเช–เชตเซเช‚\";}}s:3:\"haz\";a:8:{s:8:\"language\";s:3:\"haz\";s:7:\"version\";s:5:\"4.4.2\";s:7:\"updated\";s:19:\"2015-12-05 00:59:09\";s:12:\"english_name\";s:8:\"Hazaragi\";s:11:\"native_name\";s:15:\"ู‡ุฒุงุฑู‡ ฺฏŒ\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.4.2/haz.zip\";s:3:\"iso\";a:1:{i:3;s:3:\"haz\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:10:\"ุงุฏุงู…ู‡\";}}s:5:\"he_IL\";a:8:{s:8:\"language\";s:5:\"he_IL\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-04-18 15:51:49\";s:12:\"english_name\";s:6:\"Hebrew\";s:11:\"native_name\";s:16:\"ืขึดื‘ึฐืจึดื™ืช\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/he_IL.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"he\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"ื”ืžืฉืš\";}}s:5:\"hi_IN\";a:8:{s:8:\"language\";s:5:\"hi_IN\";s:7:\"version\";s:5:\"4.9.7\";s:7:\"updated\";s:19:\"2018-06-17 09:33:44\";s:12:\"english_name\";s:5:\"Hindi\";s:11:\"native_name\";s:18:\"เคนเคฟเคจเฅเคฆเฅ€\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.9.7/hi_IN.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"hi\";i:2;s:3:\"hin\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:12:\"เคœเคพเคฐเฅ€\";}}s:2:\"hr\";a:8:{s:8:\"language\";s:2:\"hr\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-17 19:34:46\";s:12:\"english_name\";s:8:\"Croatian\";s:11:\"native_name\";s:8:\"Hrvatski\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/hr.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"hr\";i:2;s:3:\"hrv\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:7:\"Nastavi\";}}s:3:\"hsb\";a:8:{s:8:\"language\";s:3:\"hsb\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 22:07:21\";s:12:\"english_name\";s:13:\"Upper Sorbian\";s:11:\"native_name\";s:17:\"Hornjoserbลกฤ‡ina\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/5.4.1/hsb.zip\";s:3:\"iso\";a:2:{i:2;s:3:\"hsb\";i:3;s:3:\"hsb\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:4:\"Dale\";}}s:5:\"hu_HU\";a:8:{s:8:\"language\";s:5:\"hu_HU\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 23:17:45\";s:12:\"english_name\";s:9:\"Hungarian\";s:11:\"native_name\";s:6:\"Magyar\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/hu_HU.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"hu\";i:2;s:3:\"hun\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:10:\"Folytatรกs\";}}s:2:\"hy\";a:8:{s:8:\"language\";s:2:\"hy\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-12-03 16:21:10\";s:12:\"english_name\";s:8:\"Armenian\";s:11:\"native_name\";s:14:\"ี€ีกีตีฅึ€ีฅีถ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/hy.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"hy\";i:2;s:3:\"hye\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:20:\"ี‡ีกึ€ีธึ‚ีถีกีฏีฅีฌ\";}}s:5:\"id_ID\";a:8:{s:8:\"language\";s:5:\"id_ID\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-03-28 23:32:14\";s:12:\"english_name\";s:10:\"Indonesian\";s:11:\"native_name\";s:16:\"Bahasa Indonesia\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/id_ID.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"id\";i:2;s:3:\"ind\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Lanjutkan\";}}s:5:\"is_IS\";a:8:{s:8:\"language\";s:5:\"is_IS\";s:7:\"version\";s:6:\"4.7.11\";s:7:\"updated\";s:19:\"2018-09-20 11:13:37\";s:12:\"english_name\";s:9:\"Icelandic\";s:11:\"native_name\";s:9:\"รslenska\";s:7:\"package\";s:65:\"https://downloads.wordpress.org/translation/core/4.7.11/is_IS.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"is\";i:2;s:3:\"isl\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"รfram\";}}s:5:\"it_IT\";a:8:{s:8:\"language\";s:5:\"it_IT\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-11 10:50:19\";s:12:\"english_name\";s:7:\"Italian\";s:11:\"native_name\";s:8:\"Italiano\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/it_IT.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"it\";i:2;s:3:\"ita\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continua\";}}s:2:\"ja\";a:8:{s:8:\"language\";s:2:\"ja\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-19 02:02:47\";s:12:\"english_name\";s:8:\"Japanese\";s:11:\"native_name\";s:9:\"ๆ—ฅๆœฌ่ชž\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/ja.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"ja\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"็ถšใ‘ใ‚‹\";}}s:5:\"jv_ID\";a:8:{s:8:\"language\";s:5:\"jv_ID\";s:7:\"version\";s:5:\"4.9.5\";s:7:\"updated\";s:19:\"2018-03-24 13:53:29\";s:12:\"english_name\";s:8:\"Javanese\";s:11:\"native_name\";s:9:\"Basa Jawa\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.9.5/jv_ID.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"jv\";i:2;s:3:\"jav\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Nerusakรฉ\";}}s:5:\"ka_GE\";a:8:{s:8:\"language\";s:5:\"ka_GE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-04-30 07:54:16\";s:12:\"english_name\";s:8:\"Georgian\";s:11:\"native_name\";s:21:\"แƒฅแƒแƒ แƒ—แƒฃแƒšแƒ˜\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/ka_GE.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ka\";i:2;s:3:\"kat\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:30:\"แƒ’แƒแƒ’แƒ แƒซแƒ”แƒšแƒ”แƒ‘แƒ\";}}s:3:\"kab\";a:8:{s:8:\"language\";s:3:\"kab\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-21 17:25:57\";s:12:\"english_name\";s:6:\"Kabyle\";s:11:\"native_name\";s:9:\"Taqbaylit\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/5.4.1/kab.zip\";s:3:\"iso\";a:2:{i:2;s:3:\"kab\";i:3;s:3:\"kab\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Kemmel\";}}s:2:\"kk\";a:8:{s:8:\"language\";s:2:\"kk\";s:7:\"version\";s:5:\"4.9.5\";s:7:\"updated\";s:19:\"2018-03-12 08:08:32\";s:12:\"english_name\";s:6:\"Kazakh\";s:11:\"native_name\";s:19:\"าšะฐะทะฐา› ั‚ั–ะปั–\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.9.5/kk.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"kk\";i:2;s:3:\"kaz\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:20:\"ะ–ะฐะปา“ะฐัั‚ั‹ั€ัƒ\";}}s:2:\"km\";a:8:{s:8:\"language\";s:2:\"km\";s:7:\"version\";s:5:\"5.0.3\";s:7:\"updated\";s:19:\"2019-01-09 07:34:10\";s:12:\"english_name\";s:5:\"Khmer\";s:11:\"native_name\";s:27:\"แž—แžถแžŸแžถแžแŸ’แž˜แŸ‚แžš\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.0.3/km.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"km\";i:2;s:3:\"khm\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:12:\"แž”แž“แŸ’แž\";}}s:2:\"kn\";a:8:{s:8:\"language\";s:2:\"kn\";s:7:\"version\";s:6:\"4.9.14\";s:7:\"updated\";s:19:\"2019-12-04 12:22:34\";s:12:\"english_name\";s:7:\"Kannada\";s:11:\"native_name\";s:15:\"เฒ•เฒจเณเฒจเฒก\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.9.14/kn.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"kn\";i:2;s:3:\"kan\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:30:\"เฒฎเณเฒ‚เฒฆเณเฒตเฒฐเณ†เฒธเฒฟ\";}}s:5:\"ko_KR\";a:8:{s:8:\"language\";s:5:\"ko_KR\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-05-21 16:29:57\";s:12:\"english_name\";s:6:\"Korean\";s:11:\"native_name\";s:9:\"ํ•œ๊ตญ์–ด\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/ko_KR.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ko\";i:2;s:3:\"kor\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"๊ณ„์†\";}}s:3:\"ckb\";a:8:{s:8:\"language\";s:3:\"ckb\";s:7:\"version\";s:5:\"4.9.9\";s:7:\"updated\";s:19:\"2018-12-18 14:32:44\";s:12:\"english_name\";s:16:\"Kurdish (Sorani)\";s:11:\"native_name\";s:13:\"ูƒูˆุฑุฏŒโ€Ž\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.9.9/ckb.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ku\";i:3;s:3:\"ckb\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:30:\"ุจู‡โ€Œุฑุฏู‡โ€Œูˆุงู… ุจู‡โ€Œ\";}}s:2:\"lo\";a:8:{s:8:\"language\";s:2:\"lo\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-11-12 09:59:23\";s:12:\"english_name\";s:3:\"Lao\";s:11:\"native_name\";s:21:\"เบžเบฒเบชเบฒเบฅเบฒเบง\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/lo.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"lo\";i:2;s:3:\"lao\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:18:\"เบ•เปเปˆโ€‹เป„เบ›\";}}s:5:\"lt_LT\";a:8:{s:8:\"language\";s:5:\"lt_LT\";s:7:\"version\";s:5:\"5.2.6\";s:7:\"updated\";s:19:\"2019-10-19 19:23:46\";s:12:\"english_name\";s:10:\"Lithuanian\";s:11:\"native_name\";s:15:\"Lietuviลณ kalba\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.2.6/lt_LT.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"lt\";i:2;s:3:\"lit\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Tฤ™sti\";}}s:2:\"lv\";a:8:{s:8:\"language\";s:2:\"lv\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-06 14:36:42\";s:12:\"english_name\";s:7:\"Latvian\";s:11:\"native_name\";s:16:\"Latvieลกu valoda\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/lv.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"lv\";i:2;s:3:\"lav\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Turpinฤt\";}}s:5:\"mk_MK\";a:8:{s:8:\"language\";s:5:\"mk_MK\";s:7:\"version\";s:5:\"5.2.3\";s:7:\"updated\";s:19:\"2019-09-08 12:57:25\";s:12:\"english_name\";s:10:\"Macedonian\";s:11:\"native_name\";s:31:\"ะœะฐะบะตะดะพะฝัะบะธ ั˜ะฐะทะธะบ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.2.3/mk_MK.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"mk\";i:2;s:3:\"mkd\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:16:\"ะŸั€ะพะดะพะปะถะธ\";}}s:5:\"ml_IN\";a:8:{s:8:\"language\";s:5:\"ml_IN\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2017-01-27 03:43:32\";s:12:\"english_name\";s:9:\"Malayalam\";s:11:\"native_name\";s:18:\"เดฎเดฒเดฏเดพเดณเด‚\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.7.2/ml_IN.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ml\";i:2;s:3:\"mal\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:18:\"เดคเตเดŸเดฐเตเด•\";}}s:2:\"mn\";a:8:{s:8:\"language\";s:2:\"mn\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2017-01-12 07:29:35\";s:12:\"english_name\";s:9:\"Mongolian\";s:11:\"native_name\";s:12:\"ะœะพะฝะณะพะป\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/mn.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"mn\";i:2;s:3:\"mon\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:24:\"าฎั€ะณัะปะถะปาฏาฏะปัั…\";}}s:2:\"mr\";a:8:{s:8:\"language\";s:2:\"mr\";s:7:\"version\";s:6:\"4.8.13\";s:7:\"updated\";s:19:\"2018-02-13 07:38:55\";s:12:\"english_name\";s:7:\"Marathi\";s:11:\"native_name\";s:15:\"เคฎเคฐเคพเค เฅ€\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.8.13/mr.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"mr\";i:2;s:3:\"mar\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:25:\"เคธเฅเคฐเฅ เค เฅ‡เคตเคพ\";}}s:5:\"ms_MY\";a:8:{s:8:\"language\";s:5:\"ms_MY\";s:7:\"version\";s:5:\"4.9.8\";s:7:\"updated\";s:19:\"2018-08-30 20:27:25\";s:12:\"english_name\";s:5:\"Malay\";s:11:\"native_name\";s:13:\"Bahasa Melayu\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.9.8/ms_MY.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ms\";i:2;s:3:\"msa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Teruskan\";}}s:5:\"my_MM\";a:8:{s:8:\"language\";s:5:\"my_MM\";s:7:\"version\";s:6:\"4.1.20\";s:7:\"updated\";s:19:\"2015-03-26 15:57:42\";s:12:\"english_name\";s:17:\"Myanmar (Burmese)\";s:11:\"native_name\";s:15:\"แ€—แ€™แ€ฌแ€…แ€ฌ\";s:7:\"package\";s:65:\"https://downloads.wordpress.org/translation/core/4.1.20/my_MM.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"my\";i:2;s:3:\"mya\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:54:\"แ€†แ€€แ€บแ€œแ€€แ€บแ€œแ€ฏแ€•แ€บแ€†แ€ฑแ€ฌแ€„แ€บแ€•แ€ซแ‹\";}}s:5:\"nb_NO\";a:8:{s:8:\"language\";s:5:\"nb_NO\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-21 22:41:36\";s:12:\"english_name\";s:19:\"Norwegian (Bokmรฅl)\";s:11:\"native_name\";s:13:\"Norsk bokmรฅl\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/nb_NO.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"nb\";i:2;s:3:\"nob\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Fortsett\";}}s:5:\"ne_NP\";a:8:{s:8:\"language\";s:5:\"ne_NP\";s:7:\"version\";s:5:\"4.9.5\";s:7:\"updated\";s:19:\"2018-03-27 10:30:26\";s:12:\"english_name\";s:6:\"Nepali\";s:11:\"native_name\";s:18:\"เคจเฅ‡เคชเคพเคฒเฅ€\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.9.5/ne_NP.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ne\";i:2;s:3:\"nep\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:43:\"เคœเคพเคฐเฅ€ เคฐเคพเค–เฅเคจเฅเคนเฅ‹เคธเฅ\";}}s:5:\"nl_BE\";a:8:{s:8:\"language\";s:5:\"nl_BE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-17 14:42:00\";s:12:\"english_name\";s:15:\"Dutch (Belgium)\";s:11:\"native_name\";s:20:\"Nederlands (Belgiรซ)\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/nl_BE.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"nl\";i:2;s:3:\"nld\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Doorgaan\";}}s:5:\"nl_NL\";a:8:{s:8:\"language\";s:5:\"nl_NL\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-14 13:51:53\";s:12:\"english_name\";s:5:\"Dutch\";s:11:\"native_name\";s:10:\"Nederlands\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/nl_NL.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"nl\";i:2;s:3:\"nld\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Doorgaan\";}}s:12:\"nl_NL_formal\";a:8:{s:8:\"language\";s:12:\"nl_NL_formal\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-14 13:52:48\";s:12:\"english_name\";s:14:\"Dutch (Formal)\";s:11:\"native_name\";s:20:\"Nederlands (Formeel)\";s:7:\"package\";s:71:\"https://downloads.wordpress.org/translation/core/5.4.1/nl_NL_formal.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"nl\";i:2;s:3:\"nld\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Doorgaan\";}}s:5:\"nn_NO\";a:8:{s:8:\"language\";s:5:\"nn_NO\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-01-01 08:53:00\";s:12:\"english_name\";s:19:\"Norwegian (Nynorsk)\";s:11:\"native_name\";s:13:\"Norsk nynorsk\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/nn_NO.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"nn\";i:2;s:3:\"nno\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Hald fram\";}}s:3:\"oci\";a:8:{s:8:\"language\";s:3:\"oci\";s:7:\"version\";s:5:\"4.8.3\";s:7:\"updated\";s:19:\"2017-08-25 10:03:08\";s:12:\"english_name\";s:7:\"Occitan\";s:11:\"native_name\";s:7:\"Occitan\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.8.3/oci.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"oc\";i:2;s:3:\"oci\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Contunhar\";}}s:5:\"pa_IN\";a:8:{s:8:\"language\";s:5:\"pa_IN\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2017-01-16 05:19:43\";s:12:\"english_name\";s:7:\"Punjabi\";s:11:\"native_name\";s:18:\"เจชเฉฐเจœเจพเจฌเฉ€\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.7.2/pa_IN.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"pa\";i:2;s:3:\"pan\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:25:\"เจœเจพเจฐเฉ€ เจฐเฉฑเจ–เฉ‹\";}}s:5:\"pl_PL\";a:8:{s:8:\"language\";s:5:\"pl_PL\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-21 12:28:50\";s:12:\"english_name\";s:6:\"Polish\";s:11:\"native_name\";s:6:\"Polski\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/pl_PL.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"pl\";i:2;s:3:\"pol\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Kontynuuj\";}}s:2:\"ps\";a:8:{s:8:\"language\";s:2:\"ps\";s:7:\"version\";s:6:\"4.1.20\";s:7:\"updated\";s:19:\"2015-03-29 22:19:48\";s:12:\"english_name\";s:6:\"Pashto\";s:11:\"native_name\";s:8:\"ูพฺšุชูˆ\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.1.20/ps.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ps\";i:2;s:3:\"pus\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:19:\"ุฏูˆุงู… ูˆุฑฺฉฺ“ู‡\";}}s:5:\"pt_PT\";a:8:{s:8:\"language\";s:5:\"pt_PT\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-16 02:27:25\";s:12:\"english_name\";s:21:\"Portuguese (Portugal)\";s:11:\"native_name\";s:10:\"Portuguรชs\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/pt_PT.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"pt\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:10:\"pt_PT_ao90\";a:8:{s:8:\"language\";s:10:\"pt_PT_ao90\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-03-30 09:19:21\";s:12:\"english_name\";s:27:\"Portuguese (Portugal, AO90)\";s:11:\"native_name\";s:17:\"Portuguรชs (AO90)\";s:7:\"package\";s:69:\"https://downloads.wordpress.org/translation/core/5.4.1/pt_PT_ao90.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"pt\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"pt_BR\";a:8:{s:8:\"language\";s:5:\"pt_BR\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 23:19:07\";s:12:\"english_name\";s:19:\"Portuguese (Brazil)\";s:11:\"native_name\";s:20:\"Portuguรชs do Brasil\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/pt_BR.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"pt\";i:2;s:3:\"por\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:5:\"pt_AO\";a:8:{s:8:\"language\";s:5:\"pt_AO\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-15 10:13:20\";s:12:\"english_name\";s:19:\"Portuguese (Angola)\";s:11:\"native_name\";s:20:\"Portuguรชs de Angola\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/pt_AO.zip\";s:3:\"iso\";a:1:{i:1;s:2:\"pt\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuar\";}}s:3:\"rhg\";a:8:{s:8:\"language\";s:3:\"rhg\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-03-16 13:03:18\";s:12:\"english_name\";s:8:\"Rohingya\";s:11:\"native_name\";s:8:\"Ruรกinga\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/rhg.zip\";s:3:\"iso\";a:1:{i:3;s:3:\"rhg\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:5:\"ro_RO\";a:8:{s:8:\"language\";s:5:\"ro_RO\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-15 20:40:02\";s:12:\"english_name\";s:8:\"Romanian\";s:11:\"native_name\";s:8:\"Romรขnฤƒ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/ro_RO.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ro\";i:2;s:3:\"ron\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Continuฤƒ\";}}s:5:\"ru_RU\";a:8:{s:8:\"language\";s:5:\"ru_RU\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 23:02:05\";s:12:\"english_name\";s:7:\"Russian\";s:11:\"native_name\";s:14:\"ะ ัƒััะบะธะน\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/ru_RU.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ru\";i:2;s:3:\"rus\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:20:\"ะŸั€ะพะดะพะปะถะธั‚ัŒ\";}}s:3:\"sah\";a:8:{s:8:\"language\";s:3:\"sah\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2017-01-21 02:06:41\";s:12:\"english_name\";s:5:\"Sakha\";s:11:\"native_name\";s:14:\"ะกะฐั…ะฐะปั‹ั‹\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/sah.zip\";s:3:\"iso\";a:2:{i:2;s:3:\"sah\";i:3;s:3:\"sah\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:12:\"ะกะฐะปา•ะฐะฐ\";}}s:3:\"snd\";a:8:{s:8:\"language\";s:3:\"snd\";s:7:\"version\";s:3:\"5.3\";s:7:\"updated\";s:19:\"2019-11-12 04:37:38\";s:12:\"english_name\";s:6:\"Sindhi\";s:11:\"native_name\";s:8:\"ุณู†ฺŒูŠ\";s:7:\"package\";s:60:\"https://downloads.wordpress.org/translation/core/5.3/snd.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"sd\";i:2;s:2:\"sd\";i:3;s:3:\"snd\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:15:\"ุงฺณุชูŠ ู‡ู„ูˆ\";}}s:5:\"si_LK\";a:8:{s:8:\"language\";s:5:\"si_LK\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-11-12 06:00:52\";s:12:\"english_name\";s:7:\"Sinhala\";s:11:\"native_name\";s:15:\"เทƒเท’เถ‚เท„เถฝ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.7.2/si_LK.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"si\";i:2;s:3:\"sin\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:44:\"เถฏเท’เถœเถงเถธ เถšเถปเถœเท™เถฑ เถบเถฑเทŠเถฑ\";}}s:5:\"sk_SK\";a:8:{s:8:\"language\";s:5:\"sk_SK\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-20 06:37:07\";s:12:\"english_name\";s:6:\"Slovak\";s:11:\"native_name\";s:11:\"Slovenฤina\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/sk_SK.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"sk\";i:2;s:3:\"slk\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:12:\"Pokraฤovaลฅ\";}}s:3:\"skr\";a:8:{s:8:\"language\";s:3:\"skr\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-04-15 03:12:06\";s:12:\"english_name\";s:7:\"Saraiki\";s:11:\"native_name\";s:14:\"ุณุฑุงุฆŒฺฉŒ\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/5.4.1/skr.zip\";s:3:\"iso\";a:1:{i:3;s:3:\"skr\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:17:\"ุฌุงุฑŒ ุฑฺฉฺพูˆ\";}}s:5:\"sl_SI\";a:8:{s:8:\"language\";s:5:\"sl_SI\";s:7:\"version\";s:5:\"4.9.2\";s:7:\"updated\";s:19:\"2018-01-04 13:33:13\";s:12:\"english_name\";s:9:\"Slovenian\";s:11:\"native_name\";s:13:\"Slovenลกฤina\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.9.2/sl_SI.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"sl\";i:2;s:3:\"slv\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Nadaljuj\";}}s:2:\"sq\";a:8:{s:8:\"language\";s:2:\"sq\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-11 07:24:45\";s:12:\"english_name\";s:8:\"Albanian\";s:11:\"native_name\";s:5:\"Shqip\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/sq.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"sq\";i:2;s:3:\"sqi\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"Vazhdo\";}}s:5:\"sr_RS\";a:8:{s:8:\"language\";s:5:\"sr_RS\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-04-01 01:42:23\";s:12:\"english_name\";s:7:\"Serbian\";s:11:\"native_name\";s:23:\"ะกั€ะฟัะบะธ ั˜ะตะทะธะบ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/sr_RS.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"sr\";i:2;s:3:\"srp\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:14:\"ะะฐัั‚ะฐะฒะธ\";}}s:5:\"sv_SE\";a:8:{s:8:\"language\";s:5:\"sv_SE\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-22 22:23:36\";s:12:\"english_name\";s:7:\"Swedish\";s:11:\"native_name\";s:7:\"Svenska\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/sv_SE.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"sv\";i:2;s:3:\"swe\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:9:\"Fortsรคtt\";}}s:2:\"sw\";a:8:{s:8:\"language\";s:2:\"sw\";s:7:\"version\";s:5:\"5.2.6\";s:7:\"updated\";s:19:\"2019-10-22 00:19:41\";s:12:\"english_name\";s:7:\"Swahili\";s:11:\"native_name\";s:9:\"Kiswahili\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.2.6/sw.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"sw\";i:2;s:3:\"swa\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:7:\"Endelea\";}}s:3:\"szl\";a:8:{s:8:\"language\";s:3:\"szl\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-09-24 19:58:14\";s:12:\"english_name\";s:8:\"Silesian\";s:11:\"native_name\";s:17:\"ลšlลnskล gลdka\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/szl.zip\";s:3:\"iso\";a:1:{i:3;s:3:\"szl\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:13:\"Kลntynuowaฤ‡\";}}s:5:\"ta_IN\";a:8:{s:8:\"language\";s:5:\"ta_IN\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2017-01-27 03:22:47\";s:12:\"english_name\";s:5:\"Tamil\";s:11:\"native_name\";s:15:\"เฎคเฎฎเฎฟเฎดเฏ\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.7.2/ta_IN.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ta\";i:2;s:3:\"tam\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:24:\"เฎคเฏŠเฎŸเฎฐเฎตเฏเฎฎเฏ\";}}s:2:\"te\";a:8:{s:8:\"language\";s:2:\"te\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2017-01-26 15:47:39\";s:12:\"english_name\";s:6:\"Telugu\";s:11:\"native_name\";s:18:\"เฐคเฑ†เฐฒเฑเฐ—เฑ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/te.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"te\";i:2;s:3:\"tel\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:30:\"เฐ•เฑŠเฐจเฐธเฐพเฐ—เฐฟเฐ‚เฐšเฑ\";}}s:2:\"th\";a:8:{s:8:\"language\";s:2:\"th\";s:7:\"version\";s:5:\"5.2.6\";s:7:\"updated\";s:19:\"2020-05-05 06:24:37\";s:12:\"english_name\";s:4:\"Thai\";s:11:\"native_name\";s:9:\"เน„เธ—เธข\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.2.6/th.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"th\";i:2;s:3:\"tha\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:15:\"เธ•เนˆเธญเน„เธ›\";}}s:2:\"tl\";a:8:{s:8:\"language\";s:2:\"tl\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-12-30 02:38:08\";s:12:\"english_name\";s:7:\"Tagalog\";s:11:\"native_name\";s:7:\"Tagalog\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/4.7.2/tl.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"tl\";i:2;s:3:\"tgl\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:10:\"Magpatuloy\";}}s:5:\"tr_TR\";a:8:{s:8:\"language\";s:5:\"tr_TR\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-15 08:46:08\";s:12:\"english_name\";s:7:\"Turkish\";s:11:\"native_name\";s:8:\"Tรผrkรงe\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/tr_TR.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"tr\";i:2;s:3:\"tur\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:5:\"Devam\";}}s:5:\"tt_RU\";a:8:{s:8:\"language\";s:5:\"tt_RU\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-11-20 20:20:50\";s:12:\"english_name\";s:5:\"Tatar\";s:11:\"native_name\";s:19:\"ะขะฐั‚ะฐั€ ั‚ะตะปะต\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.7.2/tt_RU.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"tt\";i:2;s:3:\"tat\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:17:\"ะดำ™ะฒะฐะผ ะธั‚าฏ\";}}s:3:\"tah\";a:8:{s:8:\"language\";s:3:\"tah\";s:7:\"version\";s:5:\"4.7.2\";s:7:\"updated\";s:19:\"2016-03-06 18:39:39\";s:12:\"english_name\";s:8:\"Tahitian\";s:11:\"native_name\";s:10:\"Reo Tahiti\";s:7:\"package\";s:62:\"https://downloads.wordpress.org/translation/core/4.7.2/tah.zip\";s:3:\"iso\";a:3:{i:1;s:2:\"ty\";i:2;s:3:\"tah\";i:3;s:3:\"tah\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:8:\"Continue\";}}s:5:\"ug_CN\";a:8:{s:8:\"language\";s:5:\"ug_CN\";s:7:\"version\";s:5:\"4.9.5\";s:7:\"updated\";s:19:\"2018-04-12 12:31:53\";s:12:\"english_name\";s:6:\"Uighur\";s:11:\"native_name\";s:16:\"ุฆ‡ูŠุบ‡ุฑฺ†•\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/4.9.5/ug_CN.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ug\";i:2;s:3:\"uig\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:26:\"ุฏุง‹ุงู…ู„ุงุดุช‡ุฑ‡ุด\";}}s:2:\"uk\";a:8:{s:8:\"language\";s:2:\"uk\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-23 01:47:18\";s:12:\"english_name\";s:9:\"Ukrainian\";s:11:\"native_name\";s:20:\"ะฃะบั€ะฐั—ะฝััŒะบะฐ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.4.1/uk.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"uk\";i:2;s:3:\"ukr\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:20:\"ะŸั€ะพะดะพะฒะถะธั‚ะธ\";}}s:2:\"ur\";a:8:{s:8:\"language\";s:2:\"ur\";s:7:\"version\";s:5:\"5.1.5\";s:7:\"updated\";s:19:\"2020-04-09 10:48:08\";s:12:\"english_name\";s:4:\"Urdu\";s:11:\"native_name\";s:8:\"ุงุฑุฏูˆ\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.1.5/ur.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"ur\";i:2;s:3:\"urd\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:19:\"ุฌุงุฑŒ ุฑฺฉฺพŒฺบ\";}}s:5:\"uz_UZ\";a:8:{s:8:\"language\";s:5:\"uz_UZ\";s:7:\"version\";s:5:\"5.0.9\";s:7:\"updated\";s:19:\"2019-01-23 12:32:40\";s:12:\"english_name\";s:5:\"Uzbek\";s:11:\"native_name\";s:11:\"Oโ€˜zbekcha\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.0.9/uz_UZ.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"uz\";i:2;s:3:\"uzb\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:11:\"Davom etish\";}}s:2:\"vi\";a:8:{s:8:\"language\";s:2:\"vi\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2019-12-07 15:52:24\";s:12:\"english_name\";s:10:\"Vietnamese\";s:11:\"native_name\";s:14:\"Tiแบฟng Viแป‡t\";s:7:\"package\";s:61:\"https://downloads.wordpress.org/translation/core/5.3.3/vi.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"vi\";i:2;s:3:\"vie\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:12:\"Tiแบฟp tแปฅc\";}}s:5:\"zh_TW\";a:8:{s:8:\"language\";s:5:\"zh_TW\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-05-17 04:53:04\";s:12:\"english_name\";s:16:\"Chinese (Taiwan)\";s:11:\"native_name\";s:12:\"็น้ซ”ไธญๆ–‡\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/zh_TW.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"zh\";i:2;s:3:\"zho\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"็นผ็บŒ\";}}s:5:\"zh_CN\";a:8:{s:8:\"language\";s:5:\"zh_CN\";s:7:\"version\";s:5:\"5.4.1\";s:7:\"updated\";s:19:\"2020-03-30 20:54:59\";s:12:\"english_name\";s:15:\"Chinese (China)\";s:11:\"native_name\";s:12:\"็ฎ€ไฝ“ไธญๆ–‡\";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.4.1/zh_CN.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"zh\";i:2;s:3:\"zho\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"็ปง็ปญ\";}}s:5:\"zh_HK\";a:8:{s:8:\"language\";s:5:\"zh_HK\";s:7:\"version\";s:5:\"5.3.3\";s:7:\"updated\";s:19:\"2020-03-08 12:12:22\";s:12:\"english_name\";s:19:\"Chinese (Hong Kong)\";s:11:\"native_name\";s:16:\"้ฆ™ๆธฏไธญๆ–‡็‰ˆ \";s:7:\"package\";s:64:\"https://downloads.wordpress.org/translation/core/5.3.3/zh_HK.zip\";s:3:\"iso\";a:2:{i:1;s:2:\"zh\";i:2;s:3:\"zho\";}s:7:\"strings\";a:1:{s:8:\"continue\";s:6:\"็นผ็บŒ\";}}}','no'),(4471,'theme_mods_twentynineteen','a:1:{s:18:\"custom_css_post_id\";i:-1;}','yes'); +/*!40000 ALTER TABLE `wp_options` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_pods_category` +-- + +DROP TABLE IF EXISTS `wp_pods_category`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_pods_category` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `wp_text_field` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_pods_category` +-- + +LOCK TABLES `wp_pods_category` WRITE; +/*!40000 ALTER TABLE `wp_pods_category` DISABLE KEYS */; +INSERT INTO `wp_pods_category` VALUES (6,'Testing f27f6aa87ec90698cc92add87c329889'); +/*!40000 ALTER TABLE `wp_pods_category` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_pods_nav_menu` +-- + +DROP TABLE IF EXISTS `wp_pods_nav_menu`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_pods_nav_menu` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `wp_text_field` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_pods_nav_menu` +-- + +LOCK TABLES `wp_pods_nav_menu` WRITE; +/*!40000 ALTER TABLE `wp_pods_nav_menu` DISABLE KEYS */; +INSERT INTO `wp_pods_nav_menu` VALUES (8,'Testing b6e16087c5789b81d87ca565346fd337'); +/*!40000 ALTER TABLE `wp_pods_nav_menu` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_pods_post_tag` +-- + +DROP TABLE IF EXISTS `wp_pods_post_tag`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_pods_post_tag` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `wp_text_field` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_pods_post_tag` +-- + +LOCK TABLES `wp_pods_post_tag` WRITE; +/*!40000 ALTER TABLE `wp_pods_post_tag` DISABLE KEYS */; +INSERT INTO `wp_pods_post_tag` VALUES (2,'Test related tag text field fb48dd92f3198ce5cfeac554c9fb2867'),(7,'Testing ec6294c1df2cae4b69b7158bd5b7e527'); +/*!40000 ALTER TABLE `wp_pods_post_tag` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_pods_test_act` +-- + +DROP TABLE IF EXISTS `wp_pods_test_act`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_pods_test_act` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `wp_text_field` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `permalink` varchar(200) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_pods_test_act` +-- + +LOCK TABLES `wp_pods_test_act` WRITE; +/*!40000 ALTER TABLE `wp_pods_test_act` DISABLE KEYS */; +INSERT INTO `wp_pods_test_act` VALUES (1,'Test related pod text field c4aa9cb17a4cf2fcfc7e8fb840d42a8d','Related pod item c4aa9cb17a4cf2fcfc7e8fb840d42a8d','related-pod-item'),(2,'Testing 95f74c8e1f0e49ef288c74494e5d4d47','Testing index 95f74c8e1f0e49ef288c74494e5d4d47','test-slug-95f74c8e1f0e49ef288c74494e5d4d47'); +/*!40000 ALTER TABLE `wp_pods_test_act` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_pods_test_post_table` +-- + +DROP TABLE IF EXISTS `wp_pods_test_post_table`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_pods_test_post_table` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `wp_text_field` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=144 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_pods_test_post_table` +-- + +LOCK TABLES `wp_pods_test_post_table` WRITE; +/*!40000 ALTER TABLE `wp_pods_test_post_table` DISABLE KEYS */; +INSERT INTO `wp_pods_test_post_table` VALUES (143,'Testing fd1100433cbdb1a88065aa30720e3b40'); +/*!40000 ALTER TABLE `wp_pods_test_post_table` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_pods_test_tax_table` +-- + +DROP TABLE IF EXISTS `wp_pods_test_tax_table`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_pods_test_tax_table` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `wp_text_field` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_pods_test_tax_table` +-- + +LOCK TABLES `wp_pods_test_tax_table` WRITE; +/*!40000 ALTER TABLE `wp_pods_test_tax_table` DISABLE KEYS */; +INSERT INTO `wp_pods_test_tax_table` VALUES (4,'Testing dd10ac7ca2da6c9ab585c0e2d22cb11b'); +/*!40000 ALTER TABLE `wp_pods_test_tax_table` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_podsrel` +-- + +DROP TABLE IF EXISTS `wp_podsrel`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_podsrel` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `pod_id` int(10) unsigned DEFAULT NULL, + `field_id` int(10) unsigned DEFAULT NULL, + `item_id` bigint(20) unsigned DEFAULT NULL, + `related_pod_id` int(10) unsigned DEFAULT NULL, + `related_field_id` int(10) unsigned DEFAULT NULL, + `related_item_id` bigint(20) unsigned DEFAULT NULL, + `weight` smallint(5) unsigned DEFAULT 0, + PRIMARY KEY (`id`), + KEY `field_item_idx` (`field_id`,`item_id`), + KEY `rel_field_rel_item_idx` (`related_field_id`,`related_item_id`), + KEY `field_rel_item_idx` (`field_id`,`related_item_id`), + KEY `rel_field_item_idx` (`related_field_id`,`item_id`) +) ENGINE=InnoDB AUTO_INCREMENT=192 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_podsrel` +-- + +LOCK TABLES `wp_podsrel` WRITE; +/*!40000 ALTER TABLE `wp_podsrel` DISABLE KEYS */; +INSERT INTO `wp_podsrel` VALUES (1,22,23,135,0,0,2,0),(2,31,32,136,0,0,2,0),(3,31,33,136,0,0,135,0),(4,31,32,137,0,0,2,0),(5,31,33,137,0,0,135,0),(6,31,34,137,0,0,136,0),(7,76,77,2,0,0,2,0),(8,76,78,2,0,0,135,0),(9,76,79,2,0,0,136,0),(10,76,79,2,0,0,137,1),(11,104,105,138,0,0,2,0),(12,104,106,138,0,0,135,0),(13,104,107,138,0,0,136,0),(14,104,107,138,0,0,137,1),(15,104,108,138,0,0,2,0),(16,104,109,138,0,0,138,0),(17,113,114,2,0,0,2,0),(18,113,115,2,0,0,135,0),(19,113,116,2,0,0,136,0),(20,113,116,2,0,0,137,1),(21,113,117,2,0,0,2,0),(22,113,118,2,0,0,138,0),(23,122,123,1,0,0,2,0),(24,122,124,1,0,0,135,0),(25,122,125,1,0,0,136,0),(26,122,125,1,0,0,137,1),(27,122,126,1,0,0,2,0),(28,122,127,1,0,0,138,0),(29,122,128,1,0,0,2,0),(30,104,105,139,0,0,2,0),(31,104,106,139,0,0,135,0),(32,104,107,139,0,0,136,0),(33,104,107,139,0,0,137,1),(34,104,108,139,0,0,2,0),(35,104,109,139,0,0,138,0),(36,104,110,139,0,0,2,0),(37,104,111,139,0,0,1,0),(38,94,95,3,0,0,2,0),(39,94,96,3,0,0,135,0),(40,94,97,3,0,0,136,0),(41,94,97,3,0,0,137,1),(42,94,98,3,0,0,2,0),(43,94,99,3,0,0,138,0),(44,94,100,3,0,0,2,0),(45,94,101,3,0,0,1,0),(46,94,103,3,0,0,139,0),(47,94,95,2,0,0,2,0),(48,94,96,2,0,0,135,0),(49,94,97,2,0,0,136,0),(50,94,97,2,0,0,137,1),(51,94,98,2,0,0,2,0),(52,94,99,2,0,0,138,0),(53,94,100,2,0,0,2,0),(54,94,101,2,0,0,1,0),(55,94,103,2,0,0,139,0),(56,22,24,135,0,0,135,0),(57,22,25,135,0,0,136,0),(58,22,25,135,0,0,137,1),(59,22,26,135,0,0,2,0),(60,22,27,135,0,0,138,0),(61,22,28,135,0,0,2,0),(62,22,29,135,0,0,1,0),(63,31,34,137,0,0,137,1),(64,31,35,137,0,0,2,0),(65,31,36,137,0,0,138,0),(66,31,37,137,0,0,2,0),(67,31,38,137,0,0,1,0),(68,76,80,2,0,0,2,0),(69,76,81,2,0,0,138,0),(70,76,82,2,0,0,2,0),(71,76,83,2,0,0,1,0),(72,104,110,138,0,0,2,0),(73,104,111,138,0,0,1,0),(74,113,119,2,0,0,2,0),(75,113,120,2,0,0,1,0),(76,122,134,1,0,0,3,0),(77,122,129,1,0,0,1,0),(78,4,5,142,0,0,2,0),(79,4,6,142,0,0,135,0),(80,4,7,142,0,0,136,0),(81,4,7,142,0,0,137,1),(82,4,8,142,0,0,2,0),(83,4,9,142,0,0,138,0),(84,4,10,142,0,0,2,0),(85,4,11,142,0,0,1,0),(86,13,14,143,0,0,2,0),(87,13,15,143,0,0,135,0),(88,13,16,143,0,0,136,0),(89,13,16,143,0,0,137,1),(90,13,17,143,0,0,2,0),(91,13,18,143,0,0,138,0),(92,13,19,143,0,0,2,0),(93,13,20,143,0,0,1,0),(94,22,23,144,0,0,2,0),(95,22,24,144,0,0,135,0),(96,22,25,144,0,0,136,0),(97,22,25,144,0,0,137,1),(98,22,26,144,0,0,2,0),(99,22,27,144,0,0,138,0),(100,22,28,144,0,0,2,0),(101,22,29,144,0,0,1,0),(102,31,32,145,0,0,2,0),(103,31,33,145,0,0,135,0),(104,31,34,145,0,0,136,0),(105,31,34,145,0,0,137,1),(106,31,35,145,0,0,2,0),(107,31,36,145,0,0,138,0),(108,31,37,145,0,0,2,0),(109,31,38,145,0,0,1,0),(110,40,41,146,0,0,2,0),(111,40,42,146,0,0,135,0),(112,40,43,146,0,0,136,0),(113,40,43,146,0,0,137,1),(114,40,44,146,0,0,2,0),(115,40,45,146,0,0,138,0),(116,40,46,146,0,0,2,0),(117,40,47,146,0,0,1,0),(118,49,50,4,0,0,2,0),(119,49,51,4,0,0,135,0),(120,49,52,4,0,0,136,0),(121,49,52,4,0,0,137,1),(122,49,53,4,0,0,2,0),(123,49,54,4,0,0,138,0),(124,49,55,4,0,0,2,0),(125,49,56,4,0,0,1,0),(126,58,59,5,0,0,2,0),(127,58,60,5,0,0,135,0),(128,58,61,5,0,0,136,0),(129,58,61,5,0,0,137,1),(130,58,62,5,0,0,2,0),(131,58,63,5,0,0,138,0),(132,58,64,5,0,0,2,0),(133,58,65,5,0,0,1,0),(134,67,68,6,0,0,2,0),(135,67,69,6,0,0,135,0),(136,67,70,6,0,0,136,0),(137,67,70,6,0,0,137,1),(138,67,71,6,0,0,2,0),(139,67,72,6,0,0,138,0),(140,67,73,6,0,0,2,0),(141,67,74,6,0,0,1,0),(142,76,77,7,0,0,2,0),(143,76,78,7,0,0,135,0),(144,76,79,7,0,0,136,0),(145,76,79,7,0,0,137,1),(146,76,80,7,0,0,2,0),(147,76,81,7,0,0,138,0),(148,76,82,7,0,0,2,0),(149,76,83,7,0,0,1,0),(150,85,86,8,0,0,2,0),(151,85,87,8,0,0,135,0),(152,85,88,8,0,0,136,0),(153,85,88,8,0,0,137,1),(154,85,89,8,0,0,2,0),(155,85,90,8,0,0,138,0),(156,85,91,8,0,0,2,0),(157,85,92,8,0,0,1,0),(158,94,95,4,0,0,2,0),(159,94,96,4,0,0,135,0),(160,94,97,4,0,0,136,0),(161,94,97,4,0,0,137,1),(162,94,98,4,0,0,2,0),(163,94,99,4,0,0,138,0),(164,94,100,4,0,0,2,0),(165,94,101,4,0,0,1,0),(166,94,103,4,0,0,139,0),(167,104,105,147,0,0,2,0),(168,104,106,147,0,0,135,0),(169,104,107,147,0,0,136,0),(170,104,107,147,0,0,137,1),(171,104,108,147,0,0,2,0),(172,104,109,147,0,0,138,0),(173,104,110,147,0,0,2,0),(174,104,111,147,0,0,1,0),(175,113,114,3,0,0,2,0),(176,113,115,3,0,0,135,0),(177,113,116,3,0,0,136,0),(178,113,116,3,0,0,137,1),(179,113,117,3,0,0,2,0),(180,113,118,3,0,0,138,0),(181,113,119,3,0,0,2,0),(182,113,120,3,0,0,1,0),(183,122,134,2,0,0,3,0),(184,122,123,2,0,0,2,0),(185,122,124,2,0,0,135,0),(186,122,125,2,0,0,136,0),(187,122,125,2,0,0,137,1),(188,122,126,2,0,0,2,0),(189,122,127,2,0,0,138,0),(190,122,128,2,0,0,2,0),(191,122,129,2,0,0,1,0); +/*!40000 ALTER TABLE `wp_podsrel` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_postmeta` +-- + +DROP TABLE IF EXISTS `wp_postmeta`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_postmeta` ( + `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `post_id` bigint(20) unsigned NOT NULL DEFAULT 0, + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`meta_id`), + KEY `post_id` (`post_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB AUTO_INCREMENT=850 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_postmeta` +-- + +LOCK TABLES `wp_postmeta` WRITE; +/*!40000 ALTER TABLE `wp_postmeta` DISABLE KEYS */; +INSERT INTO `wp_postmeta` VALUES (3,4,'type','post_type'),(4,4,'storage','meta'),(5,4,'built_in_taxonomies_category','1'),(6,4,'built_in_taxonomies_post_tag','1'),(7,4,'built_in_taxonomies_nav_menu','1'),(8,4,'built_in_taxonomies_test_non_pod_ct','1'),(9,5,'type','pick'),(10,5,'pick_object','user'),(11,5,'pick_format_type','single'),(12,6,'type','pick'),(13,6,'pick_object','post_type'),(14,6,'pick_val','post'),(15,6,'pick_format_type','single'),(16,7,'type','pick'),(17,7,'pick_object','post_type'),(18,7,'pick_val','page'),(19,7,'pick_format_type','multi'),(20,8,'type','pick'),(21,8,'pick_object','taxonomy'),(22,8,'pick_val','post_tag'),(23,8,'pick_format_type','single'),(24,9,'type','pick'),(25,9,'pick_object','media'),(26,9,'pick_format_type','single'),(27,10,'type','pick'),(28,10,'pick_object','comment'),(29,10,'pick_format_type','single'),(30,11,'type','pick'),(31,11,'pick_object','pod'),(32,11,'pick_val','test_act'),(33,11,'pick_format_type','single'),(34,12,'type','text'),(35,13,'type','post_type'),(36,13,'storage','table'),(37,13,'built_in_taxonomies_category','1'),(38,13,'built_in_taxonomies_post_tag','1'),(39,13,'built_in_taxonomies_nav_menu','1'),(40,13,'built_in_taxonomies_test_non_pod_ct','1'),(41,14,'type','pick'),(42,14,'pick_object','user'),(43,14,'pick_format_type','single'),(44,15,'type','pick'),(45,15,'pick_object','post_type'),(46,15,'pick_val','post'),(47,15,'pick_format_type','single'),(48,16,'type','pick'),(49,16,'pick_object','post_type'),(50,16,'pick_val','page'),(51,16,'pick_format_type','multi'),(52,17,'type','pick'),(53,17,'pick_object','taxonomy'),(54,17,'pick_val','post_tag'),(55,17,'pick_format_type','single'),(56,18,'type','pick'),(57,18,'pick_object','media'),(58,18,'pick_format_type','single'),(59,19,'type','pick'),(60,19,'pick_object','comment'),(61,19,'pick_format_type','single'),(62,20,'type','pick'),(63,20,'pick_object','pod'),(64,20,'pick_val','test_act'),(65,20,'pick_format_type','single'),(66,21,'type','text'),(67,22,'type','post_type'),(68,22,'storage','meta'),(69,22,'object','post'),(70,22,'built_in_taxonomies_category','1'),(71,22,'built_in_taxonomies_post_tag','1'),(72,22,'built_in_taxonomies_nav_menu','1'),(73,22,'built_in_taxonomies_test_non_pod_ct','1'),(74,23,'type','pick'),(75,23,'pick_object','user'),(76,23,'pick_format_type','single'),(77,24,'type','pick'),(78,24,'pick_object','post_type'),(79,24,'pick_val','post'),(80,24,'pick_format_type','single'),(81,25,'type','pick'),(82,25,'pick_object','post_type'),(83,25,'pick_val','page'),(84,25,'pick_format_type','multi'),(85,26,'type','pick'),(86,26,'pick_object','taxonomy'),(87,26,'pick_val','post_tag'),(88,26,'pick_format_type','single'),(89,27,'type','pick'),(90,27,'pick_object','media'),(91,27,'pick_format_type','single'),(92,28,'type','pick'),(93,28,'pick_object','comment'),(94,28,'pick_format_type','single'),(95,29,'type','pick'),(96,29,'pick_object','pod'),(97,29,'pick_val','test_act'),(98,29,'pick_format_type','single'),(99,30,'type','text'),(100,31,'type','post_type'),(101,31,'storage','meta'),(102,31,'object','page'),(103,31,'built_in_taxonomies_category','1'),(104,31,'built_in_taxonomies_post_tag','1'),(105,31,'built_in_taxonomies_nav_menu','1'),(106,31,'built_in_taxonomies_test_non_pod_ct','1'),(107,32,'type','pick'),(108,32,'pick_object','user'),(109,32,'pick_format_type','single'),(110,33,'type','pick'),(111,33,'pick_object','post_type'),(112,33,'pick_val','post'),(113,33,'pick_format_type','single'),(114,34,'type','pick'),(115,34,'pick_object','post_type'),(116,34,'pick_val','page'),(117,34,'pick_format_type','multi'),(118,35,'type','pick'),(119,35,'pick_object','taxonomy'),(120,35,'pick_val','post_tag'),(121,35,'pick_format_type','single'),(122,36,'type','pick'),(123,36,'pick_object','media'),(124,36,'pick_format_type','single'),(125,37,'type','pick'),(126,37,'pick_object','comment'),(127,37,'pick_format_type','single'),(128,38,'type','pick'),(129,38,'pick_object','pod'),(130,38,'pick_val','test_act'),(131,38,'pick_format_type','single'),(132,39,'type','text'),(133,40,'type','post_type'),(134,40,'storage','meta'),(135,40,'object','nav_menu_item'),(136,40,'built_in_taxonomies_category','1'),(137,40,'built_in_taxonomies_post_tag','1'),(138,40,'built_in_taxonomies_nav_menu','1'),(139,40,'built_in_taxonomies_test_non_pod_ct','1'),(140,41,'type','pick'),(141,41,'pick_object','user'),(142,41,'pick_format_type','single'),(143,42,'type','pick'),(144,42,'pick_object','post_type'),(145,42,'pick_val','post'),(146,42,'pick_format_type','single'),(147,43,'type','pick'),(148,43,'pick_object','post_type'),(149,43,'pick_val','page'),(150,43,'pick_format_type','multi'),(151,44,'type','pick'),(152,44,'pick_object','taxonomy'),(153,44,'pick_val','post_tag'),(154,44,'pick_format_type','single'),(155,45,'type','pick'),(156,45,'pick_object','media'),(157,45,'pick_format_type','single'),(158,46,'type','pick'),(159,46,'pick_object','comment'),(160,46,'pick_format_type','single'),(161,47,'type','pick'),(162,47,'pick_object','pod'),(163,47,'pick_val','test_act'),(164,47,'pick_format_type','single'),(165,48,'type','text'),(166,49,'type','taxonomy'),(167,49,'storage','table'),(168,49,'built_in_post_types_post','1'),(169,49,'built_in_post_types_page','1'),(170,49,'built_in_post_types_nav_menu_item','1'),(171,22,'built_in_taxonomies_test_tax_table','1'),(172,31,'built_in_taxonomies_test_tax_table','1'),(173,40,'built_in_taxonomies_test_tax_table','1'),(174,50,'type','pick'),(175,50,'pick_object','user'),(176,50,'pick_format_type','single'),(177,51,'type','pick'),(178,51,'pick_object','post_type'),(179,51,'pick_val','post'),(180,51,'pick_format_type','single'),(181,52,'type','pick'),(182,52,'pick_object','post_type'),(183,52,'pick_val','page'),(184,52,'pick_format_type','multi'),(185,53,'type','pick'),(186,53,'pick_object','taxonomy'),(187,53,'pick_val','post_tag'),(188,53,'pick_format_type','single'),(189,54,'type','pick'),(190,54,'pick_object','media'),(191,54,'pick_format_type','single'),(192,55,'type','pick'),(193,55,'pick_object','comment'),(194,55,'pick_format_type','single'),(195,56,'type','pick'),(196,56,'pick_object','pod'),(197,56,'pick_val','test_act'),(198,56,'pick_format_type','single'),(199,57,'type','text'),(200,58,'type','taxonomy'),(201,58,'storage','meta'),(202,58,'built_in_post_types_post','1'),(203,58,'built_in_post_types_page','1'),(204,58,'built_in_post_types_nav_menu_item','1'),(205,22,'built_in_taxonomies_test_tax_meta','1'),(206,31,'built_in_taxonomies_test_tax_meta','1'),(207,40,'built_in_taxonomies_test_tax_meta','1'),(208,59,'type','pick'),(209,59,'pick_object','user'),(210,59,'pick_format_type','single'),(211,60,'type','pick'),(212,60,'pick_object','post_type'),(213,60,'pick_val','post'),(214,60,'pick_format_type','single'),(215,61,'type','pick'),(216,61,'pick_object','post_type'),(217,61,'pick_val','page'),(218,61,'pick_format_type','multi'),(219,62,'type','pick'),(220,62,'pick_object','taxonomy'),(221,62,'pick_val','post_tag'),(222,62,'pick_format_type','single'),(223,63,'type','pick'),(224,63,'pick_object','media'),(225,63,'pick_format_type','single'),(226,64,'type','pick'),(227,64,'pick_object','comment'),(228,64,'pick_format_type','single'),(229,65,'type','pick'),(230,65,'pick_object','pod'),(231,65,'pick_val','test_act'),(232,65,'pick_format_type','single'),(233,66,'type','text'),(234,67,'type','taxonomy'),(235,67,'storage','table'),(236,67,'object','category'),(237,67,'built_in_post_types_post','1'),(238,67,'built_in_post_types_page','1'),(239,67,'built_in_post_types_nav_menu_item','1'),(240,68,'type','pick'),(241,68,'pick_object','user'),(242,68,'pick_format_type','single'),(243,69,'type','pick'),(244,69,'pick_object','post_type'),(245,69,'pick_val','post'),(246,69,'pick_format_type','single'),(247,70,'type','pick'),(248,70,'pick_object','post_type'),(249,70,'pick_val','page'),(250,70,'pick_format_type','multi'),(251,71,'type','pick'),(252,71,'pick_object','taxonomy'),(253,71,'pick_val','post_tag'),(254,71,'pick_format_type','single'),(255,72,'type','pick'),(256,72,'pick_object','media'),(257,72,'pick_format_type','single'),(258,73,'type','pick'),(259,73,'pick_object','comment'),(260,73,'pick_format_type','single'),(261,74,'type','pick'),(262,74,'pick_object','pod'),(263,74,'pick_val','test_act'),(264,74,'pick_format_type','single'),(265,75,'type','text'),(266,76,'type','taxonomy'),(267,76,'storage','table'),(268,76,'object','post_tag'),(269,76,'built_in_post_types_post','1'),(270,76,'built_in_post_types_page','1'),(271,76,'built_in_post_types_nav_menu_item','1'),(272,77,'type','pick'),(273,77,'pick_object','user'),(274,77,'pick_format_type','single'),(275,78,'type','pick'),(276,78,'pick_object','post_type'),(277,78,'pick_val','post'),(278,78,'pick_format_type','single'),(279,79,'type','pick'),(280,79,'pick_object','post_type'),(281,79,'pick_val','page'),(282,79,'pick_format_type','multi'),(283,80,'type','pick'),(284,80,'pick_object','taxonomy'),(285,80,'pick_val','post_tag'),(286,80,'pick_format_type','single'),(287,81,'type','pick'),(288,81,'pick_object','media'),(289,81,'pick_format_type','single'),(290,82,'type','pick'),(291,82,'pick_object','comment'),(292,82,'pick_format_type','single'),(293,83,'type','pick'),(294,83,'pick_object','pod'),(295,83,'pick_val','test_act'),(296,83,'pick_format_type','single'),(297,84,'type','text'),(298,85,'type','taxonomy'),(299,85,'storage','table'),(300,85,'object','nav_menu'),(301,85,'built_in_post_types_post','1'),(302,85,'built_in_post_types_page','1'),(303,85,'built_in_post_types_nav_menu_item','1'),(304,86,'type','pick'),(305,86,'pick_object','user'),(306,86,'pick_format_type','single'),(307,87,'type','pick'),(308,87,'pick_object','post_type'),(309,87,'pick_val','post'),(310,87,'pick_format_type','single'),(311,88,'type','pick'),(312,88,'pick_object','post_type'),(313,88,'pick_val','page'),(314,88,'pick_format_type','multi'),(315,89,'type','pick'),(316,89,'pick_object','taxonomy'),(317,89,'pick_val','post_tag'),(318,89,'pick_format_type','single'),(319,90,'type','pick'),(320,90,'pick_object','media'),(321,90,'pick_format_type','single'),(322,91,'type','pick'),(323,91,'pick_object','comment'),(324,91,'pick_format_type','single'),(325,92,'type','pick'),(326,92,'pick_object','pod'),(327,92,'pick_val','test_act'),(328,92,'pick_format_type','single'),(329,93,'type','text'),(330,94,'type','user'),(331,94,'storage','meta'),(332,94,'object','user'),(333,95,'type','pick'),(334,95,'pick_object','user'),(335,95,'pick_format_type','single'),(336,96,'type','pick'),(337,96,'pick_object','post_type'),(338,96,'pick_val','post'),(339,96,'pick_format_type','single'),(340,97,'type','pick'),(341,97,'pick_object','post_type'),(342,97,'pick_val','page'),(343,97,'pick_format_type','multi'),(344,98,'type','pick'),(345,98,'pick_object','taxonomy'),(346,98,'pick_val','post_tag'),(347,98,'pick_format_type','single'),(348,99,'type','pick'),(349,99,'pick_object','media'),(350,99,'pick_format_type','single'),(351,100,'type','pick'),(352,100,'pick_object','comment'),(353,100,'pick_format_type','single'),(354,101,'type','pick'),(355,101,'pick_object','pod'),(356,101,'pick_val','test_act'),(357,101,'pick_format_type','single'),(358,102,'type','text'),(359,103,'type','avatar'),(360,104,'type','media'),(361,104,'storage','meta'),(362,104,'object','media'),(363,105,'type','pick'),(364,105,'pick_object','user'),(365,105,'pick_format_type','single'),(366,106,'type','pick'),(367,106,'pick_object','post_type'),(368,106,'pick_val','post'),(369,106,'pick_format_type','single'),(370,107,'type','pick'),(371,107,'pick_object','post_type'),(372,107,'pick_val','page'),(373,107,'pick_format_type','multi'),(374,108,'type','pick'),(375,108,'pick_object','taxonomy'),(376,108,'pick_val','post_tag'),(377,108,'pick_format_type','single'),(378,109,'type','pick'),(379,109,'pick_object','media'),(380,109,'pick_format_type','single'),(381,110,'type','pick'),(382,110,'pick_object','comment'),(383,110,'pick_format_type','single'),(384,111,'type','pick'),(385,111,'pick_object','pod'),(386,111,'pick_val','test_act'),(387,111,'pick_format_type','single'),(388,112,'type','text'),(389,113,'type','comment'),(390,113,'storage','meta'),(391,113,'object','comment'),(392,114,'type','pick'),(393,114,'pick_object','user'),(394,114,'pick_format_type','single'),(395,115,'type','pick'),(396,115,'pick_object','post_type'),(397,115,'pick_val','post'),(398,115,'pick_format_type','single'),(399,116,'type','pick'),(400,116,'pick_object','post_type'),(401,116,'pick_val','page'),(402,116,'pick_format_type','multi'),(403,117,'type','pick'),(404,117,'pick_object','taxonomy'),(405,117,'pick_val','post_tag'),(406,117,'pick_format_type','single'),(407,118,'type','pick'),(408,118,'pick_object','media'),(409,118,'pick_format_type','single'),(410,119,'type','pick'),(411,119,'pick_object','comment'),(412,119,'pick_format_type','single'),(413,120,'type','pick'),(414,120,'pick_object','pod'),(415,120,'pick_val','test_act'),(416,120,'pick_format_type','single'),(417,121,'type','text'),(418,122,'type','pod'),(419,122,'storage','table'),(420,122,'pod_index','name'),(421,123,'type','pick'),(422,123,'pick_object','user'),(423,123,'pick_format_type','single'),(424,124,'type','pick'),(425,124,'pick_object','post_type'),(426,124,'pick_val','post'),(427,124,'pick_format_type','single'),(428,125,'type','pick'),(429,125,'pick_object','post_type'),(430,125,'pick_val','page'),(431,125,'pick_format_type','multi'),(432,126,'type','pick'),(433,126,'pick_object','taxonomy'),(434,126,'pick_val','post_tag'),(435,126,'pick_format_type','single'),(436,127,'type','pick'),(437,127,'pick_object','media'),(438,127,'pick_format_type','single'),(439,128,'type','pick'),(440,128,'pick_object','comment'),(441,128,'pick_format_type','single'),(442,129,'type','pick'),(443,129,'pick_object','pod'),(444,129,'pick_val','test_act'),(445,129,'pick_format_type','single'),(446,130,'type','text'),(447,131,'type','text'),(448,132,'type','slug'),(449,133,'type','test'),(450,134,'type','pick'),(451,134,'pick_object','user'),(452,134,'pick_format_type','single'),(453,135,'_pingme','1'),(454,135,'_encloseme','1'),(455,135,'avatar','0'),(456,135,'test_text_field','Test related post text field 957094053317a49eb5f8db0bc71430da'),(457,135,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(459,136,'avatar','0'),(460,136,'test_text_field','Test related page text field f820300a0ff832c3a0b9cd9a6f2bf7ba'),(461,136,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(462,136,'test_rel_user','2'),(463,136,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(464,136,'test_rel_post','135'),(465,137,'avatar','0'),(466,137,'test_text_field','Test related page text field b56642438d7bc780f732c893356d9897'),(467,137,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(469,137,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(471,137,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(473,138,'_wp_attached_file','2019/07/ee00b7f0e64c35bc6463829c7c9e1f22-180.png'),(474,138,'_wp_attachment_metadata','a:5:{s:5:\"width\";i:200;s:6:\"height\";i:200;s:4:\"file\";s:48:\"2019/07/ee00b7f0e64c35bc6463829c7c9e1f22-180.png\";s:10:\"image_meta\";a:12:{s:8:\"aperture\";s:1:\"0\";s:6:\"credit\";s:0:\"\";s:6:\"camera\";s:0:\"\";s:7:\"caption\";s:0:\"\";s:17:\"created_timestamp\";s:1:\"0\";s:9:\"copyright\";s:0:\"\";s:12:\"focal_length\";s:1:\"0\";s:3:\"iso\";s:1:\"0\";s:13:\"shutter_speed\";s:1:\"0\";s:5:\"title\";s:0:\"\";s:11:\"orientation\";s:1:\"0\";s:8:\"keywords\";a:0:{}}s:5:\"sizes\";a:1:{s:9:\"thumbnail\";a:4:{s:4:\"file\";s:48:\"ee00b7f0e64c35bc6463829c7c9e1f22-180-150x150.png\";s:5:\"width\";i:150;s:6:\"height\";i:150;s:9:\"mime-type\";s:9:\"image/png\";}}}'),(475,138,'avatar','0'),(476,138,'test_text_field','Test related media text field 08fc45387cdce771f30cf311ae34fa17'),(477,138,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(479,138,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(481,138,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(484,138,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(486,138,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(488,139,'_wp_attached_file','2019/07/ee00b7f0e64c35bc6463829c7c9e1f22-181.png'),(489,139,'_wp_attachment_metadata','a:5:{s:5:\"width\";i:200;s:6:\"height\";i:200;s:4:\"file\";s:48:\"2019/07/ee00b7f0e64c35bc6463829c7c9e1f22-181.png\";s:10:\"image_meta\";a:12:{s:8:\"aperture\";s:1:\"0\";s:6:\"credit\";s:0:\"\";s:6:\"camera\";s:0:\"\";s:7:\"caption\";s:0:\"\";s:17:\"created_timestamp\";s:1:\"0\";s:9:\"copyright\";s:0:\"\";s:12:\"focal_length\";s:1:\"0\";s:3:\"iso\";s:1:\"0\";s:13:\"shutter_speed\";s:1:\"0\";s:5:\"title\";s:0:\"\";s:11:\"orientation\";s:1:\"0\";s:8:\"keywords\";a:0:{}}s:5:\"sizes\";a:1:{s:9:\"thumbnail\";a:4:{s:4:\"file\";s:48:\"ee00b7f0e64c35bc6463829c7c9e1f22-181-150x150.png\";s:5:\"width\";i:150;s:6:\"height\";i:150;s:9:\"mime-type\";s:9:\"image/png\";}}}'),(490,139,'avatar','0'),(491,139,'test_text_field','Test avatar text field'),(492,139,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(494,139,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(496,139,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(499,139,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(501,139,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(503,139,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(505,139,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(507,135,'_pingme','1'),(508,135,'_encloseme','1'),(509,135,'_index','Related post 957094053317a49eb5f8db0bc71430da'),(510,135,'_items','a:1:{i:135;a:12:{s:10:\"post_title\";s:45:\"Related post 957094053317a49eb5f8db0bc71430da\";s:12:\"post_content\";s:32:\"957094053317a49eb5f8db0bc71430da\";s:11:\"post_status\";s:7:\"publish\";s:15:\"test_text_field\";s:61:\"Test related post text field 957094053317a49eb5f8db0bc71430da\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:1:\"0\";s:14:\"test_rel_pages\";s:1:\"0\";s:12:\"test_rel_tag\";s:1:\"0\";s:14:\"test_rel_media\";s:1:\"0\";s:16:\"test_rel_comment\";s:1:\"0\";s:12:\"test_rel_act\";s:1:\"0\";s:6:\"avatar\";s:1:\"0\";}}'),(511,135,'_field_id','ID'),(512,135,'_field_index','post_title'),(513,135,'test_rel_user','2'),(514,135,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(515,135,'test_rel_post','135'),(516,135,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(517,135,'test_rel_pages','136'),(518,135,'test_rel_pages','137'),(519,135,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(520,135,'test_rel_tag','2'),(521,135,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(522,135,'test_rel_media','138'),(523,135,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(524,135,'test_rel_comment','2'),(525,135,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(526,135,'test_rel_act','1'),(527,137,'_index','a:2:{i:136;s:45:\"Related page f820300a0ff832c3a0b9cd9a6f2bf7ba\";i:137;s:47:\"Related page 2 b56642438d7bc780f732c893356d9897\";}'),(528,137,'_items','a:2:{i:136;a:12:{s:10:\"post_title\";s:45:\"Related page f820300a0ff832c3a0b9cd9a6f2bf7ba\";s:12:\"post_content\";s:32:\"f820300a0ff832c3a0b9cd9a6f2bf7ba\";s:11:\"post_status\";s:7:\"publish\";s:15:\"test_text_field\";s:61:\"Test related page text field f820300a0ff832c3a0b9cd9a6f2bf7ba\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:3:\"135\";s:14:\"test_rel_pages\";s:3:\"136\";s:12:\"test_rel_tag\";s:1:\"0\";s:14:\"test_rel_media\";s:1:\"0\";s:16:\"test_rel_comment\";s:1:\"0\";s:12:\"test_rel_act\";s:1:\"0\";s:6:\"avatar\";s:1:\"0\";}i:137;a:12:{s:10:\"post_title\";s:47:\"Related page 2 b56642438d7bc780f732c893356d9897\";s:12:\"post_content\";s:32:\"b56642438d7bc780f732c893356d9897\";s:11:\"post_status\";s:7:\"publish\";s:15:\"test_text_field\";s:61:\"Test related page text field b56642438d7bc780f732c893356d9897\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:3:\"135\";s:14:\"test_rel_pages\";s:3:\"136\";s:12:\"test_rel_tag\";s:1:\"0\";s:14:\"test_rel_media\";s:1:\"0\";s:16:\"test_rel_comment\";s:1:\"0\";s:12:\"test_rel_act\";s:1:\"0\";s:6:\"avatar\";s:1:\"0\";}}'),(529,137,'_field_id','ID'),(530,137,'_field_index','post_title'),(531,137,'test_rel_user','2'),(532,137,'test_rel_post','135'),(533,137,'test_rel_pages','136'),(534,137,'test_rel_pages','137'),(535,137,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(536,137,'test_rel_tag','2'),(537,137,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(538,137,'test_rel_media','138'),(539,137,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(540,137,'test_rel_comment','2'),(541,137,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(542,137,'test_rel_act','1'),(543,138,'_index','Related media'),(544,138,'_items','a:1:{i:138;a:12:{s:10:\"post_title\";s:13:\"Related media\";s:12:\"post_content\";s:32:\"08fc45387cdce771f30cf311ae34fa17\";s:11:\"post_status\";s:7:\"publish\";s:15:\"test_text_field\";s:62:\"Test related media text field 08fc45387cdce771f30cf311ae34fa17\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:3:\"135\";s:14:\"test_rel_pages\";a:2:{i:136;s:3:\"136\";i:137;s:3:\"137\";}s:12:\"test_rel_tag\";s:1:\"2\";s:14:\"test_rel_media\";s:3:\"138\";s:16:\"test_rel_comment\";s:1:\"0\";s:12:\"test_rel_act\";s:1:\"0\";s:6:\"avatar\";s:1:\"0\";}}'),(545,138,'_field_id','ID'),(546,138,'_field_index','post_title'),(547,138,'test_rel_user','2'),(548,138,'test_rel_post','135'),(549,138,'test_rel_pages','136'),(550,138,'test_rel_pages','137'),(551,138,'test_rel_tag','2'),(552,138,'test_rel_media','138'),(553,138,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(554,138,'test_rel_comment','2'),(555,138,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(556,138,'test_rel_act','1'),(557,139,'_index','Related avatar'),(558,139,'_items','a:1:{i:139;a:12:{s:10:\"post_title\";s:14:\"Related avatar\";s:12:\"post_content\";s:32:\"b583076ded12c15bc9e87d7057a18180\";s:11:\"post_status\";s:7:\"publish\";s:15:\"test_text_field\";s:22:\"Test avatar text field\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:3:\"135\";s:14:\"test_rel_pages\";a:2:{i:136;s:3:\"136\";i:137;s:3:\"137\";}s:12:\"test_rel_tag\";s:1:\"2\";s:14:\"test_rel_media\";s:3:\"138\";s:16:\"test_rel_comment\";s:1:\"2\";s:12:\"test_rel_act\";s:1:\"1\";s:6:\"avatar\";s:1:\"0\";}}'),(559,139,'_field_id','ID'),(560,139,'_field_index','post_title'),(561,139,'test_rel_user','2'),(562,139,'test_rel_post','135'),(563,139,'test_rel_pages','136'),(564,139,'test_rel_pages','137'),(565,139,'test_rel_tag','2'),(566,139,'test_rel_media','138'),(567,139,'test_rel_comment','2'),(568,139,'test_rel_act','1'),(569,142,'avatar','0'),(570,142,'test_text_field','Testing a66d982c8099d014bc1fa2937e55c912'),(571,142,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(573,142,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(575,142,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(578,142,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(580,142,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(582,142,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(584,142,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(586,143,'avatar','0'),(587,143,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(589,143,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(591,143,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(594,143,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(596,143,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(598,143,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(600,143,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(602,144,'_pingme','1'),(603,144,'_encloseme','1'),(604,144,'avatar','0'),(605,144,'test_text_field','Testing 5999153530660d496e23b334a6befe6d'),(606,144,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(608,144,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(610,144,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(613,144,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(615,144,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(617,144,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(619,144,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(621,145,'avatar','0'),(622,145,'test_text_field','Testing 6dbbdb9022e2d0cd9a3664e421571379'),(623,145,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(625,145,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(627,145,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(630,145,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(632,145,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(634,145,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(636,145,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(638,146,'avatar','0'),(639,146,'test_text_field','Testing 25b0cd30b4b87446f5bf1695769cd47d'),(640,146,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(642,146,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(644,146,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(647,146,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(649,146,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(651,146,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(653,146,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(655,147,'avatar','0'),(656,147,'test_text_field','Testing 14228bf1d952618086f315a46a57a05a'),(657,147,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(659,147,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(661,147,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(664,147,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(666,147,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(668,147,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(670,147,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(672,142,'_field_id','ID'),(673,142,'_field_index','post_title'),(674,142,'test_rel_user','2'),(675,142,'test_rel_post','135'),(676,142,'test_rel_pages','136'),(677,142,'test_rel_pages','137'),(678,142,'test_rel_tag','2'),(679,142,'test_rel_media','138'),(680,142,'test_rel_comment','2'),(681,142,'test_rel_act','1'),(682,143,'_field_id','ID'),(683,143,'_field_index','post_title'),(684,143,'test_rel_user','2'),(685,143,'test_rel_post','135'),(686,143,'test_rel_pages','136'),(687,143,'test_rel_pages','137'),(688,143,'test_rel_tag','2'),(689,143,'test_rel_media','138'),(690,143,'test_rel_comment','2'),(691,143,'test_rel_act','1'),(692,144,'_pingme','1'),(693,144,'_encloseme','1'),(694,144,'_field_id','ID'),(695,144,'_field_index','post_title'),(696,144,'test_rel_user','2'),(697,144,'test_rel_post','135'),(698,144,'test_rel_pages','136'),(699,144,'test_rel_pages','137'),(700,144,'test_rel_tag','2'),(701,144,'test_rel_media','138'),(702,144,'test_rel_comment','2'),(703,144,'test_rel_act','1'),(704,145,'_field_id','ID'),(705,145,'_field_index','post_title'),(706,145,'test_rel_user','2'),(707,145,'test_rel_post','135'),(708,145,'test_rel_pages','136'),(709,145,'test_rel_pages','137'),(710,145,'test_rel_tag','2'),(711,145,'test_rel_media','138'),(712,145,'test_rel_comment','2'),(713,145,'test_rel_act','1'),(714,146,'_field_id','ID'),(715,146,'_field_index','post_title'),(716,146,'test_rel_user','2'),(717,146,'test_rel_post','135'),(718,146,'test_rel_pages','136'),(719,146,'test_rel_pages','137'),(720,146,'test_rel_tag','2'),(721,146,'test_rel_media','138'),(722,146,'test_rel_comment','2'),(723,146,'test_rel_act','1'),(724,147,'_field_id','ID'),(725,147,'_field_index','post_title'),(726,147,'test_rel_user','2'),(727,147,'test_rel_post','135'),(728,147,'test_rel_pages','136'),(729,147,'test_rel_pages','137'),(730,147,'test_rel_tag','2'),(731,147,'test_rel_media','138'),(732,147,'test_rel_comment','2'),(733,147,'test_rel_act','1'),(734,68,'group','151'),(735,69,'group','151'),(736,70,'group','151'),(737,71,'group','151'),(738,72,'group','151'),(739,73,'group','151'),(740,74,'group','151'),(741,75,'group','151'),(742,114,'group','152'),(743,115,'group','152'),(744,116,'group','152'),(745,117,'group','152'),(746,118,'group','152'),(747,119,'group','152'),(748,120,'group','152'),(749,121,'group','152'),(750,105,'group','153'),(751,106,'group','153'),(752,107,'group','153'),(753,108,'group','153'),(754,109,'group','153'),(755,110,'group','153'),(756,111,'group','153'),(757,112,'group','153'),(758,86,'group','154'),(759,87,'group','154'),(760,88,'group','154'),(761,89,'group','154'),(762,90,'group','154'),(763,91,'group','154'),(764,92,'group','154'),(765,93,'group','154'),(766,41,'group','155'),(767,42,'group','155'),(768,43,'group','155'),(769,44,'group','155'),(770,45,'group','155'),(771,46,'group','155'),(772,47,'group','155'),(773,48,'group','155'),(774,32,'group','156'),(775,33,'group','156'),(776,34,'group','156'),(777,35,'group','156'),(778,36,'group','156'),(779,37,'group','156'),(780,38,'group','156'),(781,39,'group','156'),(782,23,'group','157'),(783,24,'group','157'),(784,25,'group','157'),(785,26,'group','157'),(786,27,'group','157'),(787,28,'group','157'),(788,29,'group','157'),(789,30,'group','157'),(790,77,'group','158'),(791,78,'group','158'),(792,79,'group','158'),(793,80,'group','158'),(794,81,'group','158'),(795,82,'group','158'),(796,83,'group','158'),(797,84,'group','158'),(798,123,'group','159'),(799,124,'group','159'),(800,125,'group','159'),(801,126,'group','159'),(802,127,'group','159'),(803,128,'group','159'),(804,129,'group','159'),(805,133,'group','159'),(806,131,'group','159'),(807,132,'group','159'),(808,134,'group','159'),(809,5,'group','160'),(810,6,'group','160'),(811,7,'group','160'),(812,8,'group','160'),(813,14,'group','161'),(814,9,'group','160'),(815,10,'group','160'),(816,15,'group','161'),(817,11,'group','160'),(818,16,'group','161'),(819,12,'group','160'),(820,17,'group','161'),(821,18,'group','161'),(822,19,'group','161'),(823,20,'group','161'),(824,21,'group','161'),(825,59,'group','162'),(826,60,'group','162'),(827,61,'group','162'),(828,62,'group','162'),(829,63,'group','162'),(830,64,'group','162'),(831,65,'group','162'),(832,66,'group','162'),(833,50,'group','163'),(834,51,'group','163'),(835,52,'group','163'),(836,53,'group','163'),(837,54,'group','163'),(838,55,'group','163'),(839,56,'group','163'),(840,57,'group','163'),(841,95,'group','164'),(842,96,'group','164'),(843,97,'group','164'),(844,98,'group','164'),(845,99,'group','164'),(846,100,'group','164'),(847,101,'group','164'),(848,102,'group','164'),(849,103,'group','164'); +/*!40000 ALTER TABLE `wp_postmeta` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_posts` +-- + +DROP TABLE IF EXISTS `wp_posts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_posts` ( + `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `post_author` bigint(20) unsigned NOT NULL DEFAULT 0, + `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_content` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_title` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_excerpt` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'publish', + `comment_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open', + `ping_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open', + `post_password` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `post_name` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `to_ping` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `pinged` text COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `post_content_filtered` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `post_parent` bigint(20) unsigned NOT NULL DEFAULT 0, + `guid` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `menu_order` int(11) NOT NULL DEFAULT 0, + `post_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'post', + `post_mime_type` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `comment_count` bigint(20) NOT NULL DEFAULT 0, + PRIMARY KEY (`ID`), + KEY `post_name` (`post_name`(191)), + KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`), + KEY `post_parent` (`post_parent`), + KEY `post_author` (`post_author`) +) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_posts` +-- + +LOCK TABLES `wp_posts` WRITE; +/*!40000 ALTER TABLE `wp_posts` DISABLE KEYS */; +INSERT INTO `wp_posts` VALUES (4,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_post_meta','','publish','closed','closed','','test_post_meta','','','2019-07-06 00:23:10','2019-07-06 00:23:10','',0,'http://wordpress.test/?post_type=_pods_pod&p=4',0,'_pods_pod','',0),(5,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=5',0,'_pods_field','',0),(6,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=6',1,'_pods_field','',0),(7,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=7',2,'_pods_field','',0),(8,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=8',3,'_pods_field','',0),(9,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=9',4,'_pods_field','',0),(10,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=10',5,'_pods_field','',0),(11,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=11',6,'_pods_field','',0),(12,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',4,'http://wordpress.test/?post_type=_pods_field&p=12',7,'_pods_field','',0),(13,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_post_table','','publish','closed','closed','','test_post_table','','','2019-07-06 00:23:10','2019-07-06 00:23:10','',0,'http://wordpress.test/?post_type=_pods_pod&p=13',0,'_pods_pod','',0),(14,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=14',0,'_pods_field','',0),(15,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=15',1,'_pods_field','',0),(16,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=16',2,'_pods_field','',0),(17,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=17',3,'_pods_field','',0),(18,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=18',4,'_pods_field','',0),(19,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=19',5,'_pods_field','',0),(20,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=20',6,'_pods_field','',0),(21,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test/?post_type=_pods_field&p=21',7,'_pods_field','',0),(22,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','post','','publish','closed','closed','','post','','','2019-07-06 00:23:10','2019-07-06 00:23:10','',0,'http://wordpress.test/?post_type=_pods_pod&p=22',0,'_pods_pod','',0),(23,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=23',0,'_pods_field','',0),(24,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=24',1,'_pods_field','',0),(25,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=25',2,'_pods_field','',0),(26,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=26',3,'_pods_field','',0),(27,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=27',4,'_pods_field','',0),(28,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=28',5,'_pods_field','',0),(29,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=29',6,'_pods_field','',0),(30,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test/?post_type=_pods_field&p=30',7,'_pods_field','',0),(31,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','page','','publish','closed','closed','','page','','','2019-07-06 00:23:10','2019-07-06 00:23:10','',0,'http://wordpress.test/?post_type=_pods_pod&p=31',0,'_pods_pod','',0),(32,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=32',0,'_pods_field','',0),(33,0,'2019-07-06 00:23:10','2019-07-06 00:23:10','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=33',1,'_pods_field','',0),(34,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=34',2,'_pods_field','',0),(35,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=35',3,'_pods_field','',0),(36,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=36',4,'_pods_field','',0),(37,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=37',5,'_pods_field','',0),(38,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=38',6,'_pods_field','',0),(39,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test/?post_type=_pods_field&p=39',7,'_pods_field','',0),(40,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','nav_menu_item','','publish','closed','closed','','nav_menu_item','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=40',0,'_pods_pod','',0),(41,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',40,'http://wordpress.test/?post_type=_pods_field&p=41',0,'_pods_field','',0),(42,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',40,'http://wordpress.test/?post_type=_pods_field&p=42',1,'_pods_field','',0),(43,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:23','2020-05-23 02:18:23','',40,'http://wordpress.test/?post_type=_pods_field&p=43',2,'_pods_field','',0),(44,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:23','2020-05-23 02:18:23','',40,'http://wordpress.test/?post_type=_pods_field&p=44',3,'_pods_field','',0),(45,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:23','2020-05-23 02:18:23','',40,'http://wordpress.test/?post_type=_pods_field&p=45',4,'_pods_field','',0),(46,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:23','2020-05-23 02:18:23','',40,'http://wordpress.test/?post_type=_pods_field&p=46',5,'_pods_field','',0),(47,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:23','2020-05-23 02:18:23','',40,'http://wordpress.test/?post_type=_pods_field&p=47',6,'_pods_field','',0),(48,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:23','2020-05-23 02:18:23','',40,'http://wordpress.test/?post_type=_pods_field&p=48',7,'_pods_field','',0),(49,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_tax_table','','publish','closed','closed','','test_tax_table','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=49',0,'_pods_pod','',0),(50,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',49,'http://wordpress.test/?post_type=_pods_field&p=50',0,'_pods_field','',0),(51,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',49,'http://wordpress.test/?post_type=_pods_field&p=51',1,'_pods_field','',0),(52,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',49,'http://wordpress.test/?post_type=_pods_field&p=52',2,'_pods_field','',0),(53,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',49,'http://wordpress.test/?post_type=_pods_field&p=53',3,'_pods_field','',0),(54,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',49,'http://wordpress.test/?post_type=_pods_field&p=54',4,'_pods_field','',0),(55,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',49,'http://wordpress.test/?post_type=_pods_field&p=55',5,'_pods_field','',0),(56,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',49,'http://wordpress.test/?post_type=_pods_field&p=56',6,'_pods_field','',0),(57,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',49,'http://wordpress.test/?post_type=_pods_field&p=57',7,'_pods_field','',0),(58,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_tax_meta','','publish','closed','closed','','test_tax_meta','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=58',0,'_pods_pod','',0),(59,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=59',0,'_pods_field','',0),(60,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=60',1,'_pods_field','',0),(61,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=61',2,'_pods_field','',0),(62,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=62',3,'_pods_field','',0),(63,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=63',4,'_pods_field','',0),(64,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=64',5,'_pods_field','',0),(65,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=65',6,'_pods_field','',0),(66,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test/?post_type=_pods_field&p=66',7,'_pods_field','',0),(67,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','category','','publish','closed','closed','','category','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=67',0,'_pods_pod','',0),(68,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=68',0,'_pods_field','',0),(69,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=69',1,'_pods_field','',0),(70,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=70',2,'_pods_field','',0),(71,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=71',3,'_pods_field','',0),(72,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=72',4,'_pods_field','',0),(73,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=73',5,'_pods_field','',0),(74,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=74',6,'_pods_field','',0),(75,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test/?post_type=_pods_field&p=75',7,'_pods_field','',0),(76,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','post_tag','','publish','closed','closed','','post_tag','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=76',0,'_pods_pod','',0),(77,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=77',0,'_pods_field','',0),(78,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=78',1,'_pods_field','',0),(79,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=79',2,'_pods_field','',0),(80,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=80',3,'_pods_field','',0),(81,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=81',4,'_pods_field','',0),(82,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=82',5,'_pods_field','',0),(83,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=83',6,'_pods_field','',0),(84,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test/?post_type=_pods_field&p=84',7,'_pods_field','',0),(85,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','nav_menu','','publish','closed','closed','','nav_menu','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=85',0,'_pods_pod','',0),(86,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=86',0,'_pods_field','',0),(87,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=87',1,'_pods_field','',0),(88,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=88',2,'_pods_field','',0),(89,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=89',3,'_pods_field','',0),(90,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=90',4,'_pods_field','',0),(91,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=91',5,'_pods_field','',0),(92,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=92',6,'_pods_field','',0),(93,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test/?post_type=_pods_field&p=93',7,'_pods_field','',0),(94,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','user','','publish','closed','closed','','user','','','2019-07-06 00:23:11','2019-07-06 00:23:11','',0,'http://wordpress.test/?post_type=_pods_pod&p=94',0,'_pods_pod','',0),(95,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=95',0,'_pods_field','',0),(96,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=96',1,'_pods_field','',0),(97,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=97',2,'_pods_field','',0),(98,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=98',3,'_pods_field','',0),(99,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=99',4,'_pods_field','',0),(100,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=100',5,'_pods_field','',0),(101,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test/?post_type=_pods_field&p=101',6,'_pods_field','',0),(102,0,'2019-07-06 00:23:11','2019-07-06 00:23:11','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:49','2020-05-23 02:18:49','',94,'http://wordpress.test/?post_type=_pods_field&p=102',7,'_pods_field','',0),(103,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','avatar','','publish','closed','closed','','avatar','','','2020-05-23 02:18:49','2020-05-23 02:18:49','',94,'http://wordpress.test/?post_type=_pods_field&p=103',8,'_pods_field','',0),(104,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','media','','publish','closed','closed','','media','','','2019-07-06 00:23:12','2019-07-06 00:23:12','',0,'http://wordpress.test/?post_type=_pods_pod&p=104',0,'_pods_pod','',0),(105,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=105',0,'_pods_field','',0),(106,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=106',1,'_pods_field','',0),(107,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=107',2,'_pods_field','',0),(108,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=108',3,'_pods_field','',0),(109,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=109',4,'_pods_field','',0),(110,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=110',5,'_pods_field','',0),(111,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=111',6,'_pods_field','',0),(112,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test/?post_type=_pods_field&p=112',7,'_pods_field','',0),(113,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','comment','','publish','closed','closed','','comment','','','2019-07-06 00:23:12','2019-07-06 00:23:12','',0,'http://wordpress.test/?post_type=_pods_pod&p=113',0,'_pods_pod','',0),(114,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=114',0,'_pods_field','',0),(115,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=115',1,'_pods_field','',0),(116,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=116',2,'_pods_field','',0),(117,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=117',3,'_pods_field','',0),(118,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=118',4,'_pods_field','',0),(119,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=119',5,'_pods_field','',0),(120,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=120',6,'_pods_field','',0),(121,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test/?post_type=_pods_field&p=121',7,'_pods_field','',0),(122,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_act','','publish','closed','closed','','test_act','','','2019-07-06 00:23:12','2019-07-06 00:23:12','',0,'http://wordpress.test/?post_type=_pods_pod&p=122',0,'_pods_pod','',0),(123,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_user','','publish','closed','closed','','test_rel_user','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=123',0,'_pods_field','',0),(124,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_post','','publish','closed','closed','','test_rel_post','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=124',1,'_pods_field','',0),(125,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_pages','','publish','closed','closed','','test_rel_pages','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=125',2,'_pods_field','',0),(126,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_tag','','publish','closed','closed','','test_rel_tag','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=126',3,'_pods_field','',0),(127,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_media','','publish','closed','closed','','test_rel_media','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=127',4,'_pods_field','',0),(128,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_comment','','publish','closed','closed','','test_rel_comment','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=128',5,'_pods_field','',0),(129,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_rel_act','','publish','closed','closed','','test_rel_act','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=129',6,'_pods_field','',0),(130,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_text_field','','publish','closed','closed','','test_text_field','','','2019-07-06 00:23:12','2019-07-06 00:23:12','',122,'http://wordpress.test/?post_type=_pods_field&p=130',7,'_pods_field','',0),(131,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','name','','publish','closed','closed','','name','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=131',8,'_pods_field','',0),(132,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','permalink','','publish','closed','closed','','permalink','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=132',9,'_pods_field','',0),(133,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','test_text_field','','publish','closed','closed','','test_text_field','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=133',10,'_pods_field','',0),(134,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','','author','','publish','closed','closed','','author','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test/?post_type=_pods_field&p=134',11,'_pods_field','',0),(135,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','957094053317a49eb5f8db0bc71430da','Related post 957094053317a49eb5f8db0bc71430da','','publish','open','open','','related-post-957094053317a49eb5f8db0bc71430da','','','2019-07-06 00:23:13','2019-07-06 00:23:13','',0,'http://wordpress.test/?p=135',0,'post','',0),(136,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','f820300a0ff832c3a0b9cd9a6f2bf7ba','Related page f820300a0ff832c3a0b9cd9a6f2bf7ba','','publish','open','open','','related-page-f820300a0ff832c3a0b9cd9a6f2bf7ba','','','2019-07-06 00:23:12','2019-07-06 00:23:12','',0,'http://wordpress.test/?page_id=136',0,'page','',0),(137,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','b56642438d7bc780f732c893356d9897','Related page 2 b56642438d7bc780f732c893356d9897','','publish','open','open','','related-page-2-b56642438d7bc780f732c893356d9897','','','2019-07-06 00:23:13','2019-07-06 00:23:13','',0,'http://wordpress.test/?page_id=137',0,'page','',0),(138,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','08fc45387cdce771f30cf311ae34fa17','Related media','','inherit','open','closed','','ee00b7f0e64c35bc6463829c7c9e1f22','','','2019-07-06 00:23:13','2019-07-06 00:23:13','',0,'http://wordpress.test/wp-content/uploads/2019/07/ee00b7f0e64c35bc6463829c7c9e1f22-180.png',0,'attachment','image/png',0),(139,0,'2019-07-06 00:23:12','2019-07-06 00:23:12','b583076ded12c15bc9e87d7057a18180','Related avatar','','inherit','open','closed','','ee00b7f0e64c35bc6463829c7c9e1f22-2','','','2019-07-06 00:23:13','2019-07-06 00:23:13','',0,'http://wordpress.test/wp-content/uploads/2019/07/ee00b7f0e64c35bc6463829c7c9e1f22-181.png',0,'attachment','image/png',0),(140,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','957094053317a49eb5f8db0bc71430da','Related post 957094053317a49eb5f8db0bc71430da','','inherit','closed','closed','','135-revision-v1','','','2019-07-06 00:23:13','2019-07-06 00:23:13','',135,'http://wordpress.test/?p=140',0,'revision','',0),(141,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','b56642438d7bc780f732c893356d9897','Related page 2 b56642438d7bc780f732c893356d9897','','inherit','closed','closed','','137-revision-v1','','','2019-07-06 00:23:13','2019-07-06 00:23:13','',137,'http://wordpress.test/?p=141',0,'revision','',0),(142,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','','Testing index a66d982c8099d014bc1fa2937e55c912','','publish','open','open','','testing-index-a66d982c8099d014bc1fa2937e55c912','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',0,'http://wordpress.test/?test_post_meta=testing-index-a66d982c8099d014bc1fa2937e55c912',0,'test_post_meta','',0),(143,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','','Testing index fd1100433cbdb1a88065aa30720e3b40','','publish','open','open','','testing-index-fd1100433cbdb1a88065aa30720e3b40','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',0,'http://wordpress.test/?test_post_table=testing-index-fd1100433cbdb1a88065aa30720e3b40',0,'test_post_table','',0),(144,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','','Testing index 5999153530660d496e23b334a6befe6d','','publish','open','open','','testing-index-5999153530660d496e23b334a6befe6d','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',0,'http://wordpress.test/?p=144',0,'post','',0),(145,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','','Testing index 6dbbdb9022e2d0cd9a3664e421571379','','publish','open','open','','testing-index-6dbbdb9022e2d0cd9a3664e421571379','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',0,'http://wordpress.test/?page_id=145',0,'page','',0),(146,0,'2019-07-06 00:23:13','2019-07-06 00:23:13','','Testing index 25b0cd30b4b87446f5bf1695769cd47d','','publish','open','open','','testing-index-25b0cd30b4b87446f5bf1695769cd47d','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',0,'http://wordpress.test/?p=146',0,'nav_menu_item','',0),(147,0,'2019-07-06 00:23:14','2019-07-06 00:23:14','','Testing index 14228bf1d952618086f315a46a57a05a','','inherit','open','open','','testing-index-14228bf1d952618086f315a46a57a05a','','','2019-07-06 00:23:15','2019-07-06 00:23:15','',0,'http://wordpress.test/?attachment_id=147',0,'attachment','',0),(148,0,'2019-07-06 00:23:14','2019-07-06 00:23:14','','Testing index 5999153530660d496e23b334a6befe6d','','inherit','closed','closed','','144-revision-v1','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',144,'http://wordpress.test/?p=148',0,'revision','',0),(149,0,'2019-07-06 00:23:14','2019-07-06 00:23:14','','Testing index 6dbbdb9022e2d0cd9a3664e421571379','','inherit','closed','closed','','145-revision-v1','','','2019-07-06 00:23:14','2019-07-06 00:23:14','',145,'http://wordpress.test/?p=149',0,'revision','',0),(150,1,'2020-05-23 02:16:05','0000-00-00 00:00:00','','Auto Draft','','auto-draft','open','open','','','','','2020-05-23 02:16:05','0000-00-00 00:00:00','',0,'http://wordpress.test:8888/?p=150',0,'post','',0),(151,1,'2020-05-23 02:18:19','2020-05-23 02:18:19','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:19','2020-05-23 02:18:19','',67,'http://wordpress.test:8888/?post_type=_pods_group&p=151',0,'_pods_group','',0),(152,1,'2020-05-23 02:18:20','2020-05-23 02:18:20','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:20','2020-05-23 02:18:20','',113,'http://wordpress.test:8888/?post_type=_pods_group&p=152',0,'_pods_group','',0),(153,1,'2020-05-23 02:18:21','2020-05-23 02:18:21','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:21','2020-05-23 02:18:21','',104,'http://wordpress.test:8888/?post_type=_pods_group&p=153',0,'_pods_group','',0),(154,1,'2020-05-23 02:18:22','2020-05-23 02:18:22','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',85,'http://wordpress.test:8888/?post_type=_pods_group&p=154',0,'_pods_group','',0),(155,1,'2020-05-23 02:18:22','2020-05-23 02:18:22','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:22','2020-05-23 02:18:22','',40,'http://wordpress.test:8888/?post_type=_pods_group&p=155',0,'_pods_group','',0),(156,1,'2020-05-23 02:18:24','2020-05-23 02:18:24','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:24','2020-05-23 02:18:24','',31,'http://wordpress.test:8888/?post_type=_pods_group&p=156',0,'_pods_group','',0),(157,1,'2020-05-23 02:18:41','2020-05-23 02:18:41','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:41','2020-05-23 02:18:41','',22,'http://wordpress.test:8888/?post_type=_pods_group&p=157',0,'_pods_group','',0),(158,1,'2020-05-23 02:18:42','2020-05-23 02:18:42','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:42','2020-05-23 02:18:42','',76,'http://wordpress.test:8888/?post_type=_pods_group&p=158',0,'_pods_group','',0),(159,1,'2020-05-23 02:18:43','2020-05-23 02:18:43','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:43','2020-05-23 02:18:43','',122,'http://wordpress.test:8888/?post_type=_pods_group&p=159',0,'_pods_group','',0),(160,1,'2020-05-23 02:18:45','2020-05-23 02:18:45','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:45','2020-05-23 02:18:45','',4,'http://wordpress.test:8888/?post_type=_pods_group&p=160',0,'_pods_group','',0),(161,1,'2020-05-23 02:18:46','2020-05-23 02:18:46','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:46','2020-05-23 02:18:46','',13,'http://wordpress.test:8888/?post_type=_pods_group&p=161',0,'_pods_group','',0),(162,1,'2020-05-23 02:18:47','2020-05-23 02:18:47','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',58,'http://wordpress.test:8888/?post_type=_pods_group&p=162',0,'_pods_group','',0),(163,1,'2020-05-23 02:18:47','2020-05-23 02:18:47','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:47','2020-05-23 02:18:47','',49,'http://wordpress.test:8888/?post_type=_pods_group&p=163',0,'_pods_group','',0),(164,1,'2020-05-23 02:18:48','2020-05-23 02:18:48','','More Fields','','publish','closed','closed','','more-fields','','','2020-05-23 02:18:48','2020-05-23 02:18:48','',94,'http://wordpress.test:8888/?post_type=_pods_group&p=164',0,'_pods_group','',0); +/*!40000 ALTER TABLE `wp_posts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_term_relationships` +-- + +DROP TABLE IF EXISTS `wp_term_relationships`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_term_relationships` ( + `object_id` bigint(20) unsigned NOT NULL DEFAULT 0, + `term_taxonomy_id` bigint(20) unsigned NOT NULL DEFAULT 0, + `term_order` int(11) NOT NULL DEFAULT 0, + PRIMARY KEY (`object_id`,`term_taxonomy_id`), + KEY `term_taxonomy_id` (`term_taxonomy_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_term_relationships` +-- + +LOCK TABLES `wp_term_relationships` WRITE; +/*!40000 ALTER TABLE `wp_term_relationships` DISABLE KEYS */; +INSERT INTO `wp_term_relationships` VALUES (135,1,0),(135,3,0),(137,3,0),(142,3,0),(143,3,0),(144,1,0),(144,3,0),(145,3,0),(146,3,0); +/*!40000 ALTER TABLE `wp_term_relationships` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_term_taxonomy` +-- + +DROP TABLE IF EXISTS `wp_term_taxonomy`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_term_taxonomy` ( + `term_taxonomy_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `term_id` bigint(20) unsigned NOT NULL DEFAULT 0, + `taxonomy` varchar(32) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `description` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, + `parent` bigint(20) unsigned NOT NULL DEFAULT 0, + `count` bigint(20) NOT NULL DEFAULT 0, + PRIMARY KEY (`term_taxonomy_id`), + UNIQUE KEY `term_id_taxonomy` (`term_id`,`taxonomy`), + KEY `taxonomy` (`taxonomy`) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_term_taxonomy` +-- + +LOCK TABLES `wp_term_taxonomy` WRITE; +/*!40000 ALTER TABLE `wp_term_taxonomy` DISABLE KEYS */; +INSERT INTO `wp_term_taxonomy` VALUES (1,1,'category','',0,2),(2,2,'post_tag','fb48dd92f3198ce5cfeac554c9fb2867',0,0),(3,3,'test_non_pod_ct','b74803a4123e24ba97271d983b00419d',0,7),(4,4,'test_tax_table','',0,0),(5,5,'test_tax_meta','',0,0),(6,6,'category','',0,0),(7,7,'post_tag','',0,0),(8,8,'nav_menu','',0,0); +/*!40000 ALTER TABLE `wp_term_taxonomy` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_termmeta` +-- + +DROP TABLE IF EXISTS `wp_termmeta`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_termmeta` ( + `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `term_id` bigint(20) unsigned NOT NULL DEFAULT 0, + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`meta_id`), + KEY `term_id` (`term_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB AUTO_INCREMENT=156 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_termmeta` +-- + +LOCK TABLES `wp_termmeta` WRITE; +/*!40000 ALTER TABLE `wp_termmeta` DISABLE KEYS */; +INSERT INTO `wp_termmeta` VALUES (1,2,'avatar','0'),(2,2,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(4,2,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(6,2,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(9,2,'_index','Related post tag fb48dd92f3198ce5cfeac554c9fb2867'),(10,2,'_items','a:1:{i:2;a:11:{s:4:\"name\";s:49:\"Related post tag fb48dd92f3198ce5cfeac554c9fb2867\";s:11:\"description\";s:32:\"fb48dd92f3198ce5cfeac554c9fb2867\";s:15:\"test_text_field\";s:60:\"Test related tag text field fb48dd92f3198ce5cfeac554c9fb2867\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:3:\"135\";s:14:\"test_rel_pages\";a:2:{i:136;s:3:\"136\";i:137;s:3:\"137\";}s:12:\"test_rel_tag\";s:1:\"0\";s:14:\"test_rel_media\";s:1:\"0\";s:16:\"test_rel_comment\";s:1:\"0\";s:12:\"test_rel_act\";s:1:\"0\";s:6:\"avatar\";s:1:\"0\";}}'),(11,2,'_field_id','term_id'),(12,2,'_field_index','name'),(13,2,'test_rel_user','2'),(14,2,'test_rel_post','135'),(15,2,'test_rel_pages','136'),(16,2,'test_rel_pages','137'),(17,2,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(18,2,'test_rel_tag','2'),(19,2,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(20,2,'test_rel_media','138'),(21,2,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(22,2,'test_rel_comment','2'),(23,2,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(24,2,'test_rel_act','1'),(25,4,'avatar','0'),(26,4,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(28,4,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(30,4,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(33,4,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(35,4,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(37,4,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(39,4,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(41,5,'avatar','0'),(42,5,'test_text_field','Testing 61f604e848ee443d6747bb464a883a1e'),(43,5,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(45,5,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(47,5,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(50,5,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(52,5,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(54,5,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(56,5,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(58,6,'avatar','0'),(59,6,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(61,6,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(63,6,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(66,6,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(68,6,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(70,6,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(72,6,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(74,7,'avatar','0'),(75,7,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(77,7,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(79,7,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(82,7,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(84,7,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(86,7,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(88,7,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(90,8,'avatar','0'),(91,8,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(93,8,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(95,8,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(98,8,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(100,8,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(102,8,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(104,8,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(106,4,'_field_id','term_id'),(107,4,'_field_index','name'),(108,4,'test_rel_user','2'),(109,4,'test_rel_post','135'),(110,4,'test_rel_pages','136'),(111,4,'test_rel_pages','137'),(112,4,'test_rel_tag','2'),(113,4,'test_rel_media','138'),(114,4,'test_rel_comment','2'),(115,4,'test_rel_act','1'),(116,5,'_field_id','term_id'),(117,5,'_field_index','name'),(118,5,'test_rel_user','2'),(119,5,'test_rel_post','135'),(120,5,'test_rel_pages','136'),(121,5,'test_rel_pages','137'),(122,5,'test_rel_tag','2'),(123,5,'test_rel_media','138'),(124,5,'test_rel_comment','2'),(125,5,'test_rel_act','1'),(126,6,'_field_id','term_id'),(127,6,'_field_index','name'),(128,6,'test_rel_user','2'),(129,6,'test_rel_post','135'),(130,6,'test_rel_pages','136'),(131,6,'test_rel_pages','137'),(132,6,'test_rel_tag','2'),(133,6,'test_rel_media','138'),(134,6,'test_rel_comment','2'),(135,6,'test_rel_act','1'),(136,7,'_field_id','term_id'),(137,7,'_field_index','name'),(138,7,'test_rel_user','2'),(139,7,'test_rel_post','135'),(140,7,'test_rel_pages','136'),(141,7,'test_rel_pages','137'),(142,7,'test_rel_tag','2'),(143,7,'test_rel_media','138'),(144,7,'test_rel_comment','2'),(145,7,'test_rel_act','1'),(146,8,'_field_id','term_id'),(147,8,'_field_index','name'),(148,8,'test_rel_user','2'),(149,8,'test_rel_post','135'),(150,8,'test_rel_pages','136'),(151,8,'test_rel_pages','137'),(152,8,'test_rel_tag','2'),(153,8,'test_rel_media','138'),(154,8,'test_rel_comment','2'),(155,8,'test_rel_act','1'); +/*!40000 ALTER TABLE `wp_termmeta` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_terms` +-- + +DROP TABLE IF EXISTS `wp_terms`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_terms` ( + `term_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `slug` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `term_group` bigint(10) NOT NULL DEFAULT 0, + PRIMARY KEY (`term_id`), + KEY `slug` (`slug`(191)), + KEY `name` (`name`(191)) +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_terms` +-- + +LOCK TABLES `wp_terms` WRITE; +/*!40000 ALTER TABLE `wp_terms` DISABLE KEYS */; +INSERT INTO `wp_terms` VALUES (1,'Uncategorized','uncategorized',0),(2,'Related post tag fb48dd92f3198ce5cfeac554c9fb2867','related-post-tag-fb48dd92f3198ce5cfeac554c9fb2867',0),(3,'Non-Pod Term','non-pod-term',0),(4,'Testing index dd10ac7ca2da6c9ab585c0e2d22cb11b','testing-index-dd10ac7ca2da6c9ab585c0e2d22cb11b',0),(5,'Testing index 61f604e848ee443d6747bb464a883a1e','testing-index-61f604e848ee443d6747bb464a883a1e',0),(6,'Testing index f27f6aa87ec90698cc92add87c329889','testing-index-f27f6aa87ec90698cc92add87c329889',0),(7,'Testing index ec6294c1df2cae4b69b7158bd5b7e527','testing-index-ec6294c1df2cae4b69b7158bd5b7e527',0),(8,'Testing index b6e16087c5789b81d87ca565346fd337','testing-index-b6e16087c5789b81d87ca565346fd337',0); +/*!40000 ALTER TABLE `wp_terms` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_usermeta` +-- + +DROP TABLE IF EXISTS `wp_usermeta`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_usermeta` ( + `umeta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL DEFAULT 0, + `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + `meta_value` longtext COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, + PRIMARY KEY (`umeta_id`), + KEY `user_id` (`user_id`), + KEY `meta_key` (`meta_key`(191)) +) ENGINE=InnoDB AUTO_INCREMENT=145 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_usermeta` +-- + +LOCK TABLES `wp_usermeta` WRITE; +/*!40000 ALTER TABLE `wp_usermeta` DISABLE KEYS */; +INSERT INTO `wp_usermeta` VALUES (1,1,'nickname','admin'),(2,1,'first_name',''),(3,1,'last_name',''),(4,1,'description',''),(5,1,'rich_editing','true'),(6,1,'syntax_highlighting','true'),(7,1,'comment_shortcuts','false'),(8,1,'admin_color','fresh'),(9,1,'use_ssl','0'),(10,1,'show_admin_bar_front','true'),(11,1,'locale',''),(12,1,'wp_capabilities','a:1:{s:13:\"administrator\";b:1;}'),(13,1,'wp_user_level','10'),(14,1,'dismissed_wp_pointers',''),(15,1,'show_welcome_panel','1'),(16,2,'nickname','related-user'),(17,2,'first_name',''),(18,2,'last_name',''),(19,2,'description',''),(20,2,'rich_editing','true'),(21,2,'syntax_highlighting','true'),(22,2,'comment_shortcuts','false'),(23,2,'admin_color','fresh'),(24,2,'use_ssl','0'),(25,2,'show_admin_bar_front','true'),(26,2,'locale',''),(27,2,'test_capabilities','a:1:{s:10:\"subscriber\";b:1;}'),(28,2,'wp_user_level','0'),(29,2,'dismissed_wp_pointers',''),(30,2,'test_text_field','Test related user text field 03d5942f91be7863929f02c5287b439a'),(31,3,'nickname','related-author'),(32,3,'first_name',''),(33,3,'last_name',''),(34,3,'description',''),(35,3,'rich_editing','true'),(36,3,'syntax_highlighting','true'),(37,3,'comment_shortcuts','false'),(38,3,'admin_color','fresh'),(39,3,'use_ssl','0'),(40,3,'show_admin_bar_front','true'),(41,3,'locale',''),(42,3,'test_capabilities','a:1:{s:10:\"subscriber\";b:1;}'),(43,3,'wp_user_level','0'),(44,3,'dismissed_wp_pointers',''),(45,3,'test_text_field','Test related author text field fbd428d3fbb75b82756772e5a1428566'),(46,3,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(48,3,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(50,3,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(53,3,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(55,3,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(57,3,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(59,3,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(61,3,'_pods_avatar','a:1:{i:0;i:139;}'),(63,2,'_index','Related user 03d5942f91be7863929f02c5287b439a'),(64,2,'_items','a:1:{i:2;a:13:{s:12:\"display_name\";s:45:\"Related user 03d5942f91be7863929f02c5287b439a\";s:10:\"user_login\";s:12:\"related-user\";s:10:\"user_email\";s:16:\"related@user.com\";s:9:\"user_pass\";s:8:\"changeme\";s:15:\"test_text_field\";s:61:\"Test related user text field 03d5942f91be7863929f02c5287b439a\";s:13:\"test_rel_user\";s:1:\"0\";s:13:\"test_rel_post\";s:1:\"0\";s:14:\"test_rel_pages\";s:1:\"0\";s:12:\"test_rel_tag\";s:1:\"0\";s:14:\"test_rel_media\";s:1:\"0\";s:16:\"test_rel_comment\";s:1:\"0\";s:12:\"test_rel_act\";s:1:\"0\";s:6:\"avatar\";s:1:\"0\";}}'),(65,2,'_field_id','ID'),(66,2,'_field_index','display_name'),(67,2,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(68,2,'test_rel_user','2'),(69,2,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(70,2,'test_rel_post','135'),(71,2,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(72,2,'test_rel_pages','136'),(73,2,'test_rel_pages','137'),(74,2,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(75,2,'test_rel_tag','2'),(76,2,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(77,2,'test_rel_media','138'),(78,2,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(79,2,'test_rel_comment','2'),(80,2,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(81,2,'test_rel_act','1'),(82,2,'_pods_avatar','a:1:{i:0;i:139;}'),(83,2,'avatar','139'),(84,3,'_index','Related author fbd428d3fbb75b82756772e5a1428566'),(85,3,'_items','a:1:{i:3;a:13:{s:12:\"display_name\";s:47:\"Related author fbd428d3fbb75b82756772e5a1428566\";s:10:\"user_login\";s:14:\"related-author\";s:10:\"user_email\";s:15:\"author@user.com\";s:9:\"user_pass\";s:8:\"changeme\";s:15:\"test_text_field\";s:63:\"Test related author text field fbd428d3fbb75b82756772e5a1428566\";s:13:\"test_rel_user\";s:1:\"2\";s:13:\"test_rel_post\";s:3:\"135\";s:14:\"test_rel_pages\";a:2:{i:136;s:3:\"136\";i:137;s:3:\"137\";}s:12:\"test_rel_tag\";s:1:\"2\";s:14:\"test_rel_media\";s:3:\"138\";s:16:\"test_rel_comment\";s:1:\"2\";s:12:\"test_rel_act\";s:1:\"1\";s:6:\"avatar\";s:3:\"139\";}}'),(86,3,'_field_id','ID'),(87,3,'_field_index','display_name'),(88,3,'test_rel_user','2'),(89,3,'test_rel_post','135'),(90,3,'test_rel_pages','136'),(91,3,'test_rel_pages','137'),(92,3,'test_rel_tag','2'),(93,3,'test_rel_media','138'),(94,3,'test_rel_comment','2'),(95,3,'test_rel_act','1'),(96,3,'avatar','139'),(97,4,'nickname','User-f4d6ab3edb68db2f4399cb493a7b435b'),(98,4,'first_name',''),(99,4,'last_name',''),(100,4,'description',''),(101,4,'rich_editing','true'),(102,4,'syntax_highlighting','true'),(103,4,'comment_shortcuts','false'),(104,4,'admin_color','fresh'),(105,4,'use_ssl','0'),(106,4,'show_admin_bar_front','true'),(107,4,'locale',''),(108,4,'test_capabilities','a:1:{s:10:\"subscriber\";b:1;}'),(109,4,'wp_user_level','0'),(110,4,'dismissed_wp_pointers',''),(111,4,'test_text_field','Testing f4d6ab3edb68db2f4399cb493a7b435b'),(112,4,'_pods_test_rel_user','a:1:{i:0;i:2;}'),(114,4,'_pods_test_rel_post','a:1:{i:0;i:135;}'),(116,4,'_pods_test_rel_pages','a:2:{i:0;i:136;i:1;i:137;}'),(119,4,'_pods_test_rel_tag','a:1:{i:0;i:2;}'),(121,4,'_pods_test_rel_media','a:1:{i:0;i:138;}'),(123,4,'_pods_test_rel_comment','a:1:{i:0;i:2;}'),(125,4,'_pods_test_rel_act','a:1:{i:0;i:1;}'),(127,4,'_pods_avatar','a:1:{i:0;i:139;}'),(129,4,'_field_id','ID'),(130,4,'_field_index','display_name'),(131,4,'test_rel_user','2'),(132,4,'test_rel_post','135'),(133,4,'test_rel_pages','136'),(134,4,'test_rel_pages','137'),(135,4,'test_rel_tag','2'),(136,4,'test_rel_media','138'),(137,4,'test_rel_comment','2'),(138,4,'test_rel_act','1'),(139,4,'avatar','139'),(140,1,'session_tokens','a:2:{s:64:\"7ff96976dc7060bc22fdf5df534407fd2a5d0623b8f12013133df650f806a3c9\";a:4:{s:10:\"expiration\";i:1590372959;s:2:\"ip\";s:10:\"172.28.0.1\";s:2:\"ua\";s:121:\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36\";s:5:\"login\";i:1590200159;}s:64:\"46bcf98ccf6cee309ec472424c8d1f50e8f68af692778491f6b9f57530ff0fe7\";a:4:{s:10:\"expiration\";i:1590373198;s:2:\"ip\";s:10:\"172.28.0.1\";s:2:\"ua\";s:121:\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36\";s:5:\"login\";i:1590200398;}}'),(141,1,'wp_dashboard_quick_press_last_post_id','150'),(142,1,'community-events-location','a:1:{s:2:\"ip\";s:10:\"172.28.0.0\";}'),(143,1,'show_per_page','25'),(144,1,'orderby',''); +/*!40000 ALTER TABLE `wp_usermeta` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wp_users` +-- + +DROP TABLE IF EXISTS `wp_users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wp_users` ( + `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_login` varchar(60) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_pass` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_nicename` varchar(50) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_email` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_url` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_registered` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `user_activation_key` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + `user_status` int(11) NOT NULL DEFAULT 0, + `display_name` varchar(250) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', + PRIMARY KEY (`ID`), + KEY `user_login_key` (`user_login`), + KEY `user_nicename` (`user_nicename`), + KEY `user_email` (`user_email`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wp_users` +-- + +LOCK TABLES `wp_users` WRITE; +/*!40000 ALTER TABLE `wp_users` DISABLE KEYS */; +INSERT INTO `wp_users` VALUES (1,'admin','$P$BJ/Ms8oFmfCGEMSLdoZxzy6T217tyB.','admin','admin@wordpress.test','','2019-07-06 00:23:10','',0,'admin'),(2,'related-user','$P$BOOA3Oi7rbpHapbi7zQbeEBD2IlH7y/','related-user','related@user.com','','2019-07-06 00:23:12','',0,'Related user 03d5942f91be7863929f02c5287b439a'),(3,'related-author','$P$B74bcy5bENtC8jYe6dcEnIWlRz2dWs.','related-author','author@user.com','','2019-07-06 00:23:13','',0,'Related author fbd428d3fbb75b82756772e5a1428566'),(4,'User-f4d6ab3edb68db2f4399cb493a7b435b','$P$BF9Dnwz/HmxW5vBmSL5tw79gvCEEiA/','user-f4d6ab3edb68db2f4399cb493a7b435b','f4d6ab3edb68db2f4399cb493a7b435b@user.com','','2019-07-06 00:23:14','',0,'User f4d6ab3edb68db2f4399cb493a7b435b'); +/*!40000 ALTER TABLE `wp_users` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2020-05-23 2:20:16 diff --git a/tests/codeception/_data/images/zoltar.jpg b/tests/codeception/_data/images/zoltar.jpg new file mode 100644 index 0000000000..ef36a088b2 Binary files /dev/null and b/tests/codeception/_data/images/zoltar.jpg differ diff --git a/tests/codeception/_data/kitchen-sink-config.json b/tests/codeception/_data/kitchen-sink-config.json new file mode 100644 index 0000000000..33fafe3b7e --- /dev/null +++ b/tests/codeception/_data/kitchen-sink-config.json @@ -0,0 +1,5551 @@ +{ + "demo_long_title_for_tooltip": { + "name": "demo_long_title_for_tooltip", + "label": "Demo Extra-long Title on this field for testing the tooltip position", + "description": "max length 15", + "help": "The Query Var is used in the URL and underneath the WordPress Rewrite API to tell WordPress what page or post type you are on. For a list of reserved Query Vars, read WordPress Query Vars from the WordPress Codex.", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_boolean_group": { + "name": "demo_boolean_group", + "label": "Boolean Group", + "type": "boolean_group", + "boolean_group": [ + { + "name": "admin_only", + "label": "Restrict access to Admins", + "default": 0, + "type": "boolean", + "dependency": true, + "help": "This field will only be able to be edited by users with the ability to manage_options or delete_users, or super admins of a WordPress Multisite network" + }, + { + "name": "restrict_role", + "label": "Restrict access by Role", + "default": 0, + "type": "boolean", + "dependency": true + }, + { + "name": "restrict_capability", + "label": "Restrict access by Capability", + "default": 0, + "type": "boolean", + "dependency": true + }, + { + "name": "hidden", + "label": "Hide field from UI", + "default": 0, + "type": "boolean", + "help": "This option is overridden by access restrictions. If the user does not have access to edit this field, it will be \"hidden\" If no access restrictions are set, this field will always be \"hidden\"" + }, + { + "name": "read_only", + "label": "Make field \"Read Only\" in UI", + "default": 0, + "type": "boolean", + "help": "This option is overridden by access restrictions. If the user does not have access to edit this field, it will be read only. If no access restrictions are set, this field will always be read only.", + "depends-on": { + "demo_plain_text": [ + "Test 1", + "Test 2" + ] + } + } + ] + }, + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom_js": { + "name": "demo_datetime_custom_js", + "label": "Demo Date\/Time Custom JS", + "description": "mm-dd-yy jQuery date format, hh:mm tt A jQuery time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "mm-dd-yy", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss A", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_slider_default": { + "name": "demo_currency_slider_default", + "label": "Demo Currency Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "currency", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "slider", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "10", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_avatar_default_media_library_upload_tab": { + "name": "demo_single_avatar_default_media_library_upload_tab", + "label": "Demo Single Avatar Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "avatar", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_default_media_library_upload_tab_opt1": { + "name": "demo_single_avatar_default_media_library_upload_tab_opt1", + "label": "Demo Single Avatar Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "avatar", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "1", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_default_media_library_upload_tab_opt2": { + "name": "demo_single_avatar_default_media_library_upload_tab_opt2", + "label": "Demo Single Avatar Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "avatar", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "1", + "avatar_show_edit_link": "1", + "avatar_linked": "1", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_default_media_library_upload_tab_any_type": { + "name": "demo_single_avatar_default_media_library_upload_tab_any_type", + "label": "Demo Single Avatar Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "avatar", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "any", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_default_media_library_upload_tab_other": { + "name": "demo_single_avatar_default_media_library_upload_tab_other", + "label": "Demo Single Avatar Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "avatar", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "other", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_avatar_default_media_library_upload_tab_tiles": { + "name": "demo_single_avatar_default_media_library_upload_tab_tiles", + "label": "Demo Single Avatar Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "avatar", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "tiles", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_avatar_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single Avatar Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "avatar", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar Here", + "avatar_modal_title": "Attach a avatar here", + "avatar_modal_add_button": "Add Your Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_plupload": { + "name": "demo_single_avatar_plupload", + "label": "Demo Single Avatar Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "avatar", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "plupload", + "avatar_attachment_tab": "upload", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_single_avatar_media_library_and_media_library_tab": { + "name": "demo_single_avatar_media_library_and_media_library_tab", + "label": "Demo Single Avatar Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "avatar", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "avatar_format_type": "single", + "avatar_uploader": "attachment", + "avatar_attachment_tab": "browse", + "avatar_edit_title": "0", + "avatar_show_edit_link": "0", + "avatar_linked": "0", + "avatar_limit": "5", + "avatar_restrict_filesize": "10MB", + "avatar_type": "images", + "avatar_field_template": "rows", + "avatar_add_button": "Add Avatar", + "avatar_modal_title": "Attach a avatar", + "avatar_modal_add_button": "Add Avatar", + "avatar_wp_gallery_output": "0", + "avatar_wp_gallery_link": "post", + "avatar_wp_gallery_columns": "1", + "avatar_wp_gallery_random_sort": "0", + "avatar_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "avatar_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three\nfour|Option four\nfive|Option five\nsix|Option six\nseven|Option seven", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three\nfour|Option four\nfive|Option five\nsix|Option six\nseven|Option seven", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three\nfour|Option four\nfive|Option five\nsix|Option six\nseven|Option seven", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three\nfour|Option four\nfive|Option five\nsix|Option six\nseven|Option seven", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three\nfour|Option four\nfive|Option five\nsix|Option six\nseven|Option seven", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_post_statuses": { + "name": "demo_relationship_post_statuses", + "label": "Demo Relationship Post Statuses", + "description": "single", + "help": "", + "class": "", + "type": "pick", + "weight": 107, + "pick_object": "post-status", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "0", + "pick_taggable": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_single_autocomplete": { + "name": "demo_relationship_pages_single_autocomplete", + "label": "Demo Relationship Pages Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_single_autocomplete_tag": { + "name": "demo_relationship_pages_single_autocomplete_tag", + "label": "Demo Relationship Pages Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_multiple_autocomplete_0": { + "name": "demo_relationship_pages_multiple_autocomplete_0", + "label": "Demo Relationship Pages Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_multiple_autocomplete_5": { + "name": "demo_relationship_pages_multiple_autocomplete_5", + "label": "Demo Relationship Pages Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + }, + "demo_heading_field": { + "name": "demo_heading_field", + "label": "Demo Heading Field", + "description": "", + "help": "", + "class": "", + "type": "heading", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2" + }, + "demo_html_field": { + "name": "demo_html_field", + "label": "Demo HTML Field", + "description": "", + "html_content": "Here is the field and it has HTML content", + "help": "", + "class": "", + "type": "html", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2" + }, + "demo_html_field_no_label": { + "name": "demo_html_field_no_label", + "label": "Demo HTML Field No Label", + "description": "", + "html_content": "Here is the field and it has HTML content", + "html_no_label": "1", + "help": "", + "class": "", + "type": "html", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2" + } +} diff --git a/tests/codeception/_data/kitchen-sink-package.json b/tests/codeception/_data/kitchen-sink-package.json new file mode 100644 index 0000000000..d0aa04636f --- /dev/null +++ b/tests/codeception/_data/kitchen-sink-package.json @@ -0,0 +1,32978 @@ +{ + "meta": { + "version": "2.7.22", + "build": 1599437003 + }, + "pods": { + "kitchen_cpt": { + "name": "kitchen_cpt", + "label": "Kitchen CPT", + "description": "", + "type": "post_type", + "storage": "meta", + "object": "", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_post_statuses": { + "name": "demo_relationship_post_statuses", + "label": "Demo Relationship Post Statuses", + "description": "single", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post-status", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_single_autocomplete": { + "name": "demo_relationship_pages_single_autocomplete", + "label": "Demo Relationship Pages Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_single_autocomplete_tag": { + "name": "demo_relationship_pages_single_autocomplete_tag", + "label": "Demo Relationship Pages Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_multiple_autocomplete_0": { + "name": "demo_relationship_pages_multiple_autocomplete_0", + "label": "Demo Relationship Pages Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages_multiple_autocomplete_5": { + "name": "demo_relationship_pages_multiple_autocomplete_5", + "label": "Demo Relationship Pages Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "pick_custom": "", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "Kitchen CPT", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "kitchen_cpt", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + }, + "kitchen_ct": { + "name": "kitchen_ct", + "label": "Kitchen CT", + "description": "", + "type": "taxonomy", + "storage": "meta", + "object": "", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "h:i:s A", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "Kitchen CT", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "kitchen_ct", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + }, + "user": { + "name": "user", + "label": "User", + "description": "", + "type": "user", + "storage": "meta", + "object": "user", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "h:i:s A", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "User", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "user", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + }, + "media": { + "name": "media", + "label": "Media", + "description": "", + "type": "media", + "storage": "meta", + "object": "", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "h:i:s A", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "Media", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "media", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + }, + "comment": { + "name": "comment", + "label": "Comment", + "description": "", + "type": "comment", + "storage": "meta", + "object": "comment", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "h:i:s A", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "Comment", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "comment", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + }, + "kitchen_settings": { + "name": "kitchen_settings", + "label": "Kitchen Settings", + "description": "", + "type": "settings", + "storage": "", + "object": "", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "h:i:s A", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "Kitchen Settings", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "kitchen_settings", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + }, + "kitchen_act": { + "name": "kitchen_act", + "label": "Kitchen ACT", + "description": "", + "type": "pod", + "storage": "table", + "object": "", + "alias": "", + "fields": { + "demo_plain_text": { + "name": "demo_plain_text", + "label": "Demo Plain Text", + "description": "max length 15", + "help": "", + "class": "", + "type": "text", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "text_allow_shortcode": "0", + "text_allow_html": "0", + "text_allowed_html_tags": "strong em a ul ol li b i", + "text_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "text_repeatable": "0", + "text_placeholder": "" + }, + "demo_website": { + "name": "demo_website", + "label": "Demo Website", + "description": "max length 30", + "help": "", + "class": "", + "type": "website", + "weight": 1, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0", + "website_placeholder": "" + }, + "demo_website_html5": { + "name": "demo_website_html5", + "label": "Demo Website HTML5", + "description": "max length 30 w\/ placeholder", + "help": "", + "class": "", + "type": "website", + "weight": 2, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "website_format": "normal", + "website_allow_port": "0", + "website_clickable": "0", + "website_new_window": "0", + "website_max_length": "30", + "website_html5": "1", + "website_placeholder": "Enter Website", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "website_repeatable": "0" + }, + "demo_phone_us_dash": { + "name": "demo_phone_us_dash", + "label": "Demo Phone US Dash", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 3, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_html5": { + "name": "demo_phone_us_dash_html5", + "label": "Demo Phone US Dash HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 4, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext": { + "name": "demo_phone_us_dash_ext", + "label": "Demo Phone US Dash Ext", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 5, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dash_ext_html5": { + "name": "demo_phone_us_dash_ext_html5", + "label": "Demo Phone US Dash Ext HTML5", + "description": "max length 25 using dash", + "help": "", + "class": "", + "type": "phone", + "weight": 6, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999-999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis": { + "name": "demo_phone_us_parenthesis", + "label": "Demo Phone US Parenthesis", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 7, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_ext": { + "name": "demo_phone_us_parenthesis_ext", + "label": "Demo Phone US Parenthesis Ext", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 8, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_parenthesis_html5": { + "name": "demo_phone_us_parenthesis_html5", + "label": "Demo Phone US Parenthesis HTML5", + "description": "max length 25 using dash\/parenthesis", + "help": "", + "class": "", + "type": "phone", + "weight": 9, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "(999) 999-9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot": { + "name": "demo_phone_us_dot", + "label": "Demo Phone US Dot", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 10, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_ext": { + "name": "demo_phone_us_dot_ext", + "label": "Demo Phone US Dot Ext", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 11, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_us_dot_html5": { + "name": "demo_phone_us_dot_html5", + "label": "Demo Phone US Dot HTML5", + "description": "max length 25 using dot", + "help": "", + "class": "", + "type": "phone", + "weight": 12, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "999.999.9999 x999", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international": { + "name": "demo_phone_international", + "label": "Demo Phone International", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 13, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_ext": { + "name": "demo_phone_international_ext", + "label": "Demo Phone International Ext", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 14, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "1", + "phone_max_length": "25", + "phone_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_phone_international_html5": { + "name": "demo_phone_international_html5", + "label": "Demo Phone International HTML5", + "description": "max length 25", + "help": "", + "class": "", + "type": "phone", + "weight": 15, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "phone_format": "international", + "phone_enable_phone_extension": "0", + "phone_max_length": "25", + "phone_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "phone_repeatable": "0", + "phone_placeholder": "" + }, + "demo_e-mail": { + "name": "demo_e-mail", + "label": "Demo E-mail", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 16, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0", + "email_placeholder": "" + }, + "demo_e-mail_html5": { + "name": "demo_e-mail_html5", + "label": "Demo E-mail HTML5 Placeholder", + "description": "max 30", + "help": "", + "class": "", + "type": "email", + "weight": 17, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "email_max_length": "30", + "email_html5": "1", + "email_placeholder": "Enter E-mail Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "email_repeatable": "0" + }, + "demo_password": { + "name": "demo_password", + "label": "Demo Password", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 18, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "password_placeholder": "" + }, + "demo_password_w_placeholder": { + "name": "demo_password_w_placeholder", + "label": "Demo Password w\/ Placeholder", + "description": "max 15", + "help": "", + "class": "", + "type": "password", + "weight": 19, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "password_max_length": "15", + "password_placeholder": "Enter Password Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_plain_paragraph_text": { + "name": "demo_plain_paragraph_text", + "label": "Demo Plain Paragraph Text", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 20, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0", + "paragraph_placeholder": "" + }, + "demo_plain_paragraph_text_placeholder": { + "name": "demo_plain_paragraph_text_placeholder", + "label": "Demo Plain Paragraph Text Placeholder", + "description": "max 150", + "help": "", + "class": "", + "type": "paragraph", + "weight": 21, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "paragraph_allow_html": "1", + "paragraph_oembed": "0", + "paragraph_wptexturize": "1", + "paragraph_convert_chars": "1", + "paragraph_wpautop": "1", + "paragraph_allow_shortcode": "0", + "paragraph_allowed_html_tags": "strong em a ul ol li b i", + "paragraph_max_length": "150", + "paragraph_placeholder": "Enter Text Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "paragraph_repeatable": "0" + }, + "demo_wysiwyg_tinymce": { + "name": "demo_wysiwyg_tinymce", + "label": "Demo WYSIWYG TinyMCE", + "description": "height 100", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 22, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "0", + "wysiwyg_editor_height": "100", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_tinymce_wmedia_buttons": { + "name": "demo_wysiwyg_tinymce_wmedia_buttons", + "label": "Demo WYSIWYG TinyMCE w\/Media Buttons", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 23, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_wysiwyg_cleditor": { + "name": "demo_wysiwyg_cleditor", + "label": "Demo WYSIWYG CLEditor", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 24, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "wysiwyg_editor": "cleditor", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "wysiwyg_repeatable": "0", + "wysiwyg_editor_height": "", + "wysiwyg_allowed_html_tags": "" + }, + "demo_code": { + "name": "demo_code", + "label": "Demo Code", + "description": "max length 100", + "help": "", + "class": "", + "type": "code", + "weight": 25, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "100", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_code_no_limit": { + "name": "demo_code_no_limit", + "label": "Demo Code No Limit", + "description": "no limit", + "help": "", + "class": "", + "type": "code", + "weight": 26, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "code_allow_shortcode": "0", + "code_max_length": "-1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "code_repeatable": "0" + }, + "demo_datetime_wp_default": { + "name": "demo_datetime_wp_default", + "label": "Demo Date\/Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 27, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_year_range_static": { + "name": "demo_datetime_wp_default_year_range_static", + "label": "Demo Date\/Time WP Default Year Range static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "datetime", + "weight": 28, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "2010:2015", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_year_range_relative": { + "name": "demo_datetime_wp_default_year_range_relative", + "label": "Demo Date\/Time WP Default Year Range Relative", + "description": "Year Range -1:+3", + "help": "", + "class": "", + "type": "datetime", + "weight": 29, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_year_range_custom": "-1:+3", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "" + }, + "demo_datetime_wp_default_wempty_value": { + "name": "demo_datetime_wp_default_wempty_value", + "label": "Demo Date\/Time WP Default w\/Empty Value", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 30, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "1", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_wp_default_html5": { + "name": "demo_datetime_wp_default_html5", + "label": "Demo Date\/Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 31, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mm-dd-yyyy": { + "name": "demo_datetime_mm-dd-yyyy", + "label": "Demo Date\/Time mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 32, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy_dash", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_mmddyyyy": { + "name": "demo_datetime_mmddyyyy", + "label": "Demo Date\/Time mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 33, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "mdy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_full": { + "name": "demo_datetime_full", + "label": "Demo Date\/Time Full", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 34, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "format", + "datetime_format": "fjsy", + "datetime_time_type": "wp", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_custom": { + "name": "demo_datetime_custom", + "label": "Demo Date\/Time Custom", + "description": "d-m-Y date format, h:i:s A time format", + "help": "", + "class": "", + "type": "datetime", + "weight": 35, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "custom", + "datetime_format_custom": "d-m-Y", + "datetime_format_custom_js": "d-m-Y", + "datetime_format": "fjsy", + "datetime_time_type": "custom", + "datetime_time_format_custom": "h:i:s A", + "datetime_time_format_custom_js": "hh:mm:ss T", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour": { + "name": "demo_datetime_12_hour", + "label": "Demo Date\/Time 12 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 36, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "h_mm_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_12_hour_leading_0_wseconds": { + "name": "demo_datetime_12_hour_leading_0_wseconds", + "label": "Demo Date\/Time 12 hour leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 37, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "12", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour": { + "name": "demo_datetime_24_hour", + "label": "Demo Date\/Time 24 hour", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 38, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_datetime_24_hour_wseconds": { + "name": "demo_datetime_24_hour_wseconds", + "label": "Demo Date\/Time 24 hour w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "datetime", + "weight": 39, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "datetime_type": "wp", + "datetime_format": "mdy", + "datetime_time_type": "24", + "datetime_time_format": "hh_mm_ss_A", + "datetime_time_format_24": "hh_mm_ss", + "datetime_allow_empty": "0", + "datetime_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "datetime_repeatable": "0", + "datetime_format_custom": "", + "datetime_format_custom_js": "", + "datetime_time_format_custom": "", + "datetime_time_format_custom_js": "", + "datetime_year_range_custom": "" + }, + "demo_date_wp_default": { + "name": "demo_date_wp_default", + "label": "Demo Date WP Default", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 40, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_year_range_static": { + "name": "demo_date_wp_default_year_range_static", + "label": "Demo Date WP Default Year Range Static", + "description": "Year Range 2010:2015", + "help": "", + "class": "", + "type": "date", + "weight": 41, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "2010:2015", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_year_range_relative": { + "name": "demo_date_wp_default_year_range_relative", + "label": "Demo Date WP Default Year Range Relative", + "description": "-1:+3", + "help": "", + "class": "", + "type": "date", + "weight": 42, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_year_range_custom": "-1:+3", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "" + }, + "demo_date_wp_default_empty_value": { + "name": "demo_date_wp_default_empty_value", + "label": "Demo Date WP Default Empty Value", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 43, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "1", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_wp_default_html5": { + "name": "demo_date_wp_default_html5", + "label": "Demo Date WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 44, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "wp", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mmddyyyy": { + "name": "demo_date_mmddyyyy", + "label": "Demo Date mm\/dd\/yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 45, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_mm-dd-yyyy": { + "name": "demo_date_mm-dd-yyyy", + "label": "Demo Date mm-dd-yyyy", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 46, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "mdy_dash", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_full": { + "name": "demo_date_full", + "label": "Demo Date Full", + "description": "", + "help": "", + "class": "", + "type": "date", + "weight": 47, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "format", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_date_custom": { + "name": "demo_date_custom", + "label": "Demo Date Custom", + "description": "d-m-Y date format", + "help": "", + "class": "", + "type": "date", + "weight": 48, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "date_type": "custom", + "date_format": "fjsy", + "date_allow_empty": "0", + "date_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "date_repeatable": "0", + "date_format_custom": "d-m-Y", + "date_format_custom_js": "", + "date_year_range_custom": "" + }, + "demo_time_wp_default": { + "name": "demo_time_wp_default", + "label": "Demo Time WP Default", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 49, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_empty_field": { + "name": "demo_time_wp_default_empty_field", + "label": "Demo Time WP Default Empty Field", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 50, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "1", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_wp_default_html5": { + "name": "demo_time_wp_default_html5", + "label": "Demo Time WP Default HTML5", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 51, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "wp", + "time_format": "h_mma", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "1", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour": { + "name": "demo_time_12_hour", + "label": "Demo Time 12 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 52, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_12_hour_leading_0_wseconds": { + "name": "demo_time_12_hour_leading_0_wseconds", + "label": "Demo Time 12 Hour Leading 0 w\/seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 53, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "12", + "time_format": "hh_mm_ss_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour": { + "name": "demo_time_24_hour", + "label": "Demo Time 24 Hour", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 54, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_24_hour_w_seconds": { + "name": "demo_time_24_hour_w_seconds", + "label": "Demo Time 24 Hour w\/ seconds", + "description": "", + "help": "", + "class": "", + "type": "time", + "weight": 55, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "24", + "time_format": "h_mm_A", + "time_format_24": "hh_mm_ss", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0", + "time_format_custom": "", + "time_format_custom_js": "" + }, + "demo_time_custom": { + "name": "demo_time_custom", + "label": "Demo Time Custom", + "description": "h:i:s A time format", + "help": "", + "class": "", + "type": "time", + "weight": 56, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "time_type": "custom", + "time_format_custom": "h:i:s A", + "time_format_custom_js": "h:i:s A", + "time_format": "h_mm_A", + "time_format_24": "hh_mm", + "time_allow_empty": "0", + "time_html5": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "time_repeatable": "0" + }, + "demo_plain_number_freeform_default": { + "name": "demo_plain_number_freeform_default", + "label": "Demo Plain Number Freeform Default", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 57, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_default_placeholder": { + "name": "demo_plain_number_freeform_default_placeholder", + "label": "Demo Plain Number Freeform Default Placeholder", + "description": "0 decimals, max length 12", + "help": "", + "class": "", + "type": "number", + "weight": 58, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "i18n", + "number_decimals": "0", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "number_placeholder": "Enter Number Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0" + }, + "demo_plain_number_freeform_default_copy": { + "name": "demo_plain_number_freeform_default_copy", + "label": "Demo Plain Number Freeform US", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 59, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_other": { + "name": "demo_plain_number_freeform_other", + "label": "Demo Plain Number Freeform Other", + "description": "2 decimals, max length 12 ex. 1.234,00", + "help": "", + "class": "", + "type": "number", + "weight": 60, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_freeform_us_no_comma": { + "name": "demo_plain_number_freeform_us_no_comma", + "label": "Demo Plain Number Freeform US no comma", + "description": "2 decimals, max length 12 ex. 1,234.00", + "help": "", + "class": "", + "type": "number", + "weight": 61, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "number", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "1", + "number_min": "0", + "number_max": "100", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_default": { + "name": "demo_plain_number_slider_default", + "label": "Demo Plain Number Slider Default", + "description": "2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 62, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "i18n", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us": { + "name": "demo_plain_number_slider_us", + "label": "Demo Plain Number Slider US", + "description": "1,234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 63, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9,999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_other": { + "name": "demo_plain_number_slider_other", + "label": "Demo Plain Number Slider Other", + "description": "1.234,00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 64, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9.999,99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_plain_number_slider_us_no_comma": { + "name": "demo_plain_number_slider_us_no_comma", + "label": "Demo Plain Number Slider US no comma", + "description": "1234.00 2 decimals, max length 12 , step 10, min 0, max 1000", + "help": "", + "class": "", + "type": "number", + "weight": 65, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "number_format_type": "slider", + "number_format": "9999.99", + "number_decimals": "2", + "number_format_soft": "0", + "number_step": "10", + "number_min": "0", + "number_max": "1000", + "number_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "number_repeatable": "0", + "number_placeholder": "" + }, + "demo_currency_freeform_usd_default": { + "name": "demo_currency_freeform_usd_default", + "label": "Demo Currency Freeform $USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 66, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_default_placeholder": { + "name": "demo_currency_freeform_usd_default_placeholder", + "label": "Demo Currency Freeform $USD Default Placeholder", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 67, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "currency_placeholder": "Enter Amount Here", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "currency_repeatable": "0" + }, + "demo_currency_freeform_usdalt_default": { + "name": "demo_currency_freeform_usdalt_default", + "label": "Demo Currency Freeform USD$ Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 68, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "after", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_x_usd_default": { + "name": "demo_currency_freeform_x_usd_default", + "label": "Demo Currency Freeform $X USD Default", + "description": "2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 69, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "beforeaftercode", + "currency_format": "i18n", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us": { + "name": "demo_currency_freeform_usd_us", + "label": "Demo Currency Freeform $USD US", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 70, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_other": { + "name": "demo_currency_freeform_usd_other", + "label": "Demo Currency Freeform $USD Other", + "description": "1.234,00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 71, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9.999,99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_usd_us_no_comma": { + "name": "demo_currency_freeform_usd_us_no_comma", + "label": "Demo Currency Freeform $USD US no comma", + "description": "1234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 72, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "usd", + "currency_format_placement": "before", + "currency_format": "9999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_currency_freeform_euro_default": { + "name": "demo_currency_freeform_euro_default", + "label": "Demo Currency Freeform Euro Default", + "description": "1,234.00 2 Decimals, Max length 12", + "help": "", + "class": "", + "type": "currency", + "weight": 73, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "currency_format_type": "number", + "currency_format_sign": "euro", + "currency_format_placement": "before", + "currency_format": "9,999.99", + "currency_decimals": "2", + "currency_decimal_handling": "none", + "currency_step": "1", + "currency_min": "0", + "currency_max": "1000", + "currency_max_length": "12", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "currency_repeatable": "0", + "currency_placeholder": "" + }, + "demo_single_file_default_media_library_upload_tab": { + "name": "demo_single_file_default_media_library_upload_tab", + "label": "Demo Single File Default Media Library Upload Tab", + "description": "no editable title etc.", + "help": "", + "class": "", + "type": "file", + "weight": 74, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt1": { + "name": "demo_single_file_default_media_library_upload_tab_opt1", + "label": "Demo Single File Default Media Library Upload Tab opt1", + "description": "Editable title only", + "help": "", + "class": "", + "type": "file", + "weight": 75, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_opt2": { + "name": "demo_single_file_default_media_library_upload_tab_opt2", + "label": "Demo Single File Default Media Library Upload Tab opt2", + "description": "Editable Title, edit link, and download link", + "help": "", + "class": "", + "type": "file", + "weight": 76, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_any_type": { + "name": "demo_single_file_default_media_library_upload_tab_any_type", + "label": "Demo Single File Default Media Library Upload Tab Any Type", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 77, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "any", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_other": { + "name": "demo_single_file_default_media_library_upload_tab_other", + "label": "Demo Single File Default Media Library Upload Tab Other", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 78, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "other", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "jpg, png, mp4, mov" + }, + "demo_single_file_default_media_library_upload_tab_tiles": { + "name": "demo_single_file_default_media_library_upload_tab_tiles", + "label": "Demo Single File Default Media Library Upload Tab Tiles List", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 79, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_default_media_library_upload_tab_custom_buttons": { + "name": "demo_single_file_default_media_library_upload_tab_custom_buttons", + "label": "Demo Single File Default Media Library Upload Tab Custom buttons", + "description": "custom text for buttons", + "help": "", + "class": "", + "type": "file", + "weight": 80, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File Here", + "file_modal_title": "Attach a file here", + "file_modal_add_button": "Add Your File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows": { + "name": "demo_multiple_file_default_rows", + "label": "Demo Multiple File Default Rows", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 81, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_rows_w_editable_links": { + "name": "demo_multiple_file_default_rows_w_editable_links", + "label": "Demo Multiple File Default Rows w editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 82, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles": { + "name": "demo_multiple_file_default_tiles", + "label": "Demo Multiple File Default Tiles", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 83, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_multiple_file_default_tiles_with_editable_links": { + "name": "demo_multiple_file_default_tiles_with_editable_links", + "label": "Demo Multiple File Default Tiles with editable links", + "description": "max 5", + "help": "", + "class": "", + "type": "file", + "weight": 84, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "multi", + "file_uploader": "attachment", + "file_attachment_tab": "upload", + "file_edit_title": "1", + "file_show_edit_link": "1", + "file_linked": "1", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "tiles", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_plupload": { + "name": "demo_single_file_plupload", + "label": "Demo Single File Plupload", + "description": "10mb", + "help": "", + "class": "", + "type": "file", + "weight": 85, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "plupload", + "file_attachment_tab": "upload", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_single_file_media_library_and_media_library_tab": { + "name": "demo_single_file_media_library_and_media_library_tab", + "label": "Demo Single File Media Library and Media Library Tab", + "description": "", + "help": "", + "class": "", + "type": "file", + "weight": 86, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "file_format_type": "single", + "file_uploader": "attachment", + "file_attachment_tab": "browse", + "file_edit_title": "0", + "file_show_edit_link": "0", + "file_linked": "0", + "file_limit": "5", + "file_restrict_filesize": "10MB", + "file_type": "images", + "file_field_template": "rows", + "file_add_button": "Add File", + "file_modal_title": "Attach a file", + "file_modal_add_button": "Add File", + "file_wp_gallery_output": "0", + "file_wp_gallery_link": "post", + "file_wp_gallery_columns": "1", + "file_wp_gallery_random_sort": "0", + "file_wp_gallery_size": "thumbnail", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "file_allowed_extensions": "" + }, + "demo_oembed_default": { + "name": "demo_oembed_default", + "label": "Demo oEmbed Default", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 87, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_preview": { + "name": "demo_oembed_preview", + "label": "Demo oEmbed Preview", + "description": "no width or height restrictions", + "help": "", + "class": "", + "type": "oembed", + "weight": 88, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "0", + "oembed_height": "0", + "oembed_show_preview": "1", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_oembed_width_height": { + "name": "demo_oembed_width_height", + "label": "Demo oEmbed Width Height", + "description": "width 100 height 100", + "help": "", + "class": "", + "type": "oembed", + "weight": 89, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "oembed_width": "100", + "oembed_height": "100", + "oembed_show_preview": "0", + "oembed_restrict_providers": "0", + "oembed_enabled_providers_amazoncn": "0", + "oembed_enabled_providers_amazoncouk": "0", + "oembed_enabled_providers_amazoncom": "0", + "oembed_enabled_providers_amazoncomau": "0", + "oembed_enabled_providers_amazonin": "0", + "oembed_enabled_providers_animotocom": "0", + "oembed_enabled_providers_cloudupcom": "0", + "oembed_enabled_providers_crowdsignalcom": "0", + "oembed_enabled_providers_dailymotioncom": "0", + "oembed_enabled_providers_facebookcom": "0", + "oembed_enabled_providers_flickrcom": "0", + "oembed_enabled_providers_imgurcom": "0", + "oembed_enabled_providers_instagramcom": "0", + "oembed_enabled_providers_issuucom": "0", + "oembed_enabled_providers_kickstartercom": "0", + "oembed_enabled_providers_meetupcom": "0", + "oembed_enabled_providers_mixcloudcom": "0", + "oembed_enabled_providers_redditcom": "0", + "oembed_enabled_providers_reverbnationcom": "0", + "oembed_enabled_providers_screencastcom": "0", + "oembed_enabled_providers_scribdcom": "0", + "oembed_enabled_providers_slidesharenet": "0", + "oembed_enabled_providers_smugmugcom": "0", + "oembed_enabled_providers_someecardscom": "0", + "oembed_enabled_providers_soundcloudcom": "0", + "oembed_enabled_providers_speakerdeckcom": "0", + "oembed_enabled_providers_spotifycom": "0", + "oembed_enabled_providers_tedcom": "0", + "oembed_enabled_providers_tiktokcom": "0", + "oembed_enabled_providers_tumblrcom": "0", + "oembed_enabled_providers_twittercom": "0", + "oembed_enabled_providers_vimeocom": "0", + "oembed_enabled_providers_wordpresscom": "0", + "oembed_enabled_providers_wordpresstv": "0", + "oembed_enabled_providers_youtubecom": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "oembed_repeatable": "0" + }, + "demo_relationship_simple_list_single_drop_down": { + "name": "demo_relationship_simple_list_single_drop_down", + "label": "Demo Relationship Simple List Single Drop Down", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 90, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_drop_down_2": { + "name": "demo_relationship_simple_list_single_drop_down_2", + "label": "Demo Relationship Simple List Single Drop Down 2", + "description": "custom \"choose one\" text", + "help": "", + "class": "", + "type": "pick", + "weight": 91, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Choose One", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_radio": { + "name": "demo_relationship_simple_list_single_radio", + "label": "Demo Relationship Simple List Single Radio", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 92, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "radio", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete": { + "name": "demo_relationship_simple_list_single_autocomplete", + "label": "Demo Relationship Simple List Single Autocomplete", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 93, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_autocomplete_tag": { + "name": "demo_relationship_simple_list_single_autocomplete_tag", + "label": "Demo Relationship Simple List Single Autocomplete Tag", + "description": "", + "help": "", + "class": "", + "type": "pick", + "weight": 94, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "autocomplete", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "1", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_1": { + "name": "demo_relationship_simple_list_single_list_view_1", + "label": "Demo Relationship Simple List Single List view 1", + "description": "all checked", + "help": "", + "class": "", + "type": "pick", + "weight": 95, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_single_list_view_2": { + "name": "demo_relationship_simple_list_single_list_view_2", + "label": "Demo Relationship Simple List Single List view 2", + "description": "none checked", + "help": "", + "class": "", + "type": "pick", + "weight": 96, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "single", + "pick_format_single": "list", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_0": { + "name": "demo_relationship_simple_list_multiple_checkboxes_0", + "label": "Demo Relationship Simple List Multiple Checkboxes 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 97, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_checkboxes_5": { + "name": "demo_relationship_simple_list_multiple_checkboxes_5", + "label": "Demo Relationship Simple List Multiple Checkboxes 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 98, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_0": { + "name": "demo_relationship_simple_list_multiple_multiselect_0", + "label": "Demo Relationship Simple List Multiple Multiselect 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 99, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_multiselect_5": { + "name": "demo_relationship_simple_list_multiple_multiselect_5", + "label": "Demo Relationship Simple List Multiple Multiselect 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 100, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "multiselect", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_0": { + "name": "demo_relationship_simple_list_multiple_autocomplete_0", + "label": "Demo Relationship Simple List Multiple Autocomplete 0", + "description": "limit 0", + "help": "", + "class": "", + "type": "pick", + "weight": 101, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_autocomplete_5": { + "name": "demo_relationship_simple_list_multiple_autocomplete_5", + "label": "Demo Relationship Simple List Multiple Autocomplete 5", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 102, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "autocomplete", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_0": { + "name": "demo_relationship_simple_list_multiple_list_view_0", + "label": "Demo Relationship Simple List Multiple List View 0", + "description": "limit 0 all selected", + "help": "", + "class": "", + "type": "pick", + "weight": 103, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "0", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5": { + "name": "demo_relationship_simple_list_multiple_list_view_5", + "label": "Demo Relationship Simple List Multiple List View 5", + "description": "limit 5 all selected (selection in text)", + "help": "", + "class": "", + "type": "pick", + "weight": 104, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "Selection", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_simple_list_multiple_list_view_5_opt2": { + "name": "demo_relationship_simple_list_multiple_list_view_5_opt2", + "label": "Demo Relationship Simple List Multiple List View 5 opt2", + "description": "limit 5 none selected", + "help": "", + "class": "", + "type": "pick", + "weight": 105, + "pick_object": "custom-simple", + "pick_val": "", + "sister_id": "", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "required": "0", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "0", + "pick_show_edit_link": "0", + "pick_show_view_link": "0", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_relationship_pages": { + "name": "demo_relationship_pages", + "label": "Demo Relationship Pages", + "description": "limit 5", + "help": "", + "class": "", + "type": "pick", + "weight": 106, + "pick_object": "post_type", + "pick_val": "page", + "sister_id": "", + "required": "0", + "unique": "0", + "pick_custom": "one|Option one\ntwo|Option two\nthree|Option three", + "pick_format_type": "multi", + "pick_format_single": "dropdown", + "pick_format_multi": "list", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": "0", + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_limit": "5", + "pick_user_role": [], + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "pick_select_text": "", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "" + }, + "demo_yesno_checkbox": { + "name": "demo_yesno_checkbox", + "label": "Demo Yes\/No Checkbox", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 107, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_checkbox_alt": { + "name": "demo_yesno_checkbox_alt", + "label": "Demo Yes\/No Checkbox Alt", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 108, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "checkbox", + "boolean_yes_label": "True", + "boolean_no_label": "False", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_radio": { + "name": "demo_yesno_radio", + "label": "Demo Yes\/No Radio", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 109, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "radio", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_yesno_drop_down": { + "name": "demo_yesno_drop_down", + "label": "Demo Yes\/No Drop Down", + "description": "", + "help": "", + "class": "", + "type": "boolean", + "weight": 110, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "boolean_format_type": "dropdown", + "boolean_yes_label": "Yes", + "boolean_no_label": "No", + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "unique": "0" + }, + "demo_color_picker": { + "name": "demo_color_picker", + "label": "Demo Color Picker", + "description": "", + "help": "", + "class": "", + "type": "color", + "weight": 111, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "color_repeatable": 0 + } + }, + "show_in_menu": "1", + "label_singular": "Kitchen ACT", + "public": "1", + "show_ui": "1", + "supports_title": "1", + "supports_editor": "1", + "publicly_queryable": "1", + "exclude_from_search": "0", + "capability_type": "post", + "capability_type_custom": "kitchen_act", + "capability_type_extra": "1", + "has_archive": "0", + "hierarchical": "0", + "rewrite": "1", + "rewrite_with_front": "1", + "rewrite_feeds": "0", + "rewrite_pages": "1", + "query_var": "1", + "can_export": "1", + "default_status": "draft", + "supports_author": "0", + "supports_thumbnail": "0", + "supports_excerpt": "0", + "supports_trackbacks": "0", + "supports_custom_fields": "0", + "supports_comments": "0", + "supports_revisions": "0", + "supports_page_attributes": "0", + "supports_post_formats": "0", + "built_in_taxonomies_category": "0", + "built_in_taxonomies_link_category": "0", + "built_in_taxonomies_post_tag": "0", + "menu_position": "0", + "show_in_nav_menus": "1", + "show_in_admin_bar": "1", + "rest_enable": "0", + "read_all": "0", + "write_all": "0" + } + } +} diff --git a/tests/codeception/_data/packages/test-import.json b/tests/codeception/_data/packages/test-import.json new file mode 100644 index 0000000000..6f0f66fb77 --- /dev/null +++ b/tests/codeception/_data/packages/test-import.json @@ -0,0 +1,75 @@ +{ + "meta": { + "version": "2.7.16-a-1", + "build": 1569005171 + }, + "pods": { + "320": { + "id": 320, + "name": "page", + "label": "Page", + "description": "", + "type": "post_type", + "storage": "meta", + "object": "page", + "alias": "", + "fields": { + "banana": { + "id": 321, + "name": "banana", + "label": "Test", + "description": "", + "help": "", + "class": "", + "type": "wysiwyg", + "weight": 0, + "pick_object": "", + "pick_val": "", + "sister_id": "", + "required": "0", + "unique": "0", + "wysiwyg_editor": "tinymce", + "wysiwyg_media_buttons": "1", + "wysiwyg_oembed": "0", + "wysiwyg_wptexturize": "1", + "wysiwyg_convert_chars": "1", + "wysiwyg_wpautop": "1", + "wysiwyg_trim": "1", + "wysiwyg_allow_shortcode": "0", + "pick_post_status": [ + "publish" + ], + "admin_only": "0", + "restrict_role": "0", + "restrict_capability": "0", + "hidden": "0", + "read_only": "0", + "roles_allowed": [ + "administrator" + ], + "rest_read": "0", + "rest_write": "0", + "rest_pick_response": "array", + "rest_pick_depth": "2", + "wysiwyg_repeatable": "0", + "wysiwyg_allowed_html_tags": "" + } + }, + "show_in_menu": "1", + "pfat_enable": "0", + "pfat_run_outside_loop": "0", + "pfat_append_single": "append", + "pfat_filter_single": "the_content", + "pfat_append_archive": "append", + "pfat_filter_archive": "the_content", + "rest_enable": "0", + "rest_base": "page", + "read_all": "0", + "write_all": "0", + "built_in_taxonomies_story": "0", + "built_in_taxonomies_storytax": "0", + "built_in_taxonomies_publication": "0", + "built_in_taxonomies_publications": "0" + } + } +} diff --git a/tests/codeception/_data/packages/test-pod-sanitize-post-request.json b/tests/codeception/_data/packages/test-pod-sanitize-post-request.json new file mode 100644 index 0000000000..4581ac4401 --- /dev/null +++ b/tests/codeception/_data/packages/test-pod-sanitize-post-request.json @@ -0,0 +1,49 @@ +{ + "label": "Rel", + "name": "rel", + "description": "", + "type": "pick", + "pick_object": "post_type-post", + "pick_custom": "", + "pick_table": "", + "sister_id": "", + "required": 0, + "pick_format_type": "single", + "pick_format_single": "dropdown", + "pick_format_multi": "checkbox", + "pick_display_format_multi": "default", + "pick_display_format_separator": ", ", + "pick_allow_add_new": "1", + "pick_taggable": 0, + "pick_show_icon": "1", + "pick_show_edit_link": "1", + "pick_show_view_link": "1", + "pick_select_text": "", + "pick_limit": "0", + "pick_table_id": "", + "pick_table_index": "", + "pick_display": "", + "pick_user_role": [], + "pick_where": "", + "pick_orderby": "", + "pick_groupby": "", + "pick_post_status": [ + "publish" + ], + "class": "", + "default_value": "", + "default_value_parameter": "", + "admin_only": 0, + "restrict_role": 0, + "restrict_capability": 0, + "hidden": 0, + "read_only": 0, + "roles_allowed": [ + "administrator" + ], + "capability_allowed": "", + "rest_read": 0, + "rest_write": 0, + "rest_pick_response": "array", + "rest_pick_depth": "2" +} diff --git a/tests/codeception/_data/traversal-config.json b/tests/codeception/_data/traversal-config.json new file mode 100644 index 0000000000..5f0411a516 --- /dev/null +++ b/tests/codeception/_data/traversal-config.json @@ -0,0 +1,910 @@ +[ + { + "name": "test_post_meta", + "type": "post_type", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_taxonomies_category": 1, + "built_in_taxonomies_post_tag": 1, + "built_in_taxonomies_nav_menu": 1, + "built_in_taxonomies_test_non_pod_ct": 1, + "overwrite": true + }, + { + "name": "test_post_table", + "type": "post_type", + "storage": "table", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_taxonomies_category": 1, + "built_in_taxonomies_post_tag": 1, + "built_in_taxonomies_nav_menu": 1, + "built_in_taxonomies_test_non_pod_ct": 1, + "overwrite": true + }, + { + "name": "post", + "type": "post_type", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_taxonomies_category": 1, + "built_in_taxonomies_post_tag": 1, + "built_in_taxonomies_nav_menu": 1, + "built_in_taxonomies_test_non_pod_ct": 1, + "object": "post", + "overwrite": true + }, + { + "name": "page", + "type": "post_type", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_taxonomies_category": 1, + "built_in_taxonomies_post_tag": 1, + "built_in_taxonomies_nav_menu": 1, + "built_in_taxonomies_test_non_pod_ct": 1, + "object": "page", + "overwrite": true + }, + { + "name": "nav_menu_item", + "type": "post_type", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_taxonomies_category": 1, + "built_in_taxonomies_post_tag": 1, + "built_in_taxonomies_nav_menu": 1, + "built_in_taxonomies_test_non_pod_ct": 1, + "object": "nav_menu_item", + "overwrite": true + }, + { + "name": "test_tax_table", + "type": "taxonomy", + "storage": "table", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_post_types_post": 1, + "built_in_post_types_page": 1, + "built_in_post_types_nav_menu_item": 1, + "overwrite": true + }, + { + "name": "test_tax_meta", + "type": "taxonomy", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_post_types_post": 1, + "built_in_post_types_page": 1, + "built_in_post_types_nav_menu_item": 1, + "overwrite": true + }, + { + "name": "category", + "type": "taxonomy", + "storage": "table", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_post_types_post": 1, + "built_in_post_types_page": 1, + "built_in_post_types_nav_menu_item": 1, + "object": "category", + "overwrite": true + }, + { + "name": "post_tag", + "type": "taxonomy", + "storage": "table", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_post_types_post": 1, + "built_in_post_types_page": 1, + "built_in_post_types_nav_menu_item": 1, + "object": "post_tag", + "overwrite": true + }, + { + "name": "nav_menu", + "type": "taxonomy", + "storage": "table", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "built_in_post_types_post": 1, + "built_in_post_types_page": 1, + "built_in_post_types_nav_menu_item": 1, + "object": "nav_menu", + "overwrite": true + }, + { + "name": "user", + "type": "user", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + }, + { + "name": "avatar", + "type": "avatar" + } + ], + "options": [], + "object": "user", + "overwrite": true + }, + { + "name": "media", + "type": "media", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "object": "media", + "overwrite": true + }, + { + "name": "comment", + "type": "comment", + "storage": "meta", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + } + ], + "options": [], + "object": "comment", + "overwrite": true + }, + { + "name": "test_act", + "type": "pod", + "storage": "table", + "fields": [ + { + "name": "test_rel_user", + "type": "pick", + "pick_object": "user", + "pick_val": "user", + "pick_format_type": "single" + }, + { + "name": "test_rel_post", + "type": "pick", + "pick_object": "post_type", + "pick_val": "post", + "pick_format_type": "single" + }, + { + "name": "test_rel_pages", + "type": "pick", + "pick_object": "post_type", + "pick_val": "page", + "pick_format_type": "multi" + }, + { + "name": "test_rel_tag", + "type": "pick", + "pick_object": "taxonomy", + "pick_val": "post_tag", + "pick_format_type": "single" + }, + { + "name": "test_rel_media", + "type": "pick", + "pick_object": "media", + "pick_format_type": "single" + }, + { + "name": "test_rel_comment", + "type": "pick", + "pick_object": "comment", + "pick_format_type": "single" + }, + { + "name": "test_rel_act", + "type": "pick", + "pick_object": "pod", + "pick_val": "test_act", + "pick_format_type": "single" + }, + { + "name": "test_text_field", + "type": "text" + }, + { + "name": "name", + "type": "text" + }, + { + "name": "permalink", + "type": "slug" + }, + { + "name": "test_text_field", + "type": "test" + }, + { + "name": "author", + "type": "pick", + "pick_object": "user", + "pick_format_type": "single" + } + ], + "options": { + "pod_index": "name" + }, + "overwrite": true + } +] diff --git a/tests/codeception/_data/traversal-data.json b/tests/codeception/_data/traversal-data.json new file mode 100644 index 0000000000..b359439ab6 --- /dev/null +++ b/tests/codeception/_data/traversal-data.json @@ -0,0 +1,201 @@ +{ + "test_post_meta": { + "post_status": "publish", + "post_title": "Testing index a66d982c8099d014bc1fa2937e55c912", + "post_author": 0, + "test_text_field": "Testing a66d982c8099d014bc1fa2937e55c912", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "test_post_table": { + "post_status": "publish", + "post_title": "Testing index fd1100433cbdb1a88065aa30720e3b40", + "post_author": 0, + "test_text_field": "Testing fd1100433cbdb1a88065aa30720e3b40", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "post": { + "post_status": "publish", + "post_title": "Testing index 5999153530660d496e23b334a6befe6d", + "post_author": 0, + "test_text_field": "Testing 5999153530660d496e23b334a6befe6d", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "page": { + "post_status": "publish", + "post_title": "Testing index 6dbbdb9022e2d0cd9a3664e421571379", + "post_author": 0, + "test_text_field": "Testing 6dbbdb9022e2d0cd9a3664e421571379", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "nav_menu_item": { + "post_status": "publish", + "post_title": "Testing index 25b0cd30b4b87446f5bf1695769cd47d", + "post_author": 0, + "test_text_field": "Testing 25b0cd30b4b87446f5bf1695769cd47d", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "test_tax_table": { + "name": "Testing index dd10ac7ca2da6c9ab585c0e2d22cb11b", + "test_text_field": "Testing dd10ac7ca2da6c9ab585c0e2d22cb11b", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_tax_meta": { + "name": "Testing index 61f604e848ee443d6747bb464a883a1e", + "test_text_field": "Testing 61f604e848ee443d6747bb464a883a1e", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "category": { + "name": "Testing index f27f6aa87ec90698cc92add87c329889", + "test_text_field": "Testing f27f6aa87ec90698cc92add87c329889", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "post_tag": { + "name": "Testing index ec6294c1df2cae4b69b7158bd5b7e527", + "test_text_field": "Testing ec6294c1df2cae4b69b7158bd5b7e527", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "nav_menu": { + "name": "Testing index b6e16087c5789b81d87ca565346fd337", + "test_text_field": "Testing b6e16087c5789b81d87ca565346fd337", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "user": { + "display_name": "User f4d6ab3edb68db2f4399cb493a7b435b", + "user_login": "User-f4d6ab3edb68db2f4399cb493a7b435b", + "user_email": "f4d6ab3edb68db2f4399cb493a7b435b@user.com", + "user_pass": "test-pw-f4d6ab3edb68db2f4399cb493a7b435b", + "test_text_field": "Testing f4d6ab3edb68db2f4399cb493a7b435b", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "media": { + "post_status": "inherit", + "post_type": "attachment", + "post_title": "Testing index 14228bf1d952618086f315a46a57a05a", + "post_author": 0, + "test_text_field": "Testing 14228bf1d952618086f315a46a57a05a", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "comment": { + "comment_author": "Comment 84492f44425413f9ec236fcb3ca7ff61", + "comment_author_email": "84492f44425413f9ec236fcb3ca7ff61@comment.com", + "comment_author_url": "http:\/\/comment.com", + "comment_content": "84492f44425413f9ec236fcb3ca7ff61", + "comment_post_ID": 1, + "comment_type": "comment", + "comment_approved": 1, + "comment_date": "2014-11-11", + "user_id": 0, + "test_text_field": "Testing 84492f44425413f9ec236fcb3ca7ff61", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_act": { + "permalink": "test-slug-95f74c8e1f0e49ef288c74494e5d4d47", + "name": "Testing index 95f74c8e1f0e49ef288c74494e5d4d47", + "author": 0, + "test_text_field": "Testing 95f74c8e1f0e49ef288c74494e5d4d47", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + } +} diff --git a/tests/codeception/_data/traversal-related-data.json b/tests/codeception/_data/traversal-related-data.json new file mode 100644 index 0000000000..0e68f0e9d2 --- /dev/null +++ b/tests/codeception/_data/traversal-related-data.json @@ -0,0 +1,155 @@ +{ + "test_rel_user": { + "display_name": "Related user 03d5942f91be7863929f02c5287b439a", + "user_login": "related-user", + "user_email": "related@user.com", + "user_pass": "changeme", + "test_text_field": "Test related user text field 03d5942f91be7863929f02c5287b439a", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_rel_post": { + "post_title": "Related post 957094053317a49eb5f8db0bc71430da", + "post_content": "957094053317a49eb5f8db0bc71430da", + "post_status": "publish", + "test_text_field": "Test related post text field 957094053317a49eb5f8db0bc71430da", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "test_rel_pages": { + "post_title": "Related page f820300a0ff832c3a0b9cd9a6f2bf7ba", + "post_content": "f820300a0ff832c3a0b9cd9a6f2bf7ba", + "post_status": "publish", + "test_text_field": "Test related page text field f820300a0ff832c3a0b9cd9a6f2bf7ba", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "test_rel_pages2": { + "post_title": "Related page 2 b56642438d7bc780f732c893356d9897", + "post_content": "b56642438d7bc780f732c893356d9897", + "post_status": "publish", + "test_text_field": "Test related page text field b56642438d7bc780f732c893356d9897", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0, + "test_non_pod_ct": 0 + }, + "test_rel_tag": { + "name": "Related post tag fb48dd92f3198ce5cfeac554c9fb2867", + "description": "fb48dd92f3198ce5cfeac554c9fb2867", + "test_text_field": "Test related tag text field fb48dd92f3198ce5cfeac554c9fb2867", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_rel_media": { + "post_title": "Related media", + "post_content": "08fc45387cdce771f30cf311ae34fa17", + "post_status": "publish", + "test_text_field": "Test related media text field 08fc45387cdce771f30cf311ae34fa17", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_rel_comment": { + "comment_author": "Related comment e697208650b932f4d5e7902f1218007d", + "comment_author_email": "related@comment.com", + "comment_author_url": "http:\/\/comment.com", + "comment_content": "e697208650b932f4d5e7902f1218007d", + "comment_post_ID": 1, + "comment_type": "comment", + "comment_approved": 1, + "comment_date": "2014-11-11 00:00:00", + "test_text_field": "Test related comment text field e697208650b932f4d5e7902f1218007d", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_rel_act": { + "name": "Related pod item c4aa9cb17a4cf2fcfc7e8fb840d42a8d", + "permalink": "related-pod-item", + "author": 0, + "test_text_field": "Test related pod text field c4aa9cb17a4cf2fcfc7e8fb840d42a8d", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "avatar": { + "post_title": "Related avatar", + "post_content": "b583076ded12c15bc9e87d7057a18180", + "post_status": "publish", + "test_text_field": "Test avatar text field", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "author": { + "display_name": "Related author fbd428d3fbb75b82756772e5a1428566", + "user_login": "related-author", + "user_email": "author@user.com", + "user_pass": "changeme", + "test_text_field": "Test related author text field fbd428d3fbb75b82756772e5a1428566", + "test_rel_user": 0, + "test_rel_post": 0, + "test_rel_pages": [], + "test_rel_tag": 0, + "test_rel_media": 0, + "test_rel_comment": 0, + "test_rel_act": 0, + "avatar": 0 + }, + "test_non_pod_ct": { + "name": "Non-Pod Term", + "description": "b74803a4123e24ba97271d983b00419d" + } +} \ No newline at end of file diff --git a/tests/codeception/_support/Helper/Integration.php b/tests/codeception/_support/Helper/Integration.php new file mode 100644 index 0000000000..c3269eb0e2 --- /dev/null +++ b/tests/codeception/_support/Helper/Integration.php @@ -0,0 +1,10 @@ + array( + * 'object_name' => array( + * 'meta' => array( + * // pod array of info + * ), + * 'table' => array( + * // pod array of info + * ), + * 'none' => array( + * // pod array of info + * ) + * ) + * ) + */ + ]; + + /** + * + */ + public function setUp() : void { + static $counter = 0; + + if ( static::$db_reset_teardown ) { + parent::setUp(); + + $load_config = filter_var( getenv( 'PODS_LOAD_DATA' ), FILTER_VALIDATE_BOOLEAN ); + + if ( $load_config ) { + $counter ++; + + if ( 100 <= $counter ) { + $counter = 0; + + usleep( 500000 ); + } + } + } + } + + /** + * Initialize Pods test config. + * + * @throws \Exception + */ + public static function _initialize() { + self::_initialize_pods_config(); + self::_initialize_pods_related_data(); + self::_initialize_pods_data(); + } + + /** + * Initialize Pods test config. + * + * @throws \Exception + */ + public static function _initialize_pods_config() { + // Setup non-Pod taxonomy + $args = [ + 'hierarchical' => true, + 'show_ui' => true, + 'query_var' => true, + 'labels' => [ + 'name' => 'Non-Pod Taxonomy', + 'singular_name' => 'Non-Pod Taxonomy', + ], + ]; + + register_taxonomy( 'test_non_pod_ct', [ 'post', 'page', 'nav_menu_item' ], $args ); + + $config = file_get_contents( dirname( __DIR__ ) . '/_data/traversal-config.json' ); + $config = json_decode( $config, true ); + + $pods_api = pods_api(); + + $related_fields = [ + 'test_non_pod_ct' => [ + 'object_type' => 'taxonomy', + 'object' => 'test_non_pod_ct', + ], + ]; + + foreach ( $config as $k => $pod ) { + if ( in_array( $pod['name'], pods_reserved_keywords(), true ) ) { + /* + * Extending objects when using reserved keywords. + * + * This will then accept `post`, `page` etc. as Pods object names. + */ + $pod['create_extend'] = 'extend'; + } + + $pods_api->save_pod( $pod ); + + $pod = $pods_api->load_pod( $pod['name'] ); + + if ( 'media' === $pod['name'] ) { + codecept_debug( 'Media orig: ' . var_export( $config[ $k ], true ) ); + codecept_debug( 'Media debug: ' . var_export( $pod->export(), true ) ); + } + + if ( ! empty( $pod['fields'] ) ) { + foreach ( $pod['fields'] as $field ) { + if ( isset( $related_fields[ $field['name'] ] ) ) { + continue; + } + + /** @var Pods\Whatsit\Field $field */ + if ( 'pick' === $field['type'] ) { + $related_info = [ + 'id' => 0, + '_index' => '', + '_items' => [], + 'object_type' => $field->get_related_object_type(), + 'object' => $field->get_related_object_name(), + ]; + + $related_fields[ $field['name'] ] = $related_info; + } elseif ( in_array( $field['type'], [ 'file', 'avatar' ], true ) ) { + $related_info = [ + 'id' => 0, + '_index' => '', + '_items' => [], + 'object_type' => 'media', + 'object' => 'media', + ]; + + $related_fields[ $field['name'] ] = $related_info; + } + } + } + + self::index_build( $pod ); + + self::$config[ $pod['name'] ] = $pod; + } + + // Setup the content types if needed. + if ( did_action( 'init' ) ) { + $pods_init = pods_init(); + $pods_init->setup_content_types( true ); + } + + self::$related_fields = $related_fields; + } + + /** + * Initialize Pods test related data. + * + * @param int $depth + * + * @throws \Exception + */ + public static function _initialize_pods_related_data( $depth = 0 ) { + $data = self::$related_data; + + $import_data = file_get_contents( dirname( __DIR__ ) . '/_data/traversal-related-data.json' ); + $import_data = json_decode( $import_data, true ); + + if ( empty( $data ) ) { + $data = $import_data; + } + + $save_data = []; + + foreach ( $data as $field_name => $item ) { + $is_multi = 0; + + // Save multiple values for test_rel_pages + if ( 'test_rel_pages2' === $field_name ) { + $is_multi = 1; + + $field_name = 'test_rel_pages'; + } + + if ( ! isset( self::$related_fields[ $field_name ] ) ) { + codecept_debug( 'Field invalid: ' . $field_name ); + + continue; + } + + $pod_name = self::$related_fields[ $field_name ]['object']; + + if ( 'attachment' === $pod_name ) { + $pod_name = 'media'; + } + + // This is not a pod, use wp_insert_term instead. + if ( 'test_non_pod_ct' === $pod_name ) { + if ( 0 < $depth ) { + // Save data for later. + $save_data[ $field_name ] = $item; + + continue; + } + + $term = wp_insert_term( $item['name'], 'test_non_pod_ct', [ 'description' => $item['description'] ] ); + + if ( is_wp_error( $term ) ) { + throw new \Exception( sprintf( 'The term could not be inserted: %s', $term->get_error_message() ) ); + } + + $item['id'] = $term['term_id']; + $item['term_id'] = $item['id']; + $item['_index'] = $item['name']; + $item['_items'] = [ $item ]; + $item['_field_id'] = 'term_id'; + $item['_field_index'] = 'name'; + + // Save data for later. + $save_data[ $field_name ] = $item; + + // Save related field info for later. + self::$related_fields[ $field_name ]['id'] = $term['term_id']; + self::$related_fields[ $field_name ]['_index'] = $item['name']; + self::$related_fields[ $field_name ]['_items'][ $term['term_id'] ] = $item; + + continue; + } + + if ( ( 'test_rel_media' === $field_name || 'media' === $pod_name ) && empty( self::$related_fields[ $field_name ]['id'] ) ) { + // Get and store sample image for use later + $attachment = [ + 'post_mime_type' => 'image/png', + 'guid' => self::$sample_image, + 'post_parent' => null, + 'post_title' => basename( self::$sample_image ), + 'post_content' => '', + ]; + + $sample_image_id = wp_insert_attachment( $attachment ); + + if ( empty( $sample_image_id ) ) { + throw new \Exception( sprintf( 'The sample image wp_insert_attachment is not working', self::$sample_image ) ); + } + + self::$related_fields[ $field_name ]['id'] = $sample_image_id; + } + + $pod = pods( $pod_name, null, false ); + + if ( ! $pod || ! $pod->valid() ) { + codecept_debug( 'Pod invalid: ' . $pod_name . ' ' . __LINE__ ); + + continue; + } + + $fields = $pod->fields(); + + // Handle related IDs. + foreach ( $fields as $field ) { + if ( ! isset( self::$related_fields[ $field['name'] ] ) ) { + continue; + } + + if ( ! isset( self::$related_fields[ $field['name'] ]['id'] ) ) { + if ( isset( $item[ $field['name'] ] ) ) { + // Don't save for now. + unset( $item[ $field['name'] ] ); + } + + continue; + } + + $item[ $field['name'] ] = self::$related_fields[ $field['name'] ]['id']; + + foreach ( self::$related_fields[ $field_name ]['_items'] as $related_key => $related_item ) { + $related_item[ $field['name'] ] = $item[ $field['name'] ]; + + self::$related_fields[ $field_name ]['_items'][ $related_key ] = $related_item; + } + } + + if ( 0 === $depth ) { + if ( 0 < $is_multi ) { + $id = $pod->add( $item ); + + self::$related_fields[ $field_name ]['id'] = self::$related_fields[ $field_name ]['id']; + self::$related_fields[ $field_name ]['_index'] = self::$related_fields[ $field_name ]['_index']; + + if ( ! is_array( self::$related_fields[ $field_name ]['id'] ) ) { + if ( ! is_array( self::$related_fields[ $field_name ]['_index'] ) ) { + self::$related_fields[ $field_name ]['_index'] = [ + self::$related_fields[ $field_name ]['id'] => self::$related_fields[ $field_name ]['_index'], + ]; + } + + self::$related_fields[ $field_name ]['id'] = [ + self::$related_fields[ $field_name ]['id'] => self::$related_fields[ $field_name ]['id'], + ]; + } + + self::$related_fields[ $field_name ]['id'][ $id ] = $id; + self::$related_fields[ $field_name ]['_index'][ $id ] = $item[ $pod->pod_data['field_index'] ]; + + self::$related_fields[ $field_name ]['_items'][ $id ] = $item; + } else { + if ( ! empty( self::$related_fields[ $field_name ]['id'] ) ) { + $id = $pod->save( $item, null, self::$related_fields[ $field_name ]['id'] ); + } else { + $id = $pod->add( $item ); + } + + self::$related_fields[ $field_name ]['id'] = $id; + + self::$related_fields[ $field_name ]['_index'] = $item[ $pod->pod_data['field_index'] ]; + + self::$related_fields[ $field_name ]['_items'][ $id ] = $item; + } + + $item['id'] = self::$related_fields[ $field_name ]['id']; + $item['_index'] = self::$related_fields[ $field_name ]['_index']; + + $item['_items'] = self::$related_fields[ $field_name ]['_items']; + } else { + $id = self::$related_fields[ $field_name ]['id']; + $index = self::$related_fields[ $field_name ]['_index']; + + // Get the last item in the array. + if ( is_array( $id ) ) { + // Handle ID. + $id = array_pop( $id ); + + $item['id'] = $id; + + // Handle index. + $index = array_pop( $index ); + + $item[ $pod->pod_data['field_index'] ] = $index; + } + + $pod->save( $item, null, $id ); + + if ( $is_multi ) { + $item['id'] = self::$related_fields[ $field_name ]['id']; + $item['_index'] = self::$related_fields[ $field_name ]['_index']; + + if ( ! is_array( $item['id'] ) ) { + if ( ! is_array( $item['_index'] ) ) { + $item['_index'] = [ + $item['id'] => $item['_index'], + ]; + } + + $item['id'] = [ + $item['id'] => $item['id'], + ]; + } + + $item['id'][ $id ] = $id; + $item['_index'][ $id ] = $index; + } else { + $item['id'] = self::$related_fields[ $field_name ]['id']; + $item['_index'] = self::$related_fields[ $field_name ]['_index']; + } + + $item['_items'] = self::$related_fields[ $field_name ]['_items']; + + $item[ $pod->pod_data['field_id'] ] = $id; + } + + $item['_field_id'] = $pod->pod_data['field_id']; + $item['_field_index'] = $pod->pod_data['field_index']; + + $save_data[ $field_name ] = $item; + } + + self::$related_data = $save_data; + + if ( 0 === $depth ) { + self::_initialize_pods_related_data( ++ $depth ); + } + } + + /** + * Initialize Pods test data. + * + * @param int $depth + * + * @throws \Exception + */ + public static function _initialize_pods_data( $depth = 0 ) { + $data = self::$data; + + $import_data = file_get_contents( dirname( __DIR__ ) . '/_data/traversal-data.json' ); + $import_data = json_decode( $import_data, true ); + + if ( empty( $data ) ) { + $data = $import_data; + } + + $save_data = []; + + foreach ( $data as $pod_name => $item ) { + $pod = pods( $pod_name, null, false ); + + if ( ! $pod || ! $pod->valid() ) { + codecept_debug( 'Pod invalid: ' . $pod_name . ' ' . __LINE__ ); + + continue; + } + + $fields = $pod->fields(); + + // Handle related IDs. + foreach ( $fields as $field ) { + if ( ! isset( self::$related_data[ $field['name'] ] ) ) { + continue; + } + + if ( ! isset( self::$related_data[ $field['name'] ]['id'] ) ) { + if ( isset( $item[ $field['name'] ] ) ) { + // Don't save for now. + unset( $item[ $field['name'] ] ); + } + + continue; + } + + $item[ $field['name'] ] = self::$related_data[ $field['name'] ]['id']; + } + + if ( 0 === $depth ) { + $item['id'] = $pod->add( $item ); + + $item[ $pod->pod_data['field_id'] ] = $item['id']; + + $item['_field_id'] = $pod->pod_data['field_id']; + $item['_field_index'] = $pod->pod_data['field_index']; + } else { + $id = $item['id']; + + $pod->save( $item, null, $id ); + } + + $save_data[ $pod_name ] = $item; + } + + self::$data = $save_data; + + if ( 0 === $depth ) { + self::_initialize_pods_data( ++ $depth ); + } + } + + /** + * Index build for testing. + * + * @param Pods\Whatsit $pod Whatsit object. + */ + public static function index_build( $pod ) { + $pod_type = $pod['type']; + $object = $pod['name']; + $storage_type = $pod['storage_type']; + + if ( ! isset( self::$builds[ $pod_type ] ) ) { + self::$builds[ $pod_type ] = []; + } + + if ( ! isset( self::$builds[ $pod_type ][ $object ] ) ) { + self::$builds[ $pod_type ][ $object ] = []; + } + + self::$builds[ $pod_type ][ $object ][ $storage_type ] = $pod; + } + + /** + * Data provider for all data to pass into Traversal test methods + * for all variations and combinations to be covered. + */ + public function data_provider_base() { + $load_config = filter_var( getenv( 'PODS_LOAD_DATA' ), FILTER_VALIDATE_BOOLEAN ); + + // Bail but don't throw skip notices. + if ( ! $load_config ) { + return [ [ 1, 2, 3 ] ]; + } + + $data_base = []; + + foreach ( self::$builds as $pod_type => $objects ) { + foreach ( $objects as $object => $storage_types ) { + foreach ( $storage_types as $storage_type => $pod ) { + $pod_name = $pod['name']; + + $data_base[ build_query( compact( [ 'pod_type', 'storage_type', 'pod_name' ] ) ) ] = [ + build_query( compact( [ 'pod_type', 'storage_type', 'pod_name' ] ) ), + [ + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'pod' => $pod, + ], + ]; + } + } + } + + return $data_base; + } + + /** + * Data provider for all data to pass into Traversal test methods + * for all variations and combinations to be covered. + */ + public function data_provider() { + $data = []; + + foreach ( self::$builds as $pod_type => $objects ) { + foreach ( $objects as $object => $storage_types ) { + foreach ( $storage_types as $storage_type => $pod ) { + foreach ( $pod['fields'] as $field_name => $field ) { + if ( ( empty( $field['pick_val'] ) && empty( $field['pick_object'] ) ) || ! in_array( $field['type'], [ + 'pick', + 'taxonomy', + 'avatar', + 'author', + ], true ) ) { + continue; + } + + if ( empty( $field['pick_val'] ) ) { + $field['pick_val'] = $field['pick_object']; + } + + $pod_name = $pod['name']; + $field_name = $field['name']; + + $data[ build_query( compact( [ 'pod_type', 'storage_type', 'pod_name', 'field_name' ] ) ) ] = [ + build_query( compact( [ 'pod_type', 'storage_type', 'pod_name', 'field_name' ] ) ), + [ + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'pod' => $pod, + 'field' => $field, + ], + ]; + }//end foreach + + // Non-Pod Taxonomy field + if ( 'post_type' === $pod_type && isset( $pod['object_fields']['test_non_pod_ct'] ) ) { + $field = $pod['object_fields']['test_non_pod_ct']; + + $pod_name = $pod['name']; + $field_name = $field['name']; + + $data[ build_query( compact( [ 'pod_type', 'storage_type', 'pod_name', 'field_name' ] ) ) ] = [ + build_query( compact( [ 'pod_type', 'storage_type', 'pod_name', 'field_name' ] ) ), + [ + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'pod' => $pod, + 'field' => $field, + ], + ]; + } + }//end foreach + }//end foreach + }//end foreach + + return $data; + } + + /** + * Data provider for all data to pass into Traversal test methods + * for all variations and combinations to be covered. + */ + public function data_provider_deep() { + $data_deep = []; + + foreach ( self::$builds as $pod_type => $objects ) { + foreach ( $objects as $object => $storage_types ) { + foreach ( $storage_types as $storage_type => $pod ) { + foreach ( $pod['fields'] as $field_name => $field ) { + if ( ( empty( $field['pick_val'] ) && empty( $field['pick_object'] ) ) || ! in_array( $field['type'], [ + 'pick', + 'taxonomy', + 'avatar', + 'author', + ], true ) ) { + continue; + } + + if ( empty( $field['pick_val'] ) ) { + $field['pick_val'] = $field['pick_object']; + } + + // Related pod traversal + if ( ! isset( self::$builds[ $field['pick_object'] ][ $field['pick_val'] ], self::$related_data[ $field['name'] ] ) ) { + continue; + } + + $related_pod = current( self::$builds[ $field['pick_object'] ][ $field['pick_val'] ] ); + + foreach ( $related_pod['fields'] as $related_pod_field ) { + if ( empty( $related_pod_field['pick_val'] ) && ! empty( $related_pod_field['pick_object'] ) ) { + $related_pod_field['pick_val'] = $related_pod_field['pick_object']; + } + + $pod_name = $pod['name']; + $field_name = $field['name']; + $related_pod_name = $related_pod['name']; + $related_pod_field_name = $related_pod_field['name']; + + $data_deep[ build_query( compact( [ + 'pod_type', + 'storage_type', + 'pod_name', + 'field_name', + 'related_pod_name', + 'related_pod_field_name', + ] ) ) ] = [ + build_query( compact( [ + 'pod_type', + 'storage_type', + 'pod_name', + 'field_name', + 'related_pod_name', + 'related_pod_field_name', + ] ) ), + [ + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'pod' => $pod, + 'field' => $field, + 'related_pod' => $related_pod, + 'related_pod_field' => $related_pod_field, + ], + ]; + + continue; + // To be continued.. + // @todo Handle one more level deeper + if ( ! in_array( $related_pod_field['type'], [ + 'pick', + 'taxonomy', + 'avatar', + 'author', + ], true ) ) { + continue; + } + + if ( empty( $related_pod_field['pick_val'] ) ) { + if ( empty( $related_pod_field['pick_object'] ) ) { + continue; + } + + $related_pod_field['pick_val'] = $related_pod_field['pick_object']; + } + + if ( ! isset( self::$builds[ $related_pod_field['pick_object'] ][ $related_pod_field['pick_val'] ], self::$related_data[ $related_pod_field['name'] ] ) ) { + continue; + } + + // Related pod traversal + $sub_related_pod = current( self::$builds[ $related_pod_field['pick_object'] ][ $related_pod_field['pick_val'] ] ); + + foreach ( $sub_related_pod['fields'] as $sub_related_pod_field ) { + if ( empty( $sub_related_pod_field['pick_val'] ) ) { + if ( empty( $sub_related_pod_field['pick_object'] ) ) { + continue; + } + + $sub_related_pod_field['pick_val'] = $sub_related_pod_field['pick_object']; + } + + $sub_related_pod_name = $sub_related_pod['name']; + $sub_related_pod_field_name = $sub_related_pod_field['name']; + + $data_deep[ build_query( compact( [ + 'pod_type', + 'storage_type', + 'pod_name', + 'field_name', + 'related_pod_name', + 'related_pod_field_name', + 'sub_related_pod_name', + 'sub_related_pod_field_name', + ] ) ) ] = [ + build_query( compact( [ + 'pod_type', + 'storage_type', + 'pod_name', + 'field_name', + 'related_pod_name', + 'related_pod_field_name', + 'sub_related_pod_name', + 'sub_related_pod_field_name', + ] ) ), + [ + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'pod' => $pod, + 'field' => $field, + 'related_pod' => $related_pod, + 'related_pod_field' => $related_pod_field, + 'sub_related_pod' => $sub_related_pod, + 'sub_related_pod_field' => $sub_related_pod_field, + ], + ]; + }//end foreach + }//end foreach + }//end foreach + }//end foreach + }//end foreach + }//end foreach + + return $data_deep; + } +} diff --git a/tests/codeception/_support/Pods_UnitTestCase.php b/tests/codeception/_support/Pods_UnitTestCase.php new file mode 100644 index 0000000000..39fddaf9ea --- /dev/null +++ b/tests/codeception/_support/Pods_UnitTestCase.php @@ -0,0 +1,156 @@ +delete_objects(); + + $objects = $object_collection->get_objects(); + $default_objects = $object_collection->get_default_objects(); + + /** @var Pods\Whatsit\Storage\Collection $storage */ + $storage = $object_collection->get_storage_object( 'collection' ); + + // Delete groups/fields for internal objects. + foreach ( $objects as $identifier => $object ) { + if ( ! isset( $default_objects[ $identifier ] ) ) { + continue; + } + + // If this object has fields or groups, delete them. + $child_objects = array_merge( $object->get_all_fields(), $object->get_groups() ); + + // Delete child objects. + array_map( [ $storage, 'delete' ], $child_objects ); + + $object = null; + + unset( $object ); + + $object_collection->flatten_object( $identifier ); + } + + pods_api()->cache_flush_pods(); + } + + self::$pods = array(); + } + + /** + * @param $class + * @param $property + * + * @return mixed + */ + public function getReflectionPropertyValue( $class, $property ) { + try { + $reflection = new \ReflectionProperty( $class, $property ); + $reflection->setAccessible( true ); + + return $reflection->getValue( $class ); + } catch ( \ReflectionException $exception ) { + return null; + } + } + + /** + * @param $class + * @param $property + * @param $value + */ + public function setReflectionPropertyValue( $class, $property, $value ) { + try { + $reflection = new \ReflectionProperty( $class, $property ); + $reflection->setAccessible( true ); + + $reflection->setValue( $class, $value ); + } catch ( \ReflectionException $exception ) { + // Do nothing. + } + } + + /** + * @param $class + * @param $method + * + * @return mixed + */ + public function reflectionMethodInvoke( $class, $method ) { + try { + $reflection = new \ReflectionMethod( $class, $method ); + $reflection->setAccessible( true ); + + return $reflection->invoke( $class ); + } catch ( \ReflectionException $exception ) { + return null; + } + } + + /** + * @param $class + * @param $method + * @param $args + * + * @return mixed + */ + public function reflectionMethodInvokeArgs( $class, $method, $args ) { + try { + $reflection = new \ReflectionMethod( $class, $method ); + $reflection->setAccessible( true ); + + return $reflection->invokeArgs( $class, $args ); + } catch ( \ReflectionException $exception ) { + return null; + } + } + + /** + * Get/create pod from store. + * + * @param string $pod + * + * @return Pods + */ + public static function get_pod( $pod ) { + if ( ! isset( self::$pods[ $pod ] ) ) { + self::$pods[ $pod ] = pods( $pod, null, false ); + } + + return self::$pods[ $pod ]; + } +} diff --git a/tests/codeception/_support/Pods_UnitTest_Factory.php b/tests/codeception/_support/Pods_UnitTest_Factory.php new file mode 100644 index 0000000000..b1cd366da5 --- /dev/null +++ b/tests/codeception/_support/Pods_UnitTest_Factory.php @@ -0,0 +1,30 @@ +pod = new Pods_UnitTest_Factory_For_Pod( $this ); + } +} diff --git a/tests/codeception/_support/Pods_UnitTest_Factory_For_Field.php b/tests/codeception/_support/Pods_UnitTest_Factory_For_Field.php new file mode 100644 index 0000000000..ee375f0786 --- /dev/null +++ b/tests/codeception/_support/Pods_UnitTest_Factory_For_Field.php @@ -0,0 +1,47 @@ +default_generation_definitions = array( + 'id' => new \WP_UnitTest_Generator_Sequence( '%s' ), + 'name' => new \WP_UnitTest_Generator_Sequence( 'test-field-%s' ), + 'label' => new \WP_UnitTest_Generator_Sequence( 'Test Field %s' ), + ); + } + + /** + * @param $args + */ + public function create_object( $args ) { + // not yet implemented + } + + /** + * @param $post_id + * @param $fields + */ + public function update_object( $post_id, $fields ) { + // not yet implemented + } + + /** + * @param $post_id + */ + public function get_object_by_id( $post_id ) { + // not yet implemented + } +} diff --git a/tests/codeception/_support/Pods_UnitTest_Factory_For_Pod.php b/tests/codeception/_support/Pods_UnitTest_Factory_For_Pod.php new file mode 100644 index 0000000000..9697e45339 --- /dev/null +++ b/tests/codeception/_support/Pods_UnitTest_Factory_For_Pod.php @@ -0,0 +1,58 @@ +default_generation_definitions = array( + 'id' => new \WP_UnitTest_Generator_Sequence( '%s' ), + 'name' => new \WP_UnitTest_Generator_Sequence( 'test-pod-%s' ), + 'label' => new \WP_UnitTest_Generator_Sequence( 'Test Pod %s' ), + ); + } + + /** + * @param $args + * + * @return int + */ + public function create_object( $args ) { + if ( in_array( $args['name'], pods_reserved_keywords(), true ) ) { + /* + * Extending objects when using reserved keywords. + * + * This will then accept `post`, `page` etc. as Pods object names. + */ + $args['create_extend'] = 'extend'; + } + + return pods_api()->save_pod( $args ); + } + + /** + * @param $post_id + * @param $fields + */ + public function update_object( $post_id, $fields ) { + // not yet implemented + } + + /** + * @param $post_id + */ + public function get_object_by_id( $post_id ) { + // not yet implemented + } +} diff --git a/tests/codeception/_support/Pods_WhatsitTestCase.php b/tests/codeception/_support/Pods_WhatsitTestCase.php new file mode 100644 index 0000000000..45b0299796 --- /dev/null +++ b/tests/codeception/_support/Pods_WhatsitTestCase.php @@ -0,0 +1,169 @@ +pods_object_storage = $object_collection->get_storage_object( $this->storage_type ); + + // Setup pod. + $pod_args = array( + 'object_type' => 'pod', + 'name' => 'test-pod', + 'label' => 'Test pod', + 'description' => 'Testing pod', + 'type' => 'post_type', + 'storage' => 'meta', + 'object' => 'test-pod', + ); + + $this->pods_object_pod = $this->setup_pods_object( $pod_args, 'pod' ); + + // Setup group. + $group_args = array( + 'object_type' => 'group', + 'name' => 'test-group', + 'label' => 'Test group', + 'description' => 'Testing group', + 'parent' => $this->pods_object_pod->get_id(), + 'type' => 'metabox', + ); + + $this->pods_object_group = $this->setup_pods_object( $group_args, 'group' ); + + // Setup field. + $field_args = array( + 'object_type' => 'field', + 'name' => 'test-field', + 'label' => 'Test field', + 'description' => 'Testing field', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'type' => 'text', + ); + + $this->pods_object_field = $this->setup_pods_object( $field_args, 'field' ); + } + + public function tearDown(): void { + unset( $this->pods_object_pod, $this->pods_object_group, $this->pods_object_field ); + + $this->setup_objects = array(); + + $this->pod_args = array(); + $this->group_args = array(); + $this->field_args = array(); + + unset( $this->pods_object_storage ); + + parent::tearDown(); + } + + /** + * Setup and return a Whatsit. + * + * @param array $args Object arguments. + * @param string $type Object type. + * + * @return Whatsit + */ + public function setup_pods_object( array $args = array(), $type = '' ) { + $defaults = array( + 'object_type' => 'pod', + 'storage_type' => 'post_type', + 'id' => '', + 'name' => 'test', + 'label' => 'Test', + 'description' => 'Testing', + 'parent' => '', + 'group' => '', + 'custom1' => 'value1', + ); + + $args = array_merge( $defaults, $args ); + + $args['custom1'] = $args['custom1'] . '-' . $args['name']; + + $object_collection = Store::get_instance(); + + $class_name = $object_collection->get_object_type( $args['object_type'] ); + + /** @var Whatsit $object */ + $object = new $class_name; + $object->setup( $args ); + + $id = $this->pods_object_storage->add( $object ); + + $args['id'] = $id; + + if ( 'pod' === $type ) { + $this->pod_args = $args; + } elseif ( 'group' === $type ) { + $this->group_args = $args; + } elseif ( 'field' === $type ) { + $this->field_args = $args; + } + + $this->setup_objects[] =& $object; + + return $object; + } + +} diff --git a/tests/codeception/_support/Restv1Tester.php b/tests/codeception/_support/Restv1Tester.php new file mode 100644 index 0000000000..3bafa03002 --- /dev/null +++ b/tests/codeception/_support/Restv1Tester.php @@ -0,0 +1,29 @@ +factory = $I->factory(); + $this->site_url = $I->grabSiteUrl(); + $this->wp_rest_url = $this->site_url . '/wp-json/wp/v2/'; + $this->pods_rest_url = $this->site_url . '/wp-json/pods/v1/'; + + // Reset the user to visitor before each test. + wp_set_current_user( 0 ); + } + + public function _after( Restv1Tester $I ) { + // Do any other tear down here. + } + + /** + * Set name for snapshot. + * + * @param string $name Method identifier for snapshot. + */ + protected function setName( $name ) { + $this->name = $name; + } + + /** + * Get name for snapshot. + * + * @return string Method identifier for snapshot. + */ + protected function getName() { + return $this->name; + } +} \ No newline at end of file diff --git a/tests/codeception/_support/Testcases/REST/PodsRestCest.php b/tests/codeception/_support/Testcases/REST/PodsRestCest.php new file mode 100644 index 0000000000..b91598f614 --- /dev/null +++ b/tests/codeception/_support/Testcases/REST/PodsRestCest.php @@ -0,0 +1,80 @@ +test_rest_url = $this->pods_rest_url . 'fields/%d'; + + $api = pods_api(); + + $this->pod_id = $api->save_pod( [ + 'storage' => 'meta', + 'type' => 'post_type', + 'name' => 'my-pod', + ] ); + + $this->group_id = $api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => 'my-group', + ] ); + + $this->group_id2 = $api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => 'my-group2', + ] ); + + $this->field_id = $api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'my-field', + 'type' => 'text', + ] ); + + $this->field_id2 = $api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'my-field2', + 'type' => 'text', + ] ); + + $this->field_id3 = $api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id2, + 'name' => 'my-field3', + 'type' => 'text', + ] ); + + $this->field_id4 = $api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id2, + 'name' => 'my-field4', + 'type' => 'text', + ] ); + } + + public function _after( Restv1Tester $I ) { + $this->pod_id = null; + $this->group_id = null; + $this->group_id2 = null; + $this->field_id = null; + $this->field_id2 = null; + $this->field_id3 = null; + $this->field_id4 = null; + + parent::_after( $I ); + } +} \ No newline at end of file diff --git a/tests/codeception/_support/Traits/REST/Auth.php b/tests/codeception/_support/Traits/REST/Auth.php new file mode 100644 index 0000000000..67669d4253 --- /dev/null +++ b/tests/codeception/_support/Traits/REST/Auth.php @@ -0,0 +1,37 @@ +haveUserInDatabase( 'user', $role, [ 'user_pass' => 'user' ] ); + + // login to get the cookies + $I->loginAs( 'user', 'user' ); + + // nonce recipes + $_COOKIE[ LOGGED_IN_COOKIE ] = $I->grabCookie( LOGGED_IN_COOKIE ); + wp_set_current_user( $user_id ); + + $nonce = wp_create_nonce( 'wp_rest' ); + + $I->haveHttpHeader( 'X-WP-Nonce', $nonce ); + + return $nonce; + } +} \ No newline at end of file diff --git a/tests/codeception/_support/WpunitTester.php b/tests/codeception/_support/WpunitTester.php new file mode 100644 index 0000000000..89cdcaa8c1 --- /dev/null +++ b/tests/codeception/_support/WpunitTester.php @@ -0,0 +1,26 @@ + $value ) { + $obj->{$key} = $value; + } + + return $obj; + } +} diff --git a/tests/codeception/integration.suite.dist.yml b/tests/codeception/integration.suite.dist.yml new file mode 100644 index 0000000000..efbf01b3d0 --- /dev/null +++ b/tests/codeception/integration.suite.dist.yml @@ -0,0 +1,24 @@ +# Codeception Test Suite Configuration + +# suite for WordPress functional tests. +# Emulate web requests and make application process them. +class_name: IntegrationTester +modules: + enabled: + - \Helper\Integration + - WPLoader + config: + WPLoader: + wpRootFolder: %WP_ROOT_FOLDER% + dbName: %WP_TEST_DB_NAME% + dbHost: %WP_TEST_DB_HOST% + dbUser: %WP_TEST_DB_USER% + dbPassword: %WP_TEST_DB_PASSWORD% + tablePrefix: %WP_TABLE_PREFIX% + domain: %WP_DOMAIN% + adminEmail: admin@%WP_DOMAIN% + title: 'Pods Tests' + plugins: + - pods/init.php + activatePlugins: + - pods/init.php diff --git a/tests/codeception/integration/_bootstrap.php b/tests/codeception/integration/_bootstrap.php new file mode 100644 index 0000000000..8a88555806 --- /dev/null +++ b/tests/codeception/integration/_bootstrap.php @@ -0,0 +1,2 @@ +test_rest_url = $this->pods_rest_url . 'fields/%d'; + } + + /** + * It should not have access to getting list of field. + * + * @test + */ + public function should_not_have_access_to_getting_field( Restv1Tester $I ) { + $I->sendGET( sprintf( $this->test_rest_url, $this->field_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 401 ); + + $I->seeResponseContainsJson( [ + 'code' => 'rest_forbidden', + ] ); + } + + /** + * It should allow getting field. + * + * @test + */ + public function should_allow_getting_field( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->field_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'my-field', $response['field']['name'] ); + $I->assertEquals( 'text', $response['field']['type'] ); + $I->assertEquals( $this->field_id, $response['field']['id'] ); + } + + /** + * It should allow updating field. + * + * @test + */ + public function should_allow_updating_field( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $args = [ + 'name' => 'new_name', + 'label' => 'New label', + 'type' => 'website', + 'args' => [ + 'test_update' => 1, + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->field_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['field']['name'] ); + $I->assertEquals( $args['label'], $response['field']['label'] ); + $I->assertEquals( $args['type'], $response['field']['type'] ); + $I->assertEquals( $this->field_id, $response['field']['id'] ); + $I->assertArrayHasKey( 'test_update', $response['field'] ); + $I->assertEquals( $args['args']['test_update'], $response['field']['test_update'] ); + + // Make another request to ensure it's returning uncached. + $args = [ + 'name' => 'new_name2', + 'label' => 'New label2', + 'type' => 'number', + 'args' => [ + 'test_update' => 2, + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->field_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['field']['name'] ); + $I->assertEquals( $args['label'], $response['field']['label'] ); + $I->assertEquals( $args['type'], $response['field']['type'] ); + $I->assertEquals( $this->field_id, $response['field']['id'] ); + $I->assertArrayHasKey( 'test_update', $response['field'] ); + $I->assertEquals( $args['args']['test_update'], $response['field']['test_update'] ); + } + + /** + * It should allow deleting field. + * + * @test + */ + public function should_allow_deleting_field( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $post_id = $I->havePostInDatabase( [ + 'post_type' => 'my-pod', + 'post_title' => 'Test content', + 'post_content' => 'Test content', + ] ); + $I->havePostMetaInDatabase( $post_id, 'my-field', 'test meta' ); + + $I->sendDELETE( sprintf( $this->test_rest_url, $this->field_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + $I->seeResponseContainsJson( [ + 'status' => 'deleted', + ] ); + + $I->seePostInDatabase( [ 'ID' => $post_id ] ); + $I->dontSeePostInDatabase( [ 'ID' => $this->field_id ] ); + + // Content should still remain. + $I->seePostMetaInDatabase( [ 'post_id' => $post_id, 'meta_key' => 'my-field' ] ); + } +} diff --git a/tests/codeception/restv1/Pods/FieldsCest.php b/tests/codeception/restv1/Pods/FieldsCest.php new file mode 100644 index 0000000000..c8bc14dcd5 --- /dev/null +++ b/tests/codeception/restv1/Pods/FieldsCest.php @@ -0,0 +1,108 @@ +test_rest_url = $this->pods_rest_url . 'fields'; + } + + /** + * It should not have access to getting list of fields. + * + * @test + */ + public function should_not_have_access_to_getting_fields( Restv1Tester $I ) { + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 401 ); + + $I->seeResponseContainsJson( [ + 'code' => 'rest_forbidden', + ] ); + } + + /** + * It should allow getting all fields. + * + * @test + */ + public function should_allow_getting_all_fields( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( $this->test_rest_url, [ + 'types' => 'text', + 'include_parent' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertArrayHasKey( 'fields', $response ); + $I->assertCount( 6, $response['fields'] ); + $I->assertContains( 'my-field', wp_list_pluck( $response['fields'], 'name' ) ); + $I->assertContains( $this->field_id, wp_list_pluck( $response['fields'], 'id' ) ); + $I->assertContains( $this->pod_id, wp_list_pluck( wp_list_pluck( $response['fields'], 'parent_data' ), 'id' ) ); + } + + /** + * It should allow getting bi-directional fields. + * + * @test + */ + public function should_allow_getting_bi_directional_fields( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $api = pods_api(); + + // Create a new pod. + $pod_id2 = $api->save_pod( [ + 'storage' => 'meta', + 'type' => 'post_type', + 'name' => 'my-pod2', + ] ); + + // Create a new relationship field to our current pod. + $related_field_id = $api->save_field( [ + 'pod_id' => $pod_id2, + 'name' => 'my-related-field', + 'type' => 'pick', + 'pick_object' => 'post_type', + 'pick_val' => 'my-pod', + ] ); + + // Get fields related to our current pod, on the new pod. + $I->sendGET( $this->test_rest_url, [ + 'types' => 'pick', + 'pod' => 'my-pod2', + 'include_parent' => 1, + 'args' => [ + 'pick_object' => 'post_type', + 'pick_val' => 'my-pod', + ], + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertArrayHasKey( 'fields', $response ); + $I->assertCount( 1, $response['fields'] ); + $I->assertEquals( 'my-related-field', $response['fields'][0]['name'] ); + $I->assertEquals( 'pick', $response['fields'][0]['type'] ); + $I->assertEquals( $related_field_id, $response['fields'][0]['id'] ); + $I->assertArrayHasKey( 'parent_data', $response['fields'][0] ); + $I->assertEquals( $pod_id2, $response['fields'][0]['parent_data']['id'] ); + $I->assertEquals( 'my-pod2', $response['fields'][0]['parent_data']['name'] ); + } +} diff --git a/tests/codeception/restv1/Pods/GroupCest.php b/tests/codeception/restv1/Pods/GroupCest.php new file mode 100644 index 0000000000..1646a411e8 --- /dev/null +++ b/tests/codeception/restv1/Pods/GroupCest.php @@ -0,0 +1,161 @@ +test_rest_url = $this->pods_rest_url . 'groups/%d'; + } + + /** + * It should not have access to getting list of group. + * + * @test + */ + public function should_not_have_access_to_getting_group( Restv1Tester $I ) { + $I->sendGET( sprintf( $this->test_rest_url, $this->group_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 401 ); + + $I->seeResponseContainsJson( [ + 'code' => 'rest_forbidden', + ] ); + } + + /** + * It should allow getting group. + * + * @test + */ + public function should_allow_getting_group( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->group_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'my-group', $response['group']['name'] ); + $I->assertEquals( $this->group_id, $response['group']['id'] ); + $I->assertArrayNotHasKey( 'fields', $response['group'] ); + } + + /** + * It should allow getting group with fields. + * + * @test + */ + public function should_allow_getting_group_with_fields( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->group_id ), [ + 'include_fields' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'my-group', $response['group']['name'] ); + $I->assertEquals( $this->group_id, $response['group']['id'] ); + $I->assertArrayHasKey( 'fields', $response['group'] ); + $I->assertCount( 2, $response['group']['fields'] ); + $I->assertEquals( $this->field_id, $response['group']['fields'][0]['id'] ); + $I->assertEquals( $this->field_id2, $response['group']['fields'][1]['id'] ); + } + + /** + * It should allow updating group. + * + * @test + */ + public function should_allow_updating_group( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $args = [ + 'name' => 'new_name', + 'label' => 'New label', + 'args' => [ + 'test_update' => 1, + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->group_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['group']['name'] ); + $I->assertEquals( $args['label'], $response['group']['label'] ); + $I->assertEquals( $this->group_id, $response['group']['id'] ); + $I->assertArrayHasKey( 'test_update', $response['group'] ); + $I->assertEquals( $args['args']['test_update'], $response['group']['test_update'] ); + $I->assertArrayNotHasKey( 'fields', $response['group'] ); + + // Make another request to ensure it's returning uncached. + $args = [ + 'name' => 'new_name2', + 'label' => 'New label2', + 'args' => [ + 'test_update' => 2, + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->group_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['group']['name'] ); + $I->assertEquals( $args['label'], $response['group']['label'] ); + $I->assertEquals( $this->group_id, $response['group']['id'] ); + $I->assertArrayHasKey( 'test_update', $response['group'] ); + $I->assertEquals( $args['args']['test_update'], $response['group']['test_update'] ); + $I->assertArrayNotHasKey( 'fields', $response['group'] ); + } + + /** + * It should allow deleting group. + * + * @test + */ + public function should_allow_deleting_group( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $post_id = $I->havePostInDatabase( [ + 'post_type' => 'my-pod', + 'post_title' => 'Test content', + 'post_content' => 'Test content', + ] ); + $I->havePostMetaInDatabase( $post_id, 'my-field', 'test meta' ); + + $I->sendDELETE( sprintf( $this->test_rest_url, $this->group_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + $I->seeResponseContainsJson( [ + 'status' => 'deleted', + ] ); + + $I->seePostInDatabase( [ 'ID' => $post_id ] ); + $I->dontSeePostInDatabase( [ 'ID' => $this->group_id ] ); + $I->dontSeePostInDatabase( [ 'ID' => $this->field_id ] ); + + // Content should still remain. + $I->seePostMetaInDatabase( [ 'post_id' => $post_id, 'meta_key' => 'my-field' ] ); + } +} diff --git a/tests/codeception/restv1/Pods/PodCest.php b/tests/codeception/restv1/Pods/PodCest.php new file mode 100644 index 0000000000..cb0dc299d2 --- /dev/null +++ b/tests/codeception/restv1/Pods/PodCest.php @@ -0,0 +1,352 @@ +test_rest_url = $this->pods_rest_url . 'pods/%d'; + } + + /** + * It should not have access to getting list of pod. + * + * @test + */ + public function should_not_have_access_to_getting_pod( Restv1Tester $I ) { + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 401 ); + + $I->seeResponseContainsJson( [ + 'code' => 'rest_forbidden', + ] ); + } + + /** + * It should allow getting Pod. + * + * @test + */ + public function should_allow_getting_pod( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'meta', $response['pod']['storage'] ); + $I->assertEquals( 'post_type', $response['pod']['type'] ); + $I->assertEquals( 'my-pod', $response['pod']['name'] ); + $I->assertArrayNotHasKey( 'groups', $response['pod'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod'] ); + } + + /** + * It should allow getting Pod with groups. + * + * @test + */ + public function should_allow_getting_pod_with_groups( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ), [ + 'include_groups' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'meta', $response['pod']['storage'] ); + $I->assertEquals( 'post_type', $response['pod']['type'] ); + $I->assertEquals( 'my-pod', $response['pod']['name'] ); + $I->assertArrayHasKey( 'groups', $response['pod'] ); + $I->assertEquals( $this->group_id, $response['pod']['groups'][0]['id'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod']['groups'][0] ); + } + + /** + * It should allow getting Pod with fields. + * + * @test + */ + public function should_allow_getting_pod_with_fields( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ), [ + 'include_fields' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'meta', $response['pod']['storage'] ); + $I->assertEquals( 'post_type', $response['pod']['type'] ); + $I->assertEquals( 'my-pod', $response['pod']['name'] ); + $I->assertArrayNotHasKey( 'groups', $response['pod'] ); + $I->assertArrayHasKey( 'fields', $response['pod'] ); + $I->assertEquals( $this->field_id, $response['pod']['fields'][0]['id'] ); + } + + /** + * It should allow getting Pod with group fields. + * + * @test + */ + public function should_allow_getting_pod_with_group_fields( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ), [ + 'include_groups' => 1, + 'include_group_fields' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'meta', $response['pod']['storage'] ); + $I->assertEquals( 'post_type', $response['pod']['type'] ); + $I->assertEquals( 'my-pod', $response['pod']['name'] ); + $I->assertArrayHasKey( 'groups', $response['pod'] ); + $I->assertEquals( $this->group_id, $response['pod']['groups'][0]['id'] ); + $I->assertArrayHasKey( 'fields', $response['pod']['groups'][0] ); + $I->assertEquals( $this->field_id, $response['pod']['groups'][0]['fields'][0]['id'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod'] ); + } + + /** + * It should allow getting Pod with groups and fields. + * + * @test + */ + public function should_allow_getting_pod_with_groups_and_fields( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ), [ + 'include_groups' => 1, + 'include_fields' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( 'meta', $response['pod']['storage'] ); + $I->assertEquals( 'post_type', $response['pod']['type'] ); + $I->assertEquals( 'my-pod', $response['pod']['name'] ); + $I->assertArrayHasKey( 'groups', $response['pod'] ); + $I->assertEquals( $this->group_id, $response['pod']['groups'][0]['id'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod']['groups'][0] ); + $I->assertArrayHasKey( 'fields', $response['pod'] ); + $I->assertEquals( $this->field_id, $response['pod']['fields'][0]['id'] ); + } + + /** + * It should allow updating Pod. + * + * @test + */ + public function should_allow_updating_pod( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $args = [ + 'name' => 'new_name', + 'label' => 'New label', + 'args' => [ + 'test_update' => 1, + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->pod_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['pod']['name'] ); + $I->assertEquals( $args['label'], $response['pod']['label'] ); + $I->assertArrayHasKey( 'test_update', $response['pod'] ); + $I->assertEquals( $args['args']['test_update'], $response['pod']['test_update'] ); + $I->assertArrayNotHasKey( 'groups', $response['pod'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod'] ); + + // Make another request to ensure it's returning uncached. + $args = [ + 'name' => 'new_name2', + 'label' => 'New label2', + 'args' => [ + 'test_update' => 2, + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->pod_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['pod']['name'] ); + $I->assertEquals( $args['label'], $response['pod']['label'] ); + $I->assertArrayHasKey( 'test_update', $response['pod'] ); + $I->assertEquals( $args['args']['test_update'], $response['pod']['test_update'] ); + $I->assertArrayNotHasKey( 'groups', $response['pod'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod'] ); + } + + /** + * It should allow updating Pod. + * + * @test + */ + public function should_allow_updating_pod_with_groups_and_fields_order( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $args = [ + 'name' => 'new_name', + 'label' => 'New label', + 'args' => [ + 'test_update' => 1, + ], + 'order' => [ + 'groups' => [ + [ + 'group_id' => $this->group_id2, + 'fields' => [ + $this->field_id4, + $this->field_id3, + ], + ], + [ + 'group_id' => $this->group_id, + 'fields' => [ + $this->field_id2, + $this->field_id, + ], + ], + ], + ], + ]; + + $I->sendPOST( sprintf( $this->test_rest_url, $this->pod_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertEquals( $args['name'], $response['pod']['name'] ); + $I->assertEquals( $args['label'], $response['pod']['label'] ); + $I->assertArrayHasKey( 'test_update', $response['pod'] ); + $I->assertEquals( $args['args']['test_update'], $response['pod']['test_update'] ); + $I->assertArrayNotHasKey( 'groups', $response['pod'] ); + $I->assertArrayNotHasKey( 'fields', $response['pod'] ); + + $I->sendGET( sprintf( $this->test_rest_url, $this->pod_id ), [ + 'include_groups' => 1, + 'include_group_fields' => 1, + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->seePostInDatabase( [ + 'ID' => $this->group_id2, + 'menu_order' => 0, + ] ); + $I->seePostInDatabase( [ + 'ID' => $this->field_id4, + 'menu_order' => 0, + ] ); + $I->seePostInDatabase( [ + 'ID' => $this->field_id3, + 'menu_order' => 1, + ] ); + + $I->seePostInDatabase( [ + 'ID' => $this->group_id, + 'menu_order' => 1, + ] ); + $I->seePostInDatabase( [ + 'ID' => $this->field_id2, + 'menu_order' => 0, + ] ); + $I->seePostInDatabase( [ + 'ID' => $this->field_id, + 'menu_order' => 1, + ] ); + } + + /** + * It should allow deleting Pod. + * + * @test + */ + public function should_allow_deleting_pod( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $post_id = $I->havePostInDatabase( [ + 'post_type' => 'my-pod', + 'post_title' => 'Test content', + 'post_content' => 'Test content', + ] ); + + $I->sendDELETE( sprintf( $this->test_rest_url, $this->pod_id ) ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + $I->seeResponseContainsJson( [ + 'status' => 'deleted', + ] ); + + $I->seePostInDatabase( [ 'ID' => $post_id ] ); + } + + /** + * It should allow deleting Pod and all content. + * + * @test + */ + public function should_allow_deleting_pod_and_all_content( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $post_id = $I->havePostInDatabase( [ + 'post_type' => 'my-pod', + 'post_title' => 'Test content', + 'post_content' => 'Test content', + ] ); + + $args = [ + 'delete_all' => 1, + ]; + + $I->sendDELETE( sprintf( $this->test_rest_url, $this->pod_id ), $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + $I->seeResponseContainsJson( [ + 'status' => 'deleted', + ] ); + + $I->dontSeePostInDatabase( [ 'ID' => $post_id ] ); + } +} diff --git a/tests/codeception/restv1/Pods/PodsCest.php b/tests/codeception/restv1/Pods/PodsCest.php new file mode 100644 index 0000000000..b13e52f111 --- /dev/null +++ b/tests/codeception/restv1/Pods/PodsCest.php @@ -0,0 +1,551 @@ +test_rest_url = $this->pods_rest_url . 'pods'; + } + + /** + * It should not have access to getting list of pods. + * + * @test + */ + public function should_not_have_access_to_getting_pods( Restv1Tester $I ) { + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 401 ); + + $I->seeResponseContainsJson( [ + 'code' => 'rest_forbidden', + ] ); + } + + /** + * It should allow getting list of Pods. + * + * @test + */ + public function should_allow_getting_list_of_pods( Restv1Tester $I ) { + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertCount( 14, $response['pods'] ); + } + + public function provider_return_type() { + yield 'full' => [ + 'return_type' => 'full', + 'expected' => [ + // Compare IDs here, assertion will handle that. + 67, + 113, + 104, + 85, + 40, + 31, + 22, + 76, + 122, + 4, + 13, + 58, + 49, + 94, + ], + ]; + + yield 'names' => [ + 'return_type' => 'names', + 'expected' => [ + 'category', + 'comment', + 'media', + 'nav_menu', + 'nav_menu_item', + 'page', + 'post', + 'post_tag', + 'test_act', + 'test_post_meta', + 'test_post_table', + 'test_tax_meta', + 'test_tax_table', + 'user', + ], + ]; + + yield 'ids' => [ + 'return_type' => 'ids', + 'expected' => [ + 67, + 113, + 104, + 85, + 40, + 31, + 22, + 76, + 122, + 4, + 13, + 58, + 49, + 94, + ], + ]; + + yield 'count' => [ + 'return_type' => 'count', + 'expected' => 14, + ]; + } + + /** + * It should allow getting list of Pods with return type. + * + * @test + * @dataProvider provider_return_type + */ + public function should_allow_getting_list_of_pods_with_return_type( Restv1Tester $I, Example $example ) { + $variation = $example->getIterator()->getArrayCopy(); + + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( $this->test_rest_url, [ + 'return_type' => $variation['return_type'], + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $pods = $response['pods']; + + // Compare IDs if doing full return. + if ( 'full' === $variation['return_type'] ) { + $pods = wp_list_pluck( $response['pods'], 'id' ); + } + + $I->assertEquals( $variation['expected'], $pods ); + } + + public function provider_types() { + yield 'post_type' => [ + 'types' => 'post_type', + 'expected' => [ + 4, + 13, + 22, + 31, + 40, + ], + ]; + + yield 'taxonomy' => [ + 'types' => 'taxonomy', + 'expected' => [ + 49, + 58, + 67, + 76, + 85, + ], + ]; + + yield 'media' => [ + 'types' => 'media', + 'expected' => [ + 104, + ], + ]; + + yield 'user' => [ + 'types' => 'user', + 'expected' => [ + 94, + ], + ]; + + yield 'settings' => [ + 'types' => 'settings', + 'expected' => [], + ]; + + yield 'pod' => [ + 'types' => 'pod', + 'expected' => [ + 122, + ], + ]; + + yield 'post_type + taxonomy' => [ + 'types' => [ + 'post_type', + 'taxonomy', + ], + 'expected' => [ + 4, + 13, + 22, + 31, + 40, + 49, + 58, + 67, + 76, + 85, + ], + ]; + + yield 'post_type + taxonomy (string)' => [ + 'types' => 'post_type,taxonomy', + 'expected' => [ + 4, + 13, + 22, + 31, + 40, + 49, + 58, + 67, + 76, + 85, + ], + ]; + + yield '(empty)' => [ + 'types' => '', + 'expected' => [ + 4, + 13, + 22, + 31, + 40, + 49, + 58, + 67, + 76, + 85, + 94, + 104, + 113, + 122, + ], + ]; + } + + /** + * It should allow getting list of Pods by types. + * + * @test + * @dataProvider provider_types + */ + public function should_allow_getting_list_of_pods_by_types( Restv1Tester $I, Example $example ) { + $variation = $example->getIterator()->getArrayCopy(); + + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( $this->test_rest_url, [ + 'types' => $variation['types'], + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $pods = wp_list_pluck( $response['pods'], 'id' ); + + sort( $pods ); + + $I->assertEquals( $variation['expected'], $pods ); + } + + public function provider_ids() { + yield 'one id array' => [ + 'ids' => [ + 113, + ], + 'expected' => [ + 113, + ], + ]; + + yield 'one id string' => [ + 'ids' => '113', + 'expected' => [ + 113, + ], + ]; + + yield 'multi id array' => [ + 'ids' => [ + 113, + 104, + ], + 'expected' => [ + 104, + 113, + ], + ]; + + yield 'multi id string' => [ + 'ids' => '113,104', + 'expected' => [ + 104, + 113, + ], + ]; + + yield '(empty)' => [ + 'ids' => '', + 'expected' => [ + 4, + 13, + 22, + 31, + 40, + 49, + 58, + 67, + 76, + 85, + 94, + 104, + 113, + 122, + ], + ]; + } + + /** + * It should allow getting list of Pods by ids. + * + * @test + * @dataProvider provider_ids + */ + public function should_allow_getting_list_of_pods_by_ids( Restv1Tester $I, Example $example ) { + $variation = $example->getIterator()->getArrayCopy(); + + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( $this->test_rest_url, [ + 'ids' => $variation['ids'], + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $pods = wp_list_pluck( $response['pods'], 'id' ); + + sort( $pods ); + + $I->assertEquals( $variation['expected'], $pods ); + } + + public function provider_args() { + yield 'match' => [ + 'args' => [ + 'pod_index' => 'name', + ], + 'expected' => [ + 122, + ], + ]; + + yield 'match multi args' => [ + 'args' => [ + 'pod_index' => 'name', + 'storage' => 'table', + ], + 'expected' => [ + 122, + ], + ]; + + yield 'no match' => [ + 'args' => [ + 'pod_index' => 'something-else', + ], + 'expected' => [], + ]; + } + + /** + * It should allow getting list of Pods by args. + * + * @test + * @dataProvider provider_args + */ + public function should_allow_getting_list_of_pods_by_args( Restv1Tester $I, Example $example ) { + $variation = $example->getIterator()->getArrayCopy(); + + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendGET( $this->test_rest_url, [ + 'args' => $variation['args'], + ] ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( 200 ); + + $response = json_decode( $I->grabResponse(), true ); + + $pods = wp_list_pluck( $response['pods'], 'id' ); + + sort( $pods ); + + $I->assertEquals( $variation['expected'], $pods ); + } + + public function provider_add_pod() { + yield 'create new pod' => [ + 'args' => [ + 'mode' => 'create', + 'name' => 'my-name', + 'label' => 'my-label-plural', + 'type' => 'post_type', + 'storage' => 'meta', + 'label_singular' => 'my-label-singular', + ], + 'expected_response_code' => 200, + ]; + + yield 'create new settings pod' => [ + 'args' => [ + 'mode' => 'create', + 'name' => 'my-name', + 'label' => 'my-label-plural', + 'type' => 'settings', + 'storage' => 'none', + 'label_singular' => 'my-label-singular', + 'menu_name' => 'my-label-menu', + 'menu_location' => 'menu-location', + ], + 'expected_response_code' => 200, + ]; + + yield 'extend pod' => [ + 'args' => [ + 'mode' => 'extend', + 'name' => 'topic', + 'type' => 'post_type', + 'storage' => 'meta', + ], + 'expected_response_code' => 200, + ]; + + yield 'extend pod that already exists' => [ + 'args' => [ + 'mode' => 'extend', + 'name' => 'post', + 'type' => 'post_type', + 'storage' => 'meta', + ], + 'expected_response_code' => 500, + 'expected_message' => 'Pod using post already exists, you can not reuse an object across multiple pods', + ]; + + yield 'create pod with unknown mode' => [ + 'args' => [ + 'mode' => 'unknown-mode', + 'name' => 'my-pod', + 'label' => 'my-label-plural', + 'type' => 'post_type', + 'storage' => 'meta', + ], + 'expected_response_code' => 400, + 'expected_message' => 'Invalid parameter(s): mode', + ]; + + yield 'create pod with unknown type' => [ + 'args' => [ + 'mode' => 'create', + 'name' => 'my-pod', + 'label' => 'my-label-plural', + 'type' => 'unknown', + 'storage' => 'meta', + ], + 'expected_response_code' => 400, + 'expected_message' => 'Invalid parameter(s): type', + ]; + + yield 'create pod with unknown storage' => [ + 'args' => [ + 'mode' => 'create', + 'name' => 'my-pod', + 'label' => 'my-label-plural', + 'type' => 'post_type', + 'storage' => 'unknown', + ], + 'expected_response_code' => 400, + 'expected_message' => 'Invalid parameter(s): storage', + ]; + } + + /** + * It should allow adding new pod. + * + * @test + * @dataProvider provider_add_pod + */ + public function should_allow_adding_new_pod( Restv1Tester $I, Example $example ) { + $variation = $example->getIterator()->getArrayCopy(); + + $args = $variation['args']; + + $I->generate_nonce_for_role( 'administrator' ); + + $I->sendPOST( $this->test_rest_url, $args ); + + $I->seeResponseIsJson(); + $I->seeResponseCodeIs( $variation['expected_response_code'] ); + + if ( ! empty( $variation['expected_message'] ) ) { + $I->seeResponseContainsJson( [ + 'message' => $variation['expected_message'], + ] ); + + return; + } + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertArrayHasKey( 'pod', $response ); + + foreach ( $args as $arg => $value ) { + if ( 'mode' === $arg ) { + if ( 'create' === $value ) { + $I->assertArrayNotHasKey( 'object', $response['pod'] ); + } else { + $I->assertArrayHasKey( 'object', $response['pod'] ); + $I->assertEquals( $args['name'], $response['pod']['object'] ); + } + + continue; + } + + $I->assertArrayHasKey( $arg, $response['pod'] ); + $I->assertEquals( $value, $response['pod'][ $arg ] ); + } + } +} diff --git a/tests/codeception/restv1/Pods/SwaggerDocumentationCest.php b/tests/codeception/restv1/Pods/SwaggerDocumentationCest.php new file mode 100644 index 0000000000..d21b40d2b7 --- /dev/null +++ b/tests/codeception/restv1/Pods/SwaggerDocumentationCest.php @@ -0,0 +1,100 @@ +test_rest_url = $this->pods_rest_url . 'doc'; + } + + /** + * @test + * it should return a JSON array containing headers in Swagger format + */ + public function it_should_load_site_url( Restv1Tester $I ) { + $I->sendGET( $this->site_url ); + + $I->seeResponseCodeIs( 200 ); + } + + /** + * @test + * it should return a JSON array containing headers in Swagger format + */ + public function it_should_load_wp_rest_url( Restv1Tester $I ) { + $I->sendGET( $this->wp_rest_url ); + + $I->seeResponseCodeIs( 200 ); + } + + /** + * @test + * it should expose a Swagger documentation endpoint + */ + public function it_should_expose_a_swagger_documentation_endpoint( Restv1Tester $I ) { + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseCodeIs( 200 ); + } + + /** + * @test + * it should return a JSON array containing headers in Swagger format + */ + public function it_should_return_a_json_array_containing_headers_in_swagger_format( Restv1Tester $I ) { + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseCodeIs( 200 ); + $I->seeResponseIsJson(); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertArrayHasKey( 'openapi', $response ); + $I->assertArrayHasKey( 'info', $response ); + $I->assertArrayHasKey( 'servers', $response ); + $I->assertArrayHasKey( 'paths', $response ); + $I->assertArrayHasKey( 'components', $response ); + } + + /** + * @test + * it should return the correct information + */ + public function it_should_return_the_correct_information( Restv1Tester $I ) { + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseCodeIs( 200 ); + $I->seeResponseIsJson(); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertArrayHasKey( 'info', $response ); + + $info = $response['info']; + + $I->assertArrayHasKey( 'version', $info ); + $I->assertArrayHasKey( 'title', $info ); + $I->assertArrayHasKey( 'description', $info ); + } + + /** + * @test + * it should return the site URL as host + */ + public function it_should_return_the_site_url_as_host( Restv1Tester $I ) { + $I->sendGET( $this->test_rest_url ); + + $I->seeResponseCodeIs( 200 ); + $I->seeResponseIsJson(); + + $response = json_decode( $I->grabResponse(), true ); + + $I->assertArrayHasKey( 'url', $response['servers'][0] ); + } +} diff --git a/tests/codeception/restv1/_bootstrap.php b/tests/codeception/restv1/_bootstrap.php new file mode 100644 index 0000000000..8a88555806 --- /dev/null +++ b/tests/codeception/restv1/_bootstrap.php @@ -0,0 +1,2 @@ +_test_field_base( $variant_id, $options ); + } + + /** + * @group pods-traversal + * @group pods-traversal-field + * @group pods-traversal-shallow + * @group pods-traversal-field-shallow + * + * @covers Pods::valid + * @covers Pods::exists + * @covers Pods::field + * @covers Pods::id + * @covers PodsData::query + * + * @dataProvider data_provider + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_field_traversal( $variant_id, $options ) { + $this->_test_field_traversal( $variant_id, $options, 'field', false ); + } + + /** + * @group pods-traversal + * @group pods-traversal-field + * @group pods-traversal-deep + * @group pods-traversal-field-deep + * + * @covers Pods::valid + * @covers Pods::exists + * @covers Pods::field + * @covers Pods::id + * @covers PodsData::query + * + * @dataProvider data_provider_deep + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_field_deep_traversal( $variant_id, $options ) { + $this->_test_field_traversal( $variant_id, $options, 'field', true ); + } + + /** + * @group pods-traversal + * @group pods-traversal-display + * @group pods-traversal-shallow + * @group pods-traversal-display-shallow + * + * @covers Pods::valid + * @covers Pods::exists + * @covers Pods::field + * @covers Pods::display + * @covers Pods::id + * @covers PodsData::query + * + * @dataProvider data_provider + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_display_traversal( $variant_id, $options ) { + $this->_test_field_traversal( $variant_id, $options, 'display', false ); + } + + /** + * @group pods-traversal + * @group pods-traversal-display + * @group pods-traversal-deep + * @group pods-traversal-display-deep + * + * @covers Pods::valid + * @covers Pods::exists + * @covers Pods::field + * @covers Pods::display + * @covers Pods::id + * @covers PodsData::query + * + * @dataProvider data_provider_deep + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_display_deep_traversal( $variant_id, $options ) { + $this->_test_field_traversal( $variant_id, $options, 'display', true ); + } + + /** + * Handle all field() and display() tests based on variations + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function _test_field_base( $variant_id, $options ) { + pods_debug( $variant_id ); + + // Suppress MySQL errors + add_filter( 'pods_error_die', '__return_false' ); + + // global $wpdb; + // $wpdb->suppress_errors( true ); + // $wpdb->hide_errors(); + // Options + $pod_type = $options['pod_type']; + $storage_type = $options['storage_type']; + $pod = $options['pod']; + + $debug = array( + 'pod' => $pod['name'], + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + ); + + $this->assertInstanceOf( Pods\Whatsit\Pod::class, $pod ); + + $p = self::get_pod( $pod['name'] ); + + $this->assertArrayHasKey( $pod['name'], self::$data ); + + $data = self::$data[ $pod['name'] ]; + + // pods_debug( 'Data: ' . var_export( $data, true ) ); + + $this->assertArrayHasKey( 'id', $data, sprintf( 'Data has no ID [%s]', $variant_id ) ); + + $data['id'] = (int) $data['id']; + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + + if ( (int) $p->id() !== $data['id'] ) { + $p->fetch( $data['id'] ); + } + + $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); + + $this->assertTrue( $p->exists(), sprintf( 'Pod item not found [%s]', $variant_id ) ); + + $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + $this->assertEquals( (string) $data['id'], (string) $p->field( $data['_field_id'] ), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + $this->assertEquals( (string) $data['id'], (string) $p->display( $data['_field_id'] ), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + + $this->assertEquals( $data['_field_index'], $p->data->field_index, sprintf( 'Item index not as expected (%s) [%s]', $data['_field_index'], $variant_id ) ); + $this->assertEquals( $data[ $data['_field_index'] ], $p->display( $data['_field_index'] ), sprintf( 'Item index not as expected (%s) [%s]', $data['_field_index'], $variant_id ) ); + + remove_filter( 'pods_error_die', '__return_false' ); + } + + /** + * Handle all field() and display() tests based on variations + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + * @param string $method Method to test + * @param boolean $deep Whether to test deep traversal + */ + private function _test_field_traversal( $variant_id, $options, $method, $deep ) { + pods_debug( $variant_id ); + + // Suppress MySQL errors + add_filter( 'pods_error_die', '__return_false' ); + + // global $wpdb; + // $wpdb->suppress_errors( true ); + // $wpdb->hide_errors(); + // Options + $pod_type = $options['pod_type']; + $storage_type = $options['storage_type']; + $pod = $options['pod']; + $field = $options['field']; + $field_name = $field['name']; + $field_type = $field['type']; + $related_pod = array(); + $related_pod_field = array(); + + if ( 'taxonomy' === $pod_type && 'none' === $storage_type && function_exists( 'get_term_meta' ) ) { + $storage_type = 'meta'; + } + + $debug = array( + 'pod' => $pod['name'], + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'field_name' => $field['name'], + 'field_type' => $field_type, + 'method' => $method, + 'deep' => (int) $deep, + ); + + if ( $deep ) { + $related_pod = $options['related_pod']; + $related_pod_type = $related_pod['type']; + $related_pod_storage_type = $related_pod['storage']; + $related_pod_field = $options['related_pod_field']; + + if ( 'taxonomy' === $related_pod_type && 'none' === $related_pod_storage_type && function_exists( 'get_term_meta' ) ) { + $related_pod_storage_type = 'meta'; + } + + $debug['related_pod'] = $related_pod['name']; + $debug['related_pod_type'] = $related_pod_type; + $debug['related_pod_storage_type'] = $related_pod_storage_type; + $debug['related_pod_field_name'] = $related_pod_field['name']; + $debug['related_pod_field_type'] = $related_pod_field['type']; + } + + // pods_debug( $debug ); + + $this->assertInstanceOf( Pods\Whatsit\Pod::class, $pod ); + + $p = self::get_pod( $pod['name'] ); + + $this->assertArrayHasKey( $pod['name'], self::$data ); + + $data = self::$data[ $pod['name'] ]; + + // pods_debug( 'Data: ' . var_export( $data, true ) ); + + $this->assertArrayHasKey( 'id', $data, sprintf( 'Data has no ID [%s]', $variant_id ) ); + + $data['id'] = (int) $data['id']; + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + + if ( (int) $p->id() !== $data['id'] ) { + $p->fetch( $data['id'] ); + } + + $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); + + $this->assertTrue( $p->exists(), sprintf( 'Pod item not found [%s]', $variant_id ) ); + + $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + + if ( 'post_type' === $pod_type || 'media' === $pod_type ) { + $metadata_type = 'post'; + } elseif ( 'taxonomy' === $pod_type ) { + $metadata_type = 'term'; + } else { + $metadata_type = $pod_type; + } + + // @todo other field type coverage for relational + if ( in_array( $field_type, array( 'pick', 'taxonomy' ) ) ) { + if ( ! isset( self::$related_data[ $field['name'] ] ) ) { + $this->assertTrue( false, sprintf( 'No related item found [%s] [%s]', $variant_id, var_export( self::$related_data, true ) ) ); + + return; + } + + $related_data = self::$related_data[ $field['name'] ]; + + // pods_debug( 'Related data for ' . $field['name'] . ': ' . var_export( $related_data, true ) ); + + $check_value = $related_data['id']; + $check_index = $related_data['_index']; + + $check_display_value = $check_value; + $check_display_index = $check_index; + + $field_data = $pod->get_field( $field['name'] ); + + if ( ! $field_data ) { + $this->assertTrue( false, sprintf( 'No related field data found [%s]', $variant_id ) ); + + return; + } + + if ( ! empty( $field_data[ $field_type . '_format_type' ] ) && 'multi' === $field_data[ $field_type . '_format_type' ] ) { + $check_value = (array) $check_value; + $check_index = (array) $check_index; + + $check_display_value = pods_serial_comma( $check_value ); + $check_display_index = pods_serial_comma( $check_index ); + } + + $prefix = $field['name'] . '.'; + $traverse_id = $prefix . $related_data['_field_id']; + $traverse_index = $prefix . $related_data['_field_index']; + + /* + if ( false === $p->field( $traverse_id ) ) { + var_dump( array( + 'pod' => $pod[ 'name' ], + 'storage' => $storage_type, + 'traverse_id' => $traverse_id, + 'check_value' => $check_value, + 'field_value' => $p->field( $traverse_id ), + 'check_display_value' => $check_display_value, + 'display_value' => $p->display( $traverse_id ), + 'check_index' => $check_index, + 'field_index' => $p->field( $traverse_index ), + 'check_display_index' => $check_display_index, + 'display_index' => $p->display( $traverse_index ), + 'field_full' => $p->field( $field[ 'name' ] ), + //'field_data' => $p->fields( $field[ 'name' ] ) + ) ); + }*/ + + if ( ! $deep ) { + if ( 'field' === $method ) { + // Reset value/index array keys. + if ( is_array( $check_value ) ) { + $check_value = array_values( $check_value ); + } + + if ( is_array( $check_index ) ) { + $check_index = array_values( $check_index ); + } + + $this->assertEquals( $check_value, $p->field( $traverse_id ), sprintf( 'Related Item field value not as expected (%s) [%s] {%s should be %s}', $traverse_id, $variant_id, var_export( $p->field( $traverse_id ), true ), var_export( $check_value, true ) ) ); + $this->assertEquals( $check_index, $p->field( $traverse_index ), sprintf( 'Related Item index field value not as expected (%s) [%s] {%s should be %s}', $traverse_index, $variant_id, var_export( $p->field( $traverse_index ), true ), var_export( $check_index, true ) ) ); + + if ( 'meta' === $storage_type && 'taxonomy' !== $field_type ) { + $check_value = array_map( 'absint', (array) $check_value ); + $check_index = (array) $check_index; + + /* + var_dump( array( + 'check_array' => $check_value, + 'metadata_array' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $traverse_id ) ), + + 'check_single' => current( $check_value ), + 'metadata_single' => (int) get_metadata( $metadata_type, $data[ 'id' ], $traverse_id, true ), + + 'check_index_array' => $check_index, + 'metadata_index_array' => get_metadata( $metadata_type, $data[ 'id' ], $traverse_index ), + + 'check_index_single' => current( $check_index ), + 'metadata_index_single' => get_metadata( $metadata_type, $data[ 'id' ], $traverse_index, true ), + + 'metadata_full' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $field[ 'name' ] ) ) + ) );*/ + + $this->assertEquals( $check_value, array_map( 'absint', get_metadata( $metadata_type, $data['id'], $traverse_id ) ), sprintf( 'Related Item field meta value not as expected (%s) [%s]', $traverse_id, $variant_id ) ); + $this->assertEquals( current( $check_value ), (int) get_metadata( $metadata_type, $data['id'], $traverse_id, true ), sprintf( 'Related Item field single meta value not as expected (%s) [%s]', $traverse_id, $variant_id ) ); + + $this->assertEquals( $check_index, get_metadata( $metadata_type, $data['id'], $traverse_index ), sprintf( 'Related Item index field meta value not as expected (%s) [%s]', $traverse_index, $variant_id ) ); + $this->assertEquals( current( $check_index ), get_metadata( $metadata_type, $data['id'], $traverse_index, true ), sprintf( 'Related Item index field single meta value not as expected (%s) [%s]', $traverse_index, $variant_id ) ); + }//end if + } elseif ( 'display' === $method ) { + $this->assertEquals( $check_display_value, $p->display( $traverse_id ), sprintf( 'Related Item field display value not as expected (%s) [%s]', $traverse_id, $variant_id ) ); + $this->assertEquals( $check_display_index, $p->display( $traverse_index ), sprintf( 'Related Item index field display value not as expected (%s) [%s]', $traverse_index, $variant_id ) ); + }//end if + } else { + // Related pod traversal + if ( in_array( $related_pod_field['type'], array( 'pick', 'taxonomy', 'avatar', 'author' ), true ) ) { + if ( $field['name'] === $related_pod_field['name'] && ! isset( $related_data[ $related_pod_field['name'] ] ) ) { + $this->assertTrue( false, sprintf( 'No deep related item found [%s] | %s', $variant_id, print_r( $related_data, true ) ) ); + + return; + } + + $related_object = $related_pod_field['name']; + + if ( ! empty( $related_pod_field['pick_val'] ) ) { + $related_object = $related_pod_field['pick_val']; + } + + if ( isset( self::$related_data[ $related_pod_field['name'] ] ) ) { + $related_pod_data = self::$related_data[ $related_pod_field['name'] ]; + } elseif ( isset( self::$related_data[ $related_object ] ) ) { + $related_pod_data = self::$related_data[ $related_object ]; + } else { + // var_dump( array( 7, '$related_pod_field[ \'name\' ]' => $related_pod_field[ 'name' ], '$related_object' => $related_object ) ); + $this->assertTrue( false, sprintf( 'Invalid related item [%s]', $variant_id ) ); + + return; + } + + $related_prefix = $related_pod_field['name'] . '.'; + $related_traverse_id = $prefix . $related_prefix . $related_pod_data['_field_id']; + $related_traverse_index = $prefix . $related_prefix . $related_pod_data['_field_index']; + + $check_value = $related_pod_data['id']; + $check_index = $related_pod_data['_index']; + + $check_display_value = $check_value; + $check_display_index = $check_index; + + if ( ! empty( $related_pod['fields'][ $related_pod_field['name'] ][ $related_pod_field['type'] . '_format_type' ] ) && 'multi' === $related_pod['fields'][ $related_pod_field['name'] ][ $related_pod_field['type'] . '_format_type' ] ) { + $check_value = (array) $check_value; + $check_index = (array) $check_index; + + $check_display_value = pods_serial_comma( $check_value ); + $check_display_index = pods_serial_comma( $check_index ); + } + + // Reset value/index array keys. + if ( is_array( $check_value ) ) { + $check_value = array_values( $check_value ); + } + + if ( is_array( $check_index ) ) { + $check_index = array_values( $check_index ); + } + + if ( 'field' === $method ) { + $this->assertEquals( $check_value, $p->field( $related_traverse_id, ! is_array( $check_value ) ), sprintf( 'Deep Related Item field value not as expected (%s) [%s] | %s', $related_traverse_id, $variant_id, var_export( array( + '$check_value' => $check_value, + '$check_index' => $check_index, + '$related_traverse_id' => $related_traverse_id, + '$p->field( $related_traverse_id, true )' => $p->field( $related_traverse_id, ! is_array( $check_value ) ), + ), true ) ) ); + $this->assertEquals( $check_index, $p->field( $related_traverse_index, ! is_array( $check_index ) ), sprintf( 'Deep Related Item index field value not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( array( + '$check_value' => $check_value, + '$check_index' => $check_index, + '$related_traverse_index' => $related_traverse_index, + '$p->field( $related_traverse_index, true )' => $p->field( $related_traverse_index, ! is_array( $check_value ) ), + ), true ) ) ); + + if ( 'meta' === $storage_type && 'taxonomy' !== $related_pod_field['type'] ) { + $check_value = array_map( 'absint', (array) $check_value ); + $check_index = (array) $check_index; + + /* + var_dump( array( + 'check_array' => $check_value, + 'metadata_array' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_id ) ), + + 'check_single' => current( $check_value ), + 'metadata_single' => (int) get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_id, true ), + + 'check_index_array' => $check_index, + 'metadata_index_array' => get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_index ), + + 'check_index_single' => current( $check_index ), + 'metadata_index_single' => get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_index, true ), + + 'metadata_full' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $prefix . $related_pod_field[ 'name' ] ) ) + ) );*/ + + $this->assertEquals( $check_value, array_map( 'absint', get_metadata( $metadata_type, $data['id'], $related_traverse_id ) ), sprintf( 'Deep Related Item field meta value not as expected (%s) [%s]', $related_traverse_id, $variant_id ) ); + $this->assertEquals( current( $check_value ), (int) get_metadata( $metadata_type, $data['id'], $related_traverse_id, true ), sprintf( 'Deep Related Item field single meta value not as expected (%s) [%s]', $related_traverse_id, $variant_id ) ); + + $this->assertEquals( $check_index, get_metadata( $metadata_type, $data['id'], $related_traverse_index ), sprintf( 'Deep Related Item index field meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); + $this->assertEquals( current( $check_index ), get_metadata( $metadata_type, $data['id'], $related_traverse_index, true ), sprintf( 'Deep Related Item index field single meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); + }//end if + } elseif ( 'display' === $method ) { + $this->assertEquals( $check_display_value, $p->display( $related_traverse_id ), sprintf( 'Deep Related Item field display value not as expected (%s) [%s]', $related_traverse_id, $variant_id ) ); + $this->assertEquals( $check_display_index, $p->display( $related_traverse_index ), sprintf( 'Deep Related Item index field display value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); + }//end if + } elseif ( 'none' !== $related_pod_storage_type ) { + $check_related_value = ''; + $check_related_index = ''; + + $check_related_display_value = ''; + $check_related_display_index = ''; + + if ( isset( $related_data[ $related_pod_field['name'] ] ) ) { + $check_related_value = $related_data[ $related_pod_field['name'] ]; + $check_related_index = $check_related_value; + + // Setup test data for multiple pages. + if ( 'test_rel_pages' === $field['name'] ) { + $check_related_value = wp_list_pluck( $related_data['_items'], $related_pod_field['name'] ); + + if ( 1 === count( $check_related_value ) ) { + $check_related_value = reset( $check_related_value ); + } + + $check_related_index = $check_related_value; + } + + if ( is_array( $check_value ) && ! is_array( $check_related_value ) ) { + $check_related_value = array_fill( 0, count( $check_value ), $check_related_value ); + + if ( ! is_array( $check_related_index ) ) { + $check_related_index = array_fill( 0, count( $check_value ), $check_related_index ); + } + } + + $check_related_display_value = pods_serial_comma( (array) $check_related_value ); + $check_related_display_index = pods_serial_comma( (array) $check_related_index ); + } + + $related_traverse_index = $prefix . $related_pod_field['name']; + + // Reset value/index array keys. + if ( is_array( $check_related_value ) ) { + $check_related_value = array_values( $check_related_value ); + } + + if ( is_array( $check_related_display_index ) ) { + $check_related_display_index = array_values( $check_related_display_index ); + } + + if ( 'field' === $method ) { + $this->assertEquals( $check_related_value, $p->field( $related_traverse_index, ! is_array( $check_related_value ) ), sprintf( 'Deep Related Item related field index not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( array( + '$check_related_value' => $check_related_value, + '$check_related_index' => $check_related_index, + '$p->field( $related_traverse_index, true )' => $p->field( $related_traverse_index, ! is_array( $check_related_value ) ), + '$related_data' => $related_data, + ), true ) ) ); + + if ( 'meta' === $storage_type && 'taxonomy' !== $related_pod_field['type'] ) { + $check_related_value = (array) $check_related_value; + + $this->assertEquals( $check_related_value, get_metadata( $metadata_type, $data['id'], $related_traverse_index ), sprintf( 'Deep Related Item related field meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); + $this->assertEquals( current( $check_related_value ), get_metadata( $metadata_type, $data['id'], $related_traverse_index, true ), sprintf( 'Deep Related Item related field single meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); + } + } elseif ( 'display' === $method ) { + $this->assertEquals( $check_related_display_index, $p->display( $related_traverse_index, ! is_array( $check_related_value ) ), sprintf( 'Deep Related Item related field display value not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( array( + '$check_related_value' => $check_related_value, + '$check_related_index' => $check_related_index, + '$check_related_display_value' => $check_related_display_value, + '$check_related_display_index' => $check_related_display_index, + '$p->display( $related_traverse_index, true )' => $p->display( $related_traverse_index, ! is_array( $check_related_value ) ), + '$related_data' => $related_data, + ), true ) ) ); + }//end if + }//end if + }//end if + } elseif ( isset( $data[ $field['name'] ] ) ) { + // Other field assertions + $check_value = $data[ $field['name'] ]; + + if ( 'field' === $method ) { + $this->assertEquals( $check_value, $p->field( $field['name'] ), sprintf( 'Item field value not as expected [%s]', $variant_id ) ); + + if ( 'meta' === $storage_type ) { + $check_value = (array) $check_value; + + $this->assertEquals( $check_value, get_metadata( $metadata_type, $data['id'], $field['name'] ), sprintf( 'Item field meta value not as expected [%s]', $variant_id ) ); + $this->assertEquals( current( $check_value ), get_metadata( $metadata_type, $data['id'], $field['name'], true ), sprintf( 'Item field single meta value not as expected [%s]', $variant_id ) ); + } + } elseif ( 'display' === $method ) { + $this->assertEquals( $check_value, $p->display( $field['name'] ), sprintf( 'Item field display value not as expected [%s]', $variant_id ) ); + } + }//end if + + remove_filter( 'pods_error_die', '__return_false' ); + } + +} diff --git a/tests/codeception/wpunit-traversal/Pods/Fields/TraversalTest.php b/tests/codeception/wpunit-traversal/Pods/Fields/TraversalTest.php new file mode 100644 index 0000000000..eceea00e36 --- /dev/null +++ b/tests/codeception/wpunit-traversal/Pods/Fields/TraversalTest.php @@ -0,0 +1,292 @@ +_test_fields_base( $variant_id, $options ); + } + + /** + * @group pods-traversal + * @group pods-traversal-field + * @group pods-traversal-shallow + * @group pods-traversal-field-shallow + * + * @covers Pods::fields + * + * @dataProvider data_provider + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_fields_traversal( $variant_id, $options ) { + $this->_test_fields_traversal( $variant_id, $options, false ); + } + + /** + * @group pods-traversal + * @group pods-traversal-field + * @group pods-traversal-deep + * @group pods-traversal-field-deep + * + * @covers Pods::fields + * + * @dataProvider data_provider_deep + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_fields_deep_traversal( $variant_id, $options ) { + $this->_test_fields_traversal( $variant_id, $options, true ); + } + + /** + * Handle all field() and display() tests based on variations + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function _test_fields_base( $variant_id, $options ) { + pods_debug( $variant_id ); + + // Suppress MySQL errors + add_filter( 'pods_error_die', '__return_false' ); + + // global $wpdb; + // $wpdb->suppress_errors( true ); + // $wpdb->hide_errors(); + // Options + $pod_type = $options['pod_type']; + $storage_type = $options['storage_type']; + $pod = $options['pod']; + + $debug = array( + 'pod' => $pod['name'], + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + ); + + $this->assertInstanceOf( Pods\Whatsit\Pod::class, $pod ); + + $p = self::get_pod( $pod['name'] ); + + $this->assertArrayHasKey( $pod['name'], self::$data ); + + $data = self::$data[ $pod['name'] ]; + + // pods_debug( 'Data: ' . var_export( $data, true ) ); + + $this->assertArrayHasKey( 'id', $data, sprintf( 'Data has no ID [%s]', $variant_id ) ); + + $data['id'] = (int) $data['id']; + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + + if ( (int) $p->id() !== $data['id'] ) { + $p->fetch( $data['id'] ); + } + + $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); + + $this->assertTrue( $p->exists(), sprintf( 'Pod item not found [%s]', $variant_id ) ); + + $this->assertEquals( (string) $data['_field_index'], (string) $p->fields( $data['_field_index'], 'name' ), sprintf( 'Item index field not as expected (%s) [%s]', $data['_field_index'], $variant_id ) ); + + remove_filter( 'pods_error_die', '__return_false' ); + } + + /** + * Handle all field() and display() tests based on variations + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + * @param boolean $deep Whether to test deep traversal + */ + private function _test_fields_traversal( $variant_id, $options, $deep ) { + pods_debug( $variant_id ); + + // Suppress MySQL errors + add_filter( 'pods_error_die', '__return_false' ); + + // global $wpdb; + // $wpdb->suppress_errors( true ); + // $wpdb->hide_errors(); + // Options + $pod_type = $options['pod_type']; + $storage_type = $options['storage_type']; + $pod = $options['pod']; + $field = $options['field']; + $field_name = $field['name']; + $field_type = $field['type']; + $related_pod = array(); + $related_pod_field = array(); + + if ( 'taxonomy' === $pod_type && 'none' === $storage_type && function_exists( 'get_term_meta' ) ) { + $storage_type = 'meta'; + } + + $debug = array( + 'pod' => $pod['name'], + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'field_name' => $field['name'], + 'field_type' => $field_type, + 'deep' => (int) $deep, + ); + + if ( $deep ) { + $related_pod = $options['related_pod']; + $related_pod_type = $related_pod['type']; + $related_pod_storage_type = $related_pod['storage']; + $related_pod_field = $options['related_pod_field']; + + if ( 'taxonomy' === $related_pod_type && 'none' === $related_pod_storage_type && function_exists( 'get_term_meta' ) ) { + $related_pod_storage_type = 'meta'; + } + + $debug['related_pod'] = $related_pod['name']; + $debug['related_pod_type'] = $related_pod_type; + $debug['related_pod_storage_type'] = $related_pod_storage_type; + $debug['related_pod_field_name'] = $related_pod_field['name']; + $debug['related_pod_field_type'] = $related_pod_field['type']; + } + + // pods_debug( $debug ); + + $this->assertInstanceOf( Pods\Whatsit\Pod::class, $pod ); + + $p = self::get_pod( $pod['name'] ); + + $this->assertArrayHasKey( $pod['name'], self::$data ); + + $data = self::$data[ $pod['name'] ]; + + // pods_debug( 'Data: ' . var_export( $data, true ) ); + + $this->assertArrayHasKey( 'id', $data, sprintf( 'Data has no ID [%s]', $variant_id ) ); + + $data['id'] = (int) $data['id']; + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + + if ( (int) $p->id() !== $data['id'] ) { + $p->fetch( $data['id'] ); + } + + $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); + + $this->assertTrue( $p->exists(), sprintf( 'Pod item not found [%s]', $variant_id ) ); + + $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + + // @todo other field type coverage for relational + if ( in_array( $field_type, array( 'pick', 'taxonomy' ) ) ) { + if ( ! isset( self::$related_data[ $field['name'] ] ) ) { + $this->assertTrue( false, sprintf( 'No related item found [%s] [%s]', $variant_id, var_export( self::$related_data, true ) ) ); + + return; + } + + $related_data = self::$related_data[ $field['name'] ]; + + $field_data = $pod->get_field( $field['name'] ); + + if ( ! $field_data ) { + $this->assertTrue( false, sprintf( 'No related field data found [%s]', $variant_id ) ); + + return; + } + + $prefix = $field['name'] . '.'; + $traverse_index = $prefix . $related_data['_field_index']; + + if ( ! $deep ) { + $the_field = $p->fields( $field['name'] ); + + $this->assertEquals( $related_data['_field_index'], $p->fields( $traverse_index, 'name' ), sprintf( 'Related Item index field not as expected (%s) [%s] | %s', $traverse_index, $variant_id, var_export( array( + '$related_data[\'_field_index\']' => $related_data['_field_index'], + '$traverse_index' => $traverse_index, + '$p->fields( $traverse_index, \'name\' )' => $p->fields( $traverse_index, 'name' ), + ), true ) ) ); + } else { + // Related pod traversal + if ( in_array( $related_pod_field['type'], array( 'pick', 'taxonomy', 'avatar', 'author' ), true ) ) { + if ( $field['name'] === $related_pod_field['name'] && ! isset( $related_data[ $related_pod_field['name'] ] ) ) { + $this->assertTrue( false, sprintf( 'No deep related item found [%s] | %s', $variant_id, print_r( $related_data, true ) ) ); + + return; + } + + $related_object = $related_pod_field['name']; + + if ( ! empty( $related_pod_field['pick_val'] ) ) { + $related_object = $related_pod_field['pick_val']; + } + + if ( isset( self::$related_data[ $related_pod_field['name'] ] ) ) { + $related_pod_data = self::$related_data[ $related_pod_field['name'] ]; + } elseif ( isset( self::$related_data[ $related_object ] ) ) { + $related_pod_data = self::$related_data[ $related_object ]; + } else { + // var_dump( array( 7, '$related_pod_field[ \'name\' ]' => $related_pod_field[ 'name' ], '$related_object' => $related_object ) ); + $this->assertTrue( false, sprintf( 'Invalid related item [%s]', $variant_id ) ); + + return; + } + + $related_prefix = $related_pod_field['name'] . '.'; + $related_traverse_index = $prefix . $related_prefix . $related_pod_data['_field_index']; + + $this->assertEquals( $related_pod_data['_field_index'], $p->fields( $related_traverse_index, 'name' ), sprintf( 'Deep Related Item index field not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( array( + '$related_pod_data[\'_field_index\']' => $related_pod_data['_field_index'], + '$related_traverse_index' => $related_traverse_index, + '$p->fields( $related_traverse_index, \'name\' )' => $p->fields( $related_traverse_index, 'name' ), + ), true ) ) ); + } elseif ( 'none' !== $related_pod_storage_type ) { + $related_traverse_index = $prefix . $related_pod_field['name']; + + $this->assertEquals( $related_pod_field['name'], $p->fields( $related_traverse_index, 'name' ), sprintf( 'Deep Related Item related field index not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( array( + '$related_pod_field[\'name\']' => $related_pod_field['name'], + '$related_traverse_index' => $related_traverse_index, + '$p->fields( $related_traverse_index, \'name\' )' => $p->fields( $related_traverse_index, 'name' ), + ), true ) ) ); + }//end if + }//end if + } elseif ( isset( $data[ $field['name'] ] ) ) { + // Other field assertions + $this->assertEquals( $field['name'], $p->fields( $field['name'], 'name' ), sprintf( 'Item field name not as expected [%s]', $variant_id ) ); + }//end if + + remove_filter( 'pods_error_die', '__return_false' ); + } + +} diff --git a/tests/codeception/wpunit-traversal/Pods/Find/TraversalTest.php b/tests/codeception/wpunit-traversal/Pods/Find/TraversalTest.php new file mode 100644 index 0000000000..f0d53b55e2 --- /dev/null +++ b/tests/codeception/wpunit-traversal/Pods/Find/TraversalTest.php @@ -0,0 +1,681 @@ +_test_find_base( $variant_id, $options ); + } + + /** + * @group pods-traversal + * @group pods-traversal-find + * @group pods-traversal-shallow + * @group pods-traversal-find-shallow + * @group pods-traversal-query-fields + * + * @covers Pods::valid + * @covers Pods::find + * @covers Pods::total + * @covers Pods::total_found + * @covers Pods::fetch + * @covers Pods::id + * @covers PodsData::select + * @covers PodsData::build + * @covers PodsData::query + * + * @dataProvider data_provider_base + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_find_base_query_fields( $variant_id, $options ) { + $this->_test_find_base( $variant_id, $options, true ); + } + + /** + * @group pods-traversal + * @group pods-traversal-find + * @group pods-traversal-shallow + * @group pods-traversal-find-shallow + * + * @covers Pods::valid + * @covers Pods::find + * @covers Pods::total + * @covers Pods::total_found + * @covers Pods::fetch + * @covers Pods::id + * @covers PodsData::select + * @covers PodsData::build + * @covers PodsData::traverse + * @covers PodsData::traverse_build + * @covers PodsData::traverse_recurse + * @covers PodsData::query + * + * @dataProvider data_provider + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_find_traversal( $variant_id, $options ) { + $this->_test_find_traversal( $variant_id, $options ); + } + + /** + * @group pods-traversal + * @group pods-traversal-find + * @group pods-traversal-shallow + * @group pods-traversal-find-shallow + * @group pods-traversal-query-fields + * + * @covers Pods::valid + * @covers Pods::find + * @covers Pods::total + * @covers Pods::total_found + * @covers Pods::fetch + * @covers Pods::id + * @covers PodsData::select + * @covers PodsData::build + * @covers PodsData::traverse + * @covers PodsData::traverse_build + * @covers PodsData::traverse_recurse + * @covers PodsData::query + * @covers PodsData::query_fields + * @covers PodsData::query_field + * + * @dataProvider data_provider + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_find_traversal_query_fields( $variant_id, $options ) { + $this->_test_find_traversal( $variant_id, $options, false, true ); + } + + /** + * @group pods-traversal + * @group pods-traversal-find + * @group pods-traversal-deep + * @group pods-traversal-find-deep + * + * @covers Pods::valid + * @covers Pods::find + * @covers Pods::total + * @covers Pods::total_found + * @covers Pods::fetch + * @covers Pods::id + * @covers PodsData::select + * @covers PodsData::build + * @covers PodsData::traverse + * @covers PodsData::traverse_build + * @covers PodsData::traverse_recurse + * @covers PodsData::query + * + * @dataProvider data_provider_deep + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function test_find_deep_traversal( $variant_id, $options ) { + $this->_test_find_traversal( $variant_id, $options, true ); + } + + /** + * @group pods-traversal + * @group pods-traversal-find + * @group pods-traversal-deep + * @group pods-traversal-find-deep + * @group pods-traversal-query-fields + * + * @covers Pods::valid + * @covers Pods::find + * @covers Pods::total + * @covers Pods::total_found + * @covers Pods::fetch + * @covers Pods::id + * @covers PodsData::select + * @covers PodsData::build + * @covers PodsData::traverse + * @covers PodsData::traverse_build + * @covers PodsData::traverse_recurse + * @covers PodsData::query + * @covers PodsData::query_fields + * @covers PodsData::query_field + * + * @dataProvider data_provider_deep + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + */ + public function _test_find_deep_traversal_query_fields( $variant_id, $options ) { + $this->markTestSkipped( 'query_fields does not yet support traversal auto handling of prefix/suffix' ); + + $this->_test_find_traversal( $variant_id, $options, true, true ); + } + + /** + * + * Handle all find() base tests based on variations + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + * @param boolean $query_fields Whether to test query_fields WHERE syntax + */ + private function _test_find_base( $variant_id, $options, $query_fields = false ) { + pods_debug( $variant_id ); + + // Suppress MySQL errors + add_filter( 'pods_error_die', '__return_false' ); + + // global $wpdb; + // $wpdb->suppress_errors( true ); + // $wpdb->hide_errors(); + // Options + $pod_type = $options['pod_type']; + $storage_type = $options['storage_type']; + $pod = $options['pod']; + + $debug = array( + 'pod' => $pod['name'], + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'query_fields' => (int) $query_fields, + ); + + $this->assertInstanceOf( Pods\Whatsit\Pod::class, $pod ); + + // Base find() $params + $params = array( + 'limit' => 1, + ); + + $p = self::get_pod( $pod['name'] ); + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); + + $where = array(); + + $this->assertArrayHasKey( $pod['name'], self::$data ); + + $data = self::$data[ $pod['name'] ]; + + $this->assertArrayHasKey( 'id', $data, sprintf( 'Data has no ID [%s]', $variant_id ) ); + + $data['id'] = (int) $data['id']; + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + + $prefix = '`t`.'; + + $check_value = $data['id']; + $check_index = $data[ $data['_field_index'] ]; + + if ( $query_fields ) { + $where[] = array( + 'field' => $data['_field_id'], + 'value' => (int) $check_value, + ); + + $where[] = array( + 'field' => $data['_field_index'], + 'value' => $check_index, + ); + } else { + $where[] = $prefix . "`{$data['_field_id']}` = " . (int) $check_value; + $where[] = $prefix . "`{$data['_field_index']}` = '" . pods_sanitize( $check_index ) . "'"; + + $where = implode( ' AND ', $where ); + } + + $params['where'] = $where; + + $p->find( $params ); + + $this->assertEquals( 1, $p->total(), sprintf( 'Total not correct [%s] | %s | %s', $variant_id, $p->sql, print_r( array( + 'where' => $where, + 'params' => $p->params, + ), true ) ) ); + $this->assertEquals( 1, $p->total_found(), sprintf( 'Total found not correct [%s] | %s | %s', $variant_id, $p->sql, print_r( array( + 'where' => $where, + 'params' => $p->params, + ), true ) ) ); + + $this->assertNotEmpty( $p->fetch(), sprintf( 'Item not fetched [%s]', $variant_id ) ); + + $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + + remove_filter( 'pods_error_die', '__return_false' ); + } + + /** + * Handle all find() tests based on variations + * + * @param string $variant_id Testing variant identification + * @param array $options Data config to test + * @param boolean $deep Whether to test deep traversal + * @param boolean $query_fields Whether to test query_fields WHERE syntax + */ + private function _test_find_traversal( $variant_id, $options, $deep = false, $query_fields = false ) { + pods_debug( $variant_id ); + + // Suppress MySQL errors + add_filter( 'pods_error_die', '__return_false' ); + + global $wpdb; + // $wpdb->suppress_errors( true ); + // $wpdb->hide_errors(); + // Options + $pod_type = $options['pod_type']; + $storage_type = $options['storage_type']; + $pod = $options['pod']; + $field = $options['field']; + $field_name = $field['name']; + $field_type = $field['type']; + $related_pod = array(); + $related_pod_field = array(); + + if ( 'taxonomy' === $pod_type && 'none' === $storage_type && function_exists( 'get_term_meta' ) ) { + $storage_type = 'meta'; + } + + $debug = array( + 'pod' => $pod['name'], + 'pod_type' => $pod_type, + 'storage_type' => $storage_type, + 'field_name' => $field['name'], + 'field_type' => $field_type, + 'deep' => (int) $deep, + 'query_fields' => (int) $query_fields, + ); + + if ( $deep ) { + $related_pod = $options['related_pod']; + $related_pod_type = $related_pod['type']; + $related_pod_storage_type = $related_pod['storage']; + $related_pod_field = $options['related_pod_field']; + + if ( 'taxonomy' === $related_pod_type && 'none' === $related_pod_storage_type && function_exists( 'get_term_meta' ) ) { + $related_pod_storage_type = 'meta'; + } + + $debug['related_pod'] = $related_pod['name']; + $debug['related_pod_type'] = $related_pod_type; + $debug['related_pod_storage_type'] = $related_pod_storage_type; + $debug['related_pod_field_name'] = $related_pod_field['name']; + $debug['related_pod_field_type'] = $related_pod_field['type']; + } + + $this->assertInstanceOf( Pods\Whatsit\Pod::class, $pod ); + + // Base find() $params + $params = array( + 'limit' => 1, + ); + + $p = self::get_pod( $pod['name'] ); + + $this->assertArrayHasKey( $pod['name'], self::$data ); + + $data = self::$data[ $pod['name'] ]; + + $this->assertArrayHasKey( 'id', $data, sprintf( 'Data has no ID [%s]', $variant_id ) ); + + $data['id'] = (int) $data['id']; + + $this->assertInstanceOf( Pods::class, $p, sprintf( 'Pod not object of Pod [%s]', $variant_id ) ); + + $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); + + $where = array(); + + $podsrel_pod_id = $pod['id']; + $podsrel_field_id = $field['id']; + $podsrel_item_id = $data['id']; + + $prefix = ''; + $suffix = ''; + + if ( in_array( $field_type, array( 'pick', 'taxonomy', 'avatar', 'author' ), true ) ) { + if ( ! isset( self::$related_data[ $field_name ] ) ) { + $this->assertTrue( false, sprintf( 'No related item found [%s]', $variant_id ) ); + + return; + } + + $related_data = self::$related_data[ $field_name ]; + + $podsrel_item_id = $related_data['id']; + + $prefix = '`' . $field_name . '`.'; + + if ( ! $deep ) { + $check_value = $related_data['id']; + $check_index = $related_data[ $related_data['_field_index'] ]; + + $check_multi_value = (array) $check_value; + $check_multi_index = (array) $check_index; + + if ( ! empty( $field[ $field_type . '_format_type' ] ) && 'multi' === $field[ $field_type . '_format_type' ] ) { + // Only go and get it if you need it + if ( isset( self::$related_data[ $field['name'] ] ) ) { + $check_multi_value = (array) self::$related_data[ $field['name'] ]['id']; + $check_multi_index = (array) self::$related_data[ $field['name'] ]['_index']; + } + + $check_value = current( $check_multi_value ); + $check_index = current( $check_multi_index ); + } + + $related_where = array(); + + if ( empty( $check_value ) ) { + if ( $query_fields ) { + $related_where[] = array( + 'field' => $field_name . '.' . $related_data['_field_id'], + 'compare' => 'NOT EXISTS', + ); + } else { + $related_where[] = $prefix . '`' . $related_data['_field_id'] . '` IS NULL'; + } + } + + if ( $query_fields ) { + $related_where_set = array(); + + // Test IN / ALL (ALL uses IN logic in part of it) + if ( 1 < count( $check_multi_value ) ) { + $related_where_set[] = array( + 'field' => $field_name . '.' . $related_data['_field_id'], + 'value' => $check_multi_value, + 'compare' => 'ALL', + ); + + $related_where_set[] = array( + 'field' => $field_name . '.' . $related_data['_field_index'], + 'value' => $check_multi_index, + 'compare' => 'ALL', + ); + } else { + $related_where_set[] = array( + 'field' => $field_name . '.' . $related_data['_field_id'], + 'value' => (int) $check_value, + ); + + $related_where_set[] = array( + 'field' => $field_name . '.' . $related_data['_field_index'], + 'value' => $check_index, + ); + }//end if + + $related_where_set['relation'] = 'AND'; + + $related_where[] = $related_where_set; + + $related_where['relation'] = 'OR'; + } else { + $related_where[] = " + {$prefix}`{$related_data['_field_id']}` = " . (int) $check_value . " + AND {$prefix}`{$related_data['_field_index']}` = '" . pods_sanitize( $check_index ) . "' + "; + + $related_where = '( ' . implode( ' OR ', $related_where ) . ' )'; + }//end if + + $where[] = $related_where; + // pods_debug( array( 1, $related_where, $check_value, $check_index ) ); + } else { + // Related pod traversal + $related_pod_type = $related_pod['type']; + $related_pod_storage_type = $related_pod['storage']; + + if ( 'taxonomy' === $related_pod_type && 'none' === $related_pod_storage_type && function_exists( 'get_term_meta' ) ) { + $related_pod_storage_type = 'meta'; + } + + $related_prefix = ''; + $related_suffix = ''; + + $related_where = array(); + + if ( in_array( $related_pod_field['type'], array( 'pick', 'taxonomy', 'avatar', 'author' ), true ) ) { + if ( $field_name === $related_pod_field['name'] && ! isset( $related_data[ $related_pod_field['name'] ] ) ) { + $this->assertTrue( false, sprintf( 'No deep related item found [%s] | %s', $variant_id, print_r( $related_data, true ) ) ); + + return; + } + + $related_object = $related_pod_field['name']; + + if ( ! empty( $related_pod_field['pick_val'] ) ) { + $related_object = $related_pod_field['pick_val']; + } + + $related_prefix = '`' . $related_pod_field['name'] . '`.'; + + if ( isset( self::$related_data[ $related_pod_field['name'] ] ) ) { + $related_pod_data = self::$related_data[ $related_pod_field['name'] ]; + } elseif ( isset( self::$related_data[ $related_object ] ) ) { + $related_pod_data = self::$related_data[ $related_object ]; + } else { + // pods_debug( array( 2, '$related_pod_field[ \'name\' ]' => $related_pod_field[ 'name' ], '$related_object' => $related_object ) ); + $this->assertTrue( false, sprintf( 'Invalid deep related item [%s]', $variant_id ) ); + + return; + } + + $podsrel_pod_id = $related_pod['id']; + $podsrel_field_id = $related_pod_field['id']; + $podsrel_item_id = $related_pod_data['id']; + + $check_value = $related_pod_data['id']; + + $check_index = ''; + + if ( isset( $related_pod_data[ $related_pod_data['_field_index'] ] ) ) { + $check_index = $related_pod_data[ $related_pod_data['_field_index'] ]; + } + + $check_multi_value = (array) $check_value; + $check_multi_index = (array) $check_index; + + if ( ! empty( $related_pod_field[ $related_pod_field['type'] . '_format_type' ] ) && 'multi' === $related_pod_field[ $related_pod_field['type'] . '_format_type' ] ) { + // Only go and get it if you need it + if ( isset( self::$related_data[ $related_pod_field['name'] ] ) ) { + $check_multi_value = (array) self::$related_data[ $related_pod_field['name'] ]['id']; + $check_multi_index = (array) self::$related_data[ $related_pod_field['name'] ]['_index']; + } + + $check_value = current( $check_multi_value ); + $check_index = current( $check_multi_index ); + } + + // Temporarily check against null too, recursive data not saved fully yet + if ( empty( $check_value ) ) { + if ( $query_fields ) { + $related_where[] = array( + 'field' => $field_name . '.' . $related_pod_field['name'] . '.' . $related_pod_data['_field_id'], + 'compare' => 'NOT EXISTS', + ); + } else { + $related_where[] = $prefix . $related_prefix . '`' . $related_pod_data['_field_id'] . '` IS NULL'; + } + // pods_debug( array( 3, $related_where, 'empty $check_value' ) ); + } + + if ( $query_fields ) { + $related_where[] = array( + 'relation' => 'AND', + array( + 'field' => $field_name . '.' . $related_pod_field['name'] . '.' . $related_pod_data['_field_id'], + 'value' => (int) $check_value, + ), + array( + 'field' => $field_name . '.' . $related_pod_field['name'] . '.' . $related_pod_data['_field_index'], + 'value' => $check_index, + ), + ); + + $related_where['relation'] = 'OR'; + } else { + $related_where[] = " + {$prefix}{$related_prefix}`{$related_pod_data['_field_id']}` = " . (int) $check_value . " + AND {$prefix}{$related_prefix}`{$related_pod_data['_field_index']}` = '" . pods_sanitize( $check_index ) . "' + "; + + $related_where = '( ' . implode( ' OR ', $related_where ) . ' )'; + } + // pods_debug( array( 4, $related_where, $check_value, $check_index ) ); + } elseif ( 'none' !== $related_pod_storage_type ) { + if ( 'pod' === $related_pod_type ) { + // $related_prefix = '`t`.'; + } elseif ( 'table' === $related_pod_storage_type ) { + $related_prefix = '`d`.'; + } elseif ( 'meta' === $related_pod_storage_type ) { + $related_suffix = '.`meta_value`'; + } + + $check_related_value = ''; + + if ( isset( $related_data[ $related_pod_field['name'] ] ) ) { + $check_related_value = $related_data[ $related_pod_field['name'] ]; + } + + // Temporarily check against null too, recursive data not saved fully yet + if ( '.`meta_value`' === $related_suffix && '' === $check_related_value ) { + if ( $query_fields ) { + $related_where[] = array( + 'field' => $field_name . '.' . $related_pod_field['name'], + 'compare' => 'NOT EXISTS', + ); + } else { + $related_where[] = $prefix . $related_prefix . '`' . $related_pod_field['name'] . '`' . $related_suffix . ' IS NULL'; + } + } + + if ( $query_fields ) { + $related_where[] = array( + 'field' => $field_name . '.' . $related_pod_field['name'], + 'value' => $check_related_value, + ); + + $related_where['relation'] = 'OR'; + } else { + $related_where[] = " + {$prefix}{$related_prefix}`{$related_pod_field['name']}`{$related_suffix} = '" . pods_sanitize( $check_related_value ) . "' + "; + + $related_where = '( ' . implode( ' OR ', $related_where ) . ' )'; + } + // pods_debug( array( 5, $related_where, $related_suffix, $check_related_value, self::$related_data[ $field_name ] ) ); + }//end if + + if ( ! empty( $related_where ) ) { + $where[] = $related_where; + } + // pods_debug( array( 6, $where ) ); + }//end if + } elseif ( 'none' !== $storage_type && $field_name !== $data['_field_index'] ) { + if ( 'pod' === $pod_type ) { + $prefix = '`t`.'; + } elseif ( 'table' === $storage_type ) { + $prefix = '`d`.'; + } elseif ( 'meta' === $storage_type ) { + $suffix = '.`meta_value`'; + } + + $check_value = $data[ $field_name ]; + + if ( $query_fields ) { + $where[] = array( + 'field' => $field_name, + 'value' => $check_value, + ); + } else { + $where[] = " + {$prefix}`{$field_name}`{$suffix} = '" . pods_sanitize( $check_value ) . "' + "; + } + }//end if + + $prefix = '`t`.'; + + $check_value = $data['id']; + + if ( $query_fields ) { + $where[] = array( + 'field' => $data['_field_id'], + 'value' => (int) $check_value, + ); + } else { + $where[] = $prefix . '`' . $data['_field_id'] . '`' . ' = ' . (int) $check_value; + + $where = implode( ' AND ', $where ); + } + + $params['where'] = $where; + + $p->find( $params ); + + $debug_related = count( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}podsrel` WHERE `item_id` = %d AND `pod_id` = %d AND `field_id` = %d", $check_value, $pod['id'], $field['id'] ) ) ) . ' related items'; + + if ( $deep ) { + $prepare_data = (array) $podsrel_item_id; + $prepare_data[] = $podsrel_pod_id; + $prepare_data[] = $podsrel_field_id; + + $debug_related .= ' | ' . count( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}podsrel` WHERE `item_id` IN ( " . implode( ',', array_fill( 0, count( (array) $podsrel_item_id ), '%d' ) ) . ' ) AND `pod_id` = %d AND `field_id` = %d', $prepare_data ) ) ) . ' deep related items'; + } + + $debug = sprintf( '%s | %s | %s', $p->sql, print_r( array( + 'where' => $where, + 'params' => $p->params, + ), true ), $debug_related ); + + $this->assertEquals( 1, $p->total(), sprintf( 'Total not correct [%s] | %s', $variant_id, $debug ) ); + $this->assertEquals( 1, $p->total_found(), sprintf( 'Total found not correct [%s] | %s', $variant_id, $debug ) ); + + $this->assertNotEmpty( $p->fetch(), sprintf( 'Item not fetched [%s]', $variant_id ) ); + + $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['_field_id'], $variant_id ) ); + + remove_filter( 'pods_error_die', '__return_false' ); + } + +} diff --git a/tests/codeception/wpunit-traversal/_bootstrap.php b/tests/codeception/wpunit-traversal/_bootstrap.php new file mode 100644 index 0000000000..df0efb123e --- /dev/null +++ b/tests/codeception/wpunit-traversal/_bootstrap.php @@ -0,0 +1,24 @@ +api = pods_api(); + + $this->populate(); + } + + /** + * + */ + public function tearDown(): void { + $this->api = null; + + parent::tearDown(); + } + + public function populate() { + $this->pod = 'test_groups_pod'; + $this->pod_id = $this->api->save_pod( [ + 'name' => $this->pod, + 'type' => 'post_type', + 'label' => 'Test pod for groups', + 'some_custom_key' => 'Some custom value', + 'another_key' => - 1, + ] ); + + $this->group = 'test_group'; + $this->group_id = $this->api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => $this->group, + 'label' => 'Test group', + 'some_custom_key' => 'One custom value', + 'another_key' => 0, + ] ); + } + + public function populate_field() { + $this->field = 'test_field'; + $this->field_id = $this->api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => $this->field, + 'label' => 'Test field', + 'some_custom_key' => 'Field custom value', + 'another_key' => 1, + ] ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_empty_params() { + $params = []; + + $this->expectExceptionMessage( 'Pod ID or name is required' ); + $this->expectException( \Exception::class ); + + $this->api->save_field( $params ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_no_field_name() { + $params = [ + 'pod_id' => $this->pod_id, + ]; + + $this->expectExceptionMessage( 'Pod field name or label is required' ); + $this->expectException( \Exception::class ); + + $this->api->save_field( $params ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_group_id() { + $params = [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_field', + 'label' => 'Test field', + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( $response ); + + $this->assertEquals( $params['name'], $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + $this->assertEquals( $params['label'], $field['label'] ); + $this->assertEquals( $this->group_id, $field->get_group_id() ); + $this->assertEquals( $this->group, $field->get_group_name() ); + } + + /** + * @covers PodsAPI::add_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_add_field_with_group_id_using_existing_field_name() { + $params = [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_field', + 'label' => 'Test field', + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $params = [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_field', + 'label' => 'Test field 2', + ]; + + $this->expectExceptionMessage( 'Field test_field already exists' ); + + $this->api->add_field( $params ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_group_name() { + $params = [ + 'pod' => $this->pod, + 'group' => $this->group, + 'name' => 'test_field', + 'label' => 'Test field', + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( $response ); + + $this->assertEquals( $params['name'], $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + $this->assertEquals( $params['label'], $field['label'] ); + $this->assertEquals( $this->group_id, $field->get_group_id() ); + $this->assertEquals( $this->group, $field->get_group_name() ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_group_object() { + $pod = $this->api->load_pod( [ 'id' => $this->pod_id ] ); + $group = $this->api->load_group( [ 'id' => $this->group_id ] ); + + $params = [ + 'pod' => $pod, + 'group' => $group, + 'name' => 'test_field', + 'label' => 'Test field', + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( $response ); + + $this->assertEquals( $params['name'], $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + $this->assertEquals( $params['label'], $field['label'] ); + $this->assertEquals( $this->group_id, $field->get_group_id() ); + $this->assertEquals( $this->group, $field->get_group_name() ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_new_group_id() { + $this->populate_field(); + + $group2 = 'test_another_group'; + $group_id2 = $this->api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => $group2, + 'label' => 'Test another group', + 'some_custom_key' => 'Another custom value', + 'another_key' => 2, + ] ); + + $params = [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'id' => $this->field_id, + 'new_group_id' => $group_id2, + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( $response ); + + $this->assertEquals( $this->field, $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + $this->assertEquals( 'Test field', $field['label'] ); + $this->assertEquals( $group_id2, $field->get_group_id() ); + $this->assertEquals( $group2, $field->get_group_name() ); + } + + /** + * @covers PodsAPI::save_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_field_with_weight() { + $this->populate_field(); + + $params = [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_field2', + 'label' => 'Test field2', + 'weight' => 10, + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( $response ); + + $this->assertEquals( $params['name'], $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + $this->assertEquals( $params['label'], $field['label'] ); + $this->assertEquals( $params['weight'], $field['weight'] ); + + $params = [ + 'pod_id' => $this->pod_id, + 'id' => $this->field_id, + 'weight' => 15, + ]; + + $response = $this->api->save_field( $params ); + + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( $response ); + + $this->assertEquals( $this->field, $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + $this->assertEquals( 'Test field', $field['label'] ); + $this->assertEquals( $params['weight'], $field['weight'] ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_group_id() { + $this->populate_field(); + + $field = $this->api->load_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => $this->field, + ] ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_group_name() { + $this->populate_field(); + + $field = $this->api->load_field( [ + 'pod' => $this->pod, + 'group' => $this->group, + 'name' => $this->field, + ] ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_group_object() { + $pod = $this->api->load_pod( [ 'id' => $this->pod_id ] ); + $group = $this->api->load_group( [ 'id' => $this->group_id ] ); + + $this->populate_field(); + + $field = $this->api->load_field( [ + 'pod' => $pod, + 'group' => $group, + 'name' => $this->field, + ] ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_id() { + $this->populate_field(); + + $field = $this->api->load_field( [ + 'id' => $this->field_id, + ] ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_id_direct() { + $this->populate_field(); + + $field = $this->api->load_field( $this->field_id ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_post_direct() { + $this->populate_field(); + + $field = $this->api->load_field( get_post( $this->field_id ) ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_field_with_object_direct() { + $this->populate_field(); + + $field = $this->api->load_field( [ 'id' => $this->field_id ] ); + $field = $this->api->load_field( $field ); + + $this->assertInstanceOf( Field::class, $field ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_has_fields() { + $this->populate_field(); + + $fields = $this->api->load_fields(); + + $fields = wp_list_pluck( $fields, 'object_type' ); + $fields = array_values( array_unique( $fields ) ); + + $this->assertCount( 1, $fields ); + $this->assertContains( 'field', $fields ); + + $params = [ + 'object_type' => 'pod', + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'object_type' ); + $fields = array_values( array_unique( $fields ) ); + + $this->assertCount( 1, $fields ); + $this->assertContains( 'field', $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_by_type() { + $this->populate_field(); + + $field_id2 = $this->api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_another_field', + 'type' => 'number', + 'label' => 'Another test field', + ] ); + + $params = [ + 'type' => 'number', + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'type', 'id' ); + + $this->assertArrayHasKey( $field_id2, $fields ); + + $fields = array_values( array_unique( $fields ) ); + + $this->assertCount( 1, $fields ); + $this->assertContains( 'number', $fields ); + + $params = [ + 'type' => [ + 'number', + 'text', + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'type', 'id' ); + + $this->assertArrayHasKey( $this->field_id, $fields ); + $this->assertArrayHasKey( $field_id2, $fields ); + + $fields = array_values( array_unique( $fields ) ); + + $this->assertCount( 2, $fields ); + $this->assertContains( 'number', $fields ); + $this->assertContains( 'text', $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_by_id() { + $this->populate_field(); + + $field_id2 = $this->api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_another_field', + 'type' => 'number', + 'label' => 'Another test field', + ] ); + + $params = [ + 'id' => $field_id2, + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'id' ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $field_id2, $fields ); + + $params = [ + 'id' => [ + $field_id2, + $this->field_id, + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'id' ); + + $this->assertCount( 2, $fields ); + $this->assertContains( $field_id2, $fields ); + $this->assertContains( $this->field_id, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_by_args() { + $this->populate_field(); + + $params = [ + 'args' => [ + 'another_key' => 1, + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'id' ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field_id, $fields ); + + $params = [ + 'args' => [ + 'some_custom_key' => 'Some', + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_by_options() { + $this->populate_field(); + + $params = [ + 'options' => [ + 'another_key' => 1, + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'id' ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field_id, $fields ); + + $params = [ + 'options' => [ + 'some_custom_key' => 'Some', + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_by_where() { + $this->populate_field(); + + $params = [ + 'where' => [ + [ + 'key' => 'another_key', + 'value' => 1, + ], + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $fields = wp_list_pluck( $fields, 'id' ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field_id, $fields ); + + $params = [ + 'where' => [ + [ + 'key' => 'some_custom_key', + 'value' => 'Some', + ], + ], + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_with_names() { + $this->populate_field(); + + $params = [ + 'id' => $this->field_id, + 'names' => true, + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field, $fields ); + + $params = [ + 'id' => $this->field_id, + 'return_type' => 'names', + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_with_names_ids() { + $this->populate_field(); + + $params = [ + 'id' => $this->field_id, + 'names_ids' => true, + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field, $fields ); + $this->assertArrayHasKey( $this->field_id, $fields ); + + $params = [ + 'id' => $this->field_id, + 'return_type' => 'names_ids', + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field, $fields ); + $this->assertArrayHasKey( $this->field_id, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_with_ids() { + $this->populate_field(); + + $params = [ + 'id' => $this->field_id, + 'return_type' => 'ids', + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertCount( 1, $fields ); + $this->assertContains( $this->field_id, $fields ); + } + + /** + * @covers PodsAPI::load_fields + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_fields_with_count() { + $this->populate_field(); + + $field_id2 = $this->api->save_field( [ + 'pod_id' => $this->pod_id, + 'group_id' => $this->group_id, + 'name' => 'test_another_field', + 'type' => 'number', + 'label' => 'Another test field', + ] ); + + $params = [ + 'id' => [ + $this->field_id, + $field_id2, + ], + 'count' => true, + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertInternalType( 'int', $fields ); + $this->assertEquals( 2, $fields ); + + $params = [ + 'id' => [ + $this->field_id, + $field_id2, + ], + 'return_type' => 'count', + ]; + + $fields = $this->api->load_fields( $params ); + + $this->assertInternalType( 'int', $fields ); + $this->assertEquals( 2, $fields ); + } + + /** + * @covers PodsAPI::delete_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_delete_field() { + $this->populate_field(); + + $params = [ + 'id' => $this->field_id, + ]; + + $result = $this->api->delete_field( $params ); + + $this->assertTrue( $result ); + } + + /** + * @covers PodsAPI::delete_field + * @since 2.8.0 + * @throws \Exception + */ + public function test_delete_field_with_field_not_found() { + $params = [ + 'id' => 1234567, + ]; + + $this->expectExceptionMessage( 'Field not found' ); + $this->expectException( \Exception::class ); + + $this->api->delete_field( $params ); + } +} diff --git a/tests/codeception/wpunit/Pods/API/GroupTest.php b/tests/codeception/wpunit/Pods/API/GroupTest.php new file mode 100644 index 0000000000..c1e5668b47 --- /dev/null +++ b/tests/codeception/wpunit/Pods/API/GroupTest.php @@ -0,0 +1,637 @@ +api = pods_api(); + + $this->populate(); + } + + /** + * + */ + public function tearDown(): void { + $this->api = null; + + parent::tearDown(); + } + + public function populate() { + $this->pod = 'test_groups_pod'; + $this->pod_id = $this->api->save_pod( [ + 'name' => $this->pod, + 'type' => 'post_type', + 'label' => 'Test pod for groups', + 'some_custom_key' => 'Some custom value', + 'another_key' => 0, + ] ); + } + + public function populate_group() { + $this->group = 'test_group'; + $this->group_id = $this->api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => $this->group, + 'label' => 'Test group', + 'some_custom_key' => 'One custom value', + 'another_key' => 1, + ] ); + } + + /** + * @covers PodsAPI::save_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_group_with_empty_params() { + $params = []; + + $this->expectExceptionMessage( 'Pod ID or name is required' ); + $this->expectException( \Exception::class ); + + $this->api->save_group( $params ); + } + + /** + * @covers PodsAPI::save_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_group_with_no_group_name() { + $params = [ + 'pod_id' => $this->pod_id, + ]; + + $this->expectExceptionMessage( 'Pod group name is required' ); + $this->expectException( \Exception::class ); + + $this->api->save_group( $params ); + } + + /** + * @covers PodsAPI::save_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_group_with_pod_id() { + $params = [ + 'pod_id' => $this->pod_id, + 'name' => 'test_group', + 'label' => 'Test group', + ]; + + $response = $this->api->save_group( $params ); + + $this->assertInternalType( 'int', $response ); + + $group = $this->api->load_group( $response ); + + $this->assertEquals( $params['name'], $group['name'] ); + $this->assertEquals( '', $group['type'] ); + $this->assertEquals( $params['label'], $group['label'] ); + } + + /** + * @covers PodsAPI::save_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_group_with_pod_id_and_rename() { + $params = [ + 'pod_id' => $this->pod_id, + 'name' => 'test_group', + 'label' => 'Test group', + ]; + + $response = $this->api->save_group( $params ); + + $this->assertInternalType( 'int', $response ); + + $params = [ + 'id' => $response, + 'pod_id' => $this->pod_id, + 'name' => 'test_group2', + 'label' => 'Test group', + ]; + + $response2 = $this->api->save_group( $params ); + + $this->assertEquals( $response, $response2 ); + + $group = $this->api->load_group( $response2 ); + + $this->assertEquals( $params['name'], $group['name'] ); + $this->assertEquals( '', $group['type'] ); + $this->assertEquals( $params['label'], $group['label'] ); + } + + /** + * @covers PodsAPI::add_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_add_group_with_pod_id_using_existing_group_name() { + $params = [ + 'pod_id' => $this->pod_id, + 'name' => 'test_group', + 'label' => 'Test group', + ]; + + $response = $this->api->add_group( $params ); + + $this->assertInternalType( 'int', $response ); + + $params = [ + 'pod_id' => $this->pod_id, + 'name' => 'test_group', + 'label' => 'Test group 2', + ]; + + $this->expectExceptionMessage( 'Group test_group already exists' ); + + $this->api->add_group( $params ); + } + + /** + * @covers PodsAPI::save_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_group_with_pod_name() { + $params = [ + 'pod' => $this->pod, + 'name' => 'test_group', + 'label' => 'Test group', + ]; + + $response = $this->api->save_group( $params ); + + $this->assertInternalType( 'int', $response ); + + $group = $this->api->load_group( $response ); + + $this->assertEquals( $params['name'], $group['name'] ); + $this->assertEquals( '', $group['type'] ); + $this->assertEquals( $params['label'], $group['label'] ); + } + + /** + * @covers PodsAPI::save_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_group_with_pod_object() { + $pod = $this->api->load_pod( [ 'id' => $this->pod_id ] ); + + $params = [ + 'pod' => $pod, + 'name' => 'test_group', + 'label' => 'Test group', + ]; + + $response = $this->api->save_group( $params ); + + $this->assertInternalType( 'int', $response ); + + $group = $this->api->load_group( $response ); + + $this->assertEquals( $params['name'], $group['name'] ); + $this->assertEquals( '', $group['type'] ); + $this->assertEquals( $params['label'], $group['label'] ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_pod_id() { + $this->populate_group(); + + $group = $this->api->load_group( [ + 'pod_id' => $this->pod_id, + 'name' => $this->group, + ] ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_pod_name() { + $this->populate_group(); + + $group = $this->api->load_group( [ + 'pod' => $this->pod, + 'name' => $this->group, + ] ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_pod_object() { + $pod = $this->api->load_pod( [ 'id' => $this->pod_id ] ); + + $this->populate_group(); + + $group = $this->api->load_group( [ + 'pod' => $pod, + 'name' => $this->group, + ] ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_id() { + $this->populate_group(); + + $group = $this->api->load_group( [ + 'id' => $this->group_id, + ] ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_id_direct() { + $this->populate_group(); + + $group = $this->api->load_group( $this->group_id ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_post_direct() { + $this->populate_group(); + + $group = $this->api->load_group( get_post( $this->group_id ) ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_group + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_group_with_object_direct() { + $this->populate_group(); + + $group = $this->api->load_group( [ 'id' => $this->group_id ] ); + $group = $this->api->load_group( $group ); + + $this->assertInstanceOf( Group::class, $group ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_has_groups() { + $this->populate_group(); + + $groups = $this->api->load_groups(); + + $groups = wp_list_pluck( $groups, 'object_type' ); + $groups = array_values( array_unique( $groups ) ); + + $this->assertCount( 1, $groups ); + $this->assertContains( 'group', $groups ); + + $params = [ + 'object_type' => 'field', + ]; + + $groups = $this->api->load_groups( $params ); + + $groups = wp_list_pluck( $groups, 'object_type' ); + $groups = array_values( array_unique( $groups ) ); + + $this->assertCount( 1, $groups ); + $this->assertContains( 'group', $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_by_id() { + $this->populate_group(); + + $group_id2 = $this->api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => 'test_another_group', + 'label' => 'Another test group', + ] ); + + $params = [ + 'id' => $group_id2, + ]; + + $groups = $this->api->load_groups( $params ); + + $groups = wp_list_pluck( $groups, 'id' ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $group_id2, $groups ); + + $params = [ + 'id' => [ + $group_id2, + $this->group_id, + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $groups = wp_list_pluck( $groups, 'id' ); + + $this->assertCount( 2, $groups ); + $this->assertContains( $group_id2, $groups ); + $this->assertContains( $this->group_id, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_by_args() { + $this->populate_group(); + + $params = [ + 'args' => [ + 'another_key' => 1, + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $groups = wp_list_pluck( $groups, 'id' ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group_id, $groups ); + + $params = [ + 'args' => [ + 'some_custom_key' => 'Some', + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 0, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_by_options() { + $this->populate_group(); + + $params = [ + 'options' => [ + 'another_key' => 1, + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $groups = wp_list_pluck( $groups, 'id' ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group_id, $groups ); + + $params = [ + 'options' => [ + 'some_custom_key' => 'Some', + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 0, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_by_where() { + $this->populate_group(); + + $params = [ + 'where' => [ + [ + 'key' => 'another_key', + 'value' => 1, + ], + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $groups = wp_list_pluck( $groups, 'id' ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group_id, $groups ); + + $params = [ + 'where' => [ + [ + 'key' => 'some_custom_key', + 'value' => 'Some', + ], + ], + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 0, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_with_names() { + $this->populate_group(); + + $params = [ + 'id' => $this->group_id, + 'names' => true, + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group, $groups ); + + $params = [ + 'id' => $this->group_id, + 'return_type' => 'names', + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_with_names_ids() { + $this->populate_group(); + + $params = [ + 'id' => $this->group_id, + 'names_ids' => true, + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group, $groups ); + $this->assertArrayHasKey( $this->group_id, $groups ); + + $params = [ + 'id' => $this->group_id, + 'return_type' => 'names_ids', + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group, $groups ); + $this->assertArrayHasKey( $this->group_id, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_with_ids() { + $this->populate_group(); + + $params = [ + 'id' => $this->group_id, + 'return_type' => 'ids', + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertCount( 1, $groups ); + $this->assertContains( $this->group_id, $groups ); + } + + /** + * @covers PodsAPI::load_groups + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_groups_with_count() { + $this->populate_group(); + + $group_id2 = $this->api->save_group( [ + 'pod_id' => $this->pod_id, + 'name' => 'test_another_group', + 'label' => 'Another test group', + ] ); + + $params = [ + 'id' => [ + $this->group_id, + $group_id2, + ], + 'count' => true, + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertInternalType( 'int', $groups ); + $this->assertEquals( 2, $groups ); + + $params = [ + 'id' => [ + $this->group_id, + $group_id2, + ], + 'return_type' => 'count', + ]; + + $groups = $this->api->load_groups( $params ); + + $this->assertInternalType( 'int', $groups ); + $this->assertEquals( 2, $groups ); + } +} diff --git a/tests/codeception/wpunit/Pods/API/PodTest.php b/tests/codeception/wpunit/Pods/API/PodTest.php new file mode 100644 index 0000000000..07bc8af33f --- /dev/null +++ b/tests/codeception/wpunit/Pods/API/PodTest.php @@ -0,0 +1,659 @@ +api = pods_api(); + } + + /** + * + */ + public function tearDown(): void { + $this->api = null; + + parent::tearDown(); + } + + public function populate_pod() { + $this->pod = 'test_pod'; + $this->pod_id = $this->api->save_pod( [ + 'name' => $this->pod, + 'type' => 'post_type', + 'label' => 'Test pod', + 'some_custom_key' => 'Some custom value', + 'another_key' => 1, + ] ); + } + + /** + * @covers PodsAPI::save_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_save_pod_with_empty_params() { + $params = []; + + $this->expectExceptionMessage( 'Pod name is required' ); + $this->expectException( \Exception::class ); + + $this->api->save_pod( $params ); + } + + public function get_save_pod_configs() { + yield 'Post Type' => [ + [ + 'name' => 'test_1', + 'type' => 'post_type', + 'label' => 'Test pod for Post Type', + ], + ]; + + yield 'Taxonomy' => [ + [ + 'name' => 'test_2', + 'type' => 'taxonomy', + 'label' => 'Test pod for Taxonomy', + ], + ]; + + yield 'Advanced Content Type' => [ + [ + 'name' => 'test_3', + 'type' => 'pod', + 'label' => 'Test pod for Advanced Content Type', + ], + ]; + } + + /** + * @covers PodsAPI::save_pod + * @since 2.8.0 + * + * @dataProvider get_save_pod_configs + * @throws \Exception + */ + public function test_save_pod_table( $config ) { + /** @var WPDb $db */ + $db = $this->getModule( 'WPDb' ); + + $params = $config; + + $params['storage'] = 'table'; + $params['name'] .= $params['storage']; + + $response = $this->api->save_pod( $params ); + + $this->assertInternalType( 'int', $response ); + + $pod = $this->api->load_pod( [ 'name' => $params['name'] ] ); + + $this->assertEquals( $params['name'], $pod['name'] ); + $this->assertEquals( $params['type'], $pod['type'] ); + $this->assertEquals( $params['label'], $pod['label'] ); + $this->assertEquals( $params['storage'], $pod['storage'] ); + + /** + * Table testing. + */ + + global $wpdb; + + $wpdb->show_errors( false ); + $wpdb->suppress_errors( true ); + + // Test that the test_field column was added. + $response = $this->api->save_field( [ + 'name' => 'test_field', + 'type' => 'text', + 'pod' => $pod, + ] ); + $this->assertInternalType( 'int', $response ); + + $field = $this->api->load_field( [ 'name' => 'test_field', 'pod' => $pod ] ); + $this->assertEquals( 'test_field', $field['name'] ); + $this->assertEquals( 'text', $field['type'] ); + + $wpdb->get_var( 'SELECT `id`, `test_field` FROM `' . $db->grabTablePrefix() . 'pods_' . $params['name'] . '`' ); + $this->assertEmpty( $wpdb->last_error ); + + // Test that the test_field column was deleted. + $deleted = $this->api->delete_field( [ 'name' => 'test_field', 'pod' => $pod ] ); + $this->assertTrue( $deleted ); + + $wpdb->get_var( 'SELECT `id`, `test_field` FROM `' . $db->grabTablePrefix() . 'pods_' . $params['name'] . '`' ); + $this->assertNotEmpty( $wpdb->last_error ); + } + + /** + * @covers PodsAPI::save_pod + * @since 2.8.0 + * + * @dataProvider get_save_pod_configs + * @throws \Exception + */ + public function test_save_pod_meta( $config ) { + $db = $this->getModule( 'WPDb' ); + + $params = $config; + + $params['storage'] = 'meta'; + $params['name'] .= $params['storage']; + + $response = $this->api->save_pod( $params ); + + $this->assertInternalType( 'int', $response ); + + $pod = $this->api->load_pod( [ 'name' => $params['name'] ] ); + + $this->assertEquals( $params['name'], $pod['name'] ); + $this->assertEquals( $params['type'], $pod['type'] ); + $this->assertEquals( $params['label'], $pod['label'] ); + $this->assertEquals( $params['storage'], $pod['storage'] ); + + global $wpdb; + + $wpdb->get_var( 'SELECT id FROM `' . $db->grabTablePrefix() . 'pods_' . $params['name'] . '`' ); + + $this->assertContains( $db->grabTablePrefix() . 'pods_' . $params['name'] . '\' doesn\'t exist', $wpdb->last_error ); + } + + /** + * @covers PodsAPI::load_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pod_with_id() { + $this->populate_pod(); + + $pod = $this->api->load_pod( [ 'id' => $this->pod_id ] ); + + $this->assertInstanceOf( Pod::class, $pod ); + } + + /** + * @covers PodsAPI::load_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pod_with_internal() { + $pod = $this->api->load_pod( [ 'name' => '_pods_pod' ] ); + + $this->assertInstanceOf( Pod::class, $pod ); + } + + /** + * @covers PodsAPI::load_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pod_with_name() { + $this->populate_pod(); + + $pod = $this->api->load_pod( [ 'name' => $this->pod ] ); + + $this->assertInstanceOf( Pod::class, $pod ); + } + + /** + * @covers PodsAPI::load_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pod_with_object_direct() { + $this->populate_pod(); + + $pod = $this->api->load_pod( [ 'id' => $this->pod_id ] ); + $pod = $this->api->load_pod( $pod ); + + $this->assertInstanceOf( Pod::class, $pod ); + } + + /** + * @covers PodsAPI::load_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pod_with_id_direct() { + $this->populate_pod(); + + $pod = $this->api->load_pod( $this->pod_id ); + + $this->assertInstanceOf( Pod::class, $pod ); + } + + /** + * @covers PodsAPI::load_pod + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pod_with_post_direct() { + $this->populate_pod(); + + $pod = $this->api->load_pod( get_post( $this->pod_id ) ); + + $this->assertInstanceOf( Pod::class, $pod ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_has_pods() { + $this->populate_pod(); + + $pods = $this->api->load_pods(); + + $pods = wp_list_pluck( $pods, 'object_type' ); + $pods = array_values( array_unique( $pods ) ); + + $this->assertCount( 1, $pods ); + $this->assertContains( 'pod', $pods ); + + $params = [ + 'object_type' => 'field', + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'object_type' ); + $pods = array_values( array_unique( $pods ) ); + + $this->assertCount( 1, $pods ); + $this->assertContains( 'pod', $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_by_type() { + $this->populate_pod(); + + $pod_id2 = $this->api->save_pod( [ + 'name' => 'test_another_pod', + 'type' => 'taxonomy', + 'label' => 'Another test pod', + ] ); + + $params = [ + 'type' => 'taxonomy', + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'type', 'id' ); + + $this->assertArrayHasKey( $pod_id2, $pods ); + + $pods = array_values( array_unique( $pods ) ); + + $this->assertCount( 1, $pods ); + $this->assertContains( 'taxonomy', $pods ); + + $params = [ + 'type' => [ + 'taxonomy', + 'post_type', + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'type', 'id' ); + + $this->assertArrayHasKey( $this->pod_id, $pods ); + $this->assertArrayHasKey( $pod_id2, $pods ); + + $pods = array_values( array_unique( $pods ) ); + + $this->assertCount( 2, $pods ); + $this->assertContains( 'taxonomy', $pods ); + $this->assertContains( 'post_type', $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_by_id() { + $this->populate_pod(); + + $pod_id2 = $this->api->save_pod( [ + 'name' => 'test_another_pod', + 'type' => 'taxonomy', + 'label' => 'Another test pod', + ] ); + + $params = [ + 'id' => $pod_id2, + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'id' ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $pod_id2, $pods ); + + $params = [ + 'id' => [ + $pod_id2, + $this->pod_id, + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'id' ); + + $this->assertCount( 2, $pods ); + $this->assertContains( $pod_id2, $pods ); + $this->assertContains( $this->pod_id, $pods ); + + $params = [ + 'ids' => $pod_id2, + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'id' ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $pod_id2, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_by_args() { + $this->populate_pod(); + + $params = [ + 'args' => [ + 'another_key' => 1, + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'id' ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod_id, $pods ); + + $params = [ + 'args' => [ + 'some_custom_key' => 'Some', + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 0, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_by_options() { + $this->populate_pod(); + + $params = [ + 'options' => [ + 'another_key' => 1, + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'id' ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod_id, $pods ); + + $params = [ + 'options' => [ + 'some_custom_key' => 'Some', + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 0, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_by_where() { + $this->populate_pod(); + + $params = [ + 'where' => [ + [ + 'key' => 'another_key', + 'value' => 1, + ], + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $pods = wp_list_pluck( $pods, 'id' ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod_id, $pods ); + + $params = [ + 'where' => [ + [ + 'key' => 'some_custom_key', + 'value' => 'Some', + ], + ], + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 0, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_include_internal() { + $this->populate_pod(); + + $params = [ + 'include_internal' => true, + 'name' => '_pods_pod', + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 1, $pods ); + $this->assertArrayHasKey( '_pods_pod', $pods ); + + $params = [ + 'name' => '_pods_pod', + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 0, $pods ); + + $params = [ + 'include_internal' => true, + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertArrayHasKey( '_pods_pod', $pods ); + + $params = []; + + $pods = $this->api->load_pods( $params ); + + $this->assertArrayNotHasKey( '_pods_pod', $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_with_names() { + $this->populate_pod(); + + $params = [ + 'id' => $this->pod_id, + 'names' => true, + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod, $pods ); + + $params = [ + 'id' => $this->pod_id, + 'return_type' => 'names', + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_with_names_ids() { + $this->populate_pod(); + + $params = [ + 'id' => $this->pod_id, + 'names_ids' => true, + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod, $pods ); + $this->assertArrayHasKey( $this->pod_id, $pods ); + + $params = [ + 'id' => $this->pod_id, + 'return_type' => 'names_ids', + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod, $pods ); + $this->assertArrayHasKey( $this->pod_id, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_with_ids() { + $this->populate_pod(); + + $params = [ + 'id' => $this->pod_id, + 'return_type' => 'ids', + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertCount( 1, $pods ); + $this->assertContains( $this->pod_id, $pods ); + } + + /** + * @covers PodsAPI::load_pods + * @since 2.8.0 + * @throws \Exception + */ + public function test_load_pods_with_count() { + $this->populate_pod(); + + $pod_id2 = $this->api->save_pod( [ + 'name' => 'test_another_pod', + 'type' => 'taxonomy', + 'label' => 'Another test pod', + ] ); + + $params = [ + 'id' => [ + $this->pod_id, + $pod_id2, + ], + 'count' => true, + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertInternalType( 'int', $pods ); + $this->assertEquals( 2, $pods ); + + $params = [ + 'id' => [ + $this->pod_id, + $pod_id2, + ], + 'return_type' => 'count', + ]; + + $pods = $this->api->load_pods( $params ); + + $this->assertInternalType( 'int', $pods ); + $this->assertEquals( 2, $pods ); + } +} diff --git a/tests/codeception/wpunit/Pods/API/Whatsit/Value_FieldTest.php b/tests/codeception/wpunit/Pods/API/Whatsit/Value_FieldTest.php new file mode 100644 index 0000000000..0680e6ca93 --- /dev/null +++ b/tests/codeception/wpunit/Pods/API/Whatsit/Value_FieldTest.php @@ -0,0 +1,177 @@ +value_field = new Value_Field( $this->pods_object_field ); + $this->value = wp_generate_password(); + + $this->value_field->value = $this->value; + } + + public function tearDown(): void { + unset( $this->value_field, $this->value ); + + parent::tearDown(); + } + + /** + * @covers Value_Field::__toString + */ + public function test_string() { + $this->assertTrue( method_exists( $this->value_field, '__toString' ), 'Method __toString does not exist' ); + + $to = (string) $this->value_field; + + $this->assertInternalType( 'string', $to ); + $this->assertEquals( $this->pods_object_field->get_identifier(), $to ); + } + + /** + * @covers Value_Field::offsetExists + * @covers Value_Field::offsetGet + * @covers Value_Field::offsetSet + * @covers Value_Field::offsetUnset + */ + public function test_array_access_pod() { + $value_field = new Value_Field( $this->pods_object_pod ); + $value = wp_generate_password(); + + $value_field->value = $value; + + // Confirm methods exist. + $this->assertTrue( method_exists( $value_field, 'offsetExists' ), 'Method offsetExists does not exist' ); + $this->assertTrue( method_exists( $value_field, 'offsetGet' ), 'Method offsetGet does not exist' ); + $this->assertTrue( method_exists( $value_field, 'offsetSet' ), 'Method offsetSet does not exist' ); + $this->assertTrue( method_exists( $value_field, 'offsetUnset' ), 'Method offsetUnset does not exist' ); + + // Confirm argument get matches ArrayAccess. + $this->assertEquals( $this->pods_object_pod->get_id(), $value_field['id'] ); + $this->assertEquals( $this->pods_object_pod->get_name(), $value_field['name'] ); + $this->assertEquals( $this->pods_object_pod->get_parent(), $value_field['parent'] ); + $this->assertEquals( $this->pods_object_pod->get_group(), $value_field['group'] ); + $this->assertEquals( $this->pods_object_pod->get_fields(), $value_field['fields'] ); + $this->assertEquals( $this->pods_object_pod->get_object_fields(), $value_field['object_fields'] ); + $this->assertEquals( $this->pods_object_pod->get_groups(), $value_field['groups'] ); + $this->assertEquals( $this->pods_object_pod->get_table_info(), $value_field['table_info'] ); + $this->assertEquals( $this->pods_object_pod->get_args(), $value_field['options'] ); + $this->assertEquals( $value, $value_field['value'] ); + + // Confirm argument get matches Object __get. + $this->assertEquals( $this->pods_object_pod->get_id(), $value_field->id ); + $this->assertEquals( $this->pods_object_pod->get_name(), $value_field->name ); + $this->assertEquals( $this->pods_object_pod->get_parent(), $value_field->parent ); + $this->assertEquals( $this->pods_object_pod->get_group(), $value_field->group ); + $this->assertEquals( $this->pods_object_pod->get_fields(), $value_field->fields ); + $this->assertEquals( $this->pods_object_pod->get_object_fields(), $value_field->object_fields ); + $this->assertEquals( $this->pods_object_pod->get_groups(), $value_field->groups ); + $this->assertEquals( $this->pods_object_pod->get_table_info(), $value_field->table_info ); + $this->assertEquals( $this->pods_object_pod->get_args(), $value_field->options ); + $this->assertEquals( $value, $value_field->value ); + + $list = array( $value_field ); + + $this->assertEquals( array( $this->pods_object_pod->get_id() ), wp_list_pluck( $list, 'id' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_name() ), wp_list_pluck( $list, 'name' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_parent() ), wp_list_pluck( $list, 'parent' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_group() ), wp_list_pluck( $list, 'group' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_arg( 'custom1' ) ), wp_list_pluck( $list, 'custom1' ) ); + $this->assertEquals( array( $value ), wp_list_pluck( $list, 'value' ) ); + + // Test non-existent arguments and handling for ArrayAccess. + $this->assertNull( $this->pods_object_pod->get_arg( 'fourohfour' ) ); + $this->assertEquals( $this->pods_object_pod->get_arg( 'fourohfour' ), $value_field['fourohfour'] ); + $this->assertFalse( isset( $value_field['fourohfour'] ) ); + + // Test isset for ArrayAccess. + $this->assertTrue( isset( $value_field['id'] ) ); + $this->assertTrue( isset( $value_field['name'] ) ); + $this->assertTrue( isset( $value_field['parent'] ) ); + $this->assertTrue( isset( $value_field['group'] ) ); + + // Test unset handling for ArrayAccess served arguments. + unset( $value_field['id'], $value_field['name'], $value_field['parent'], $value_field['group'], $value_field['value'] ); + + // Confirm ArrayAccess arguments are now empty strings for reserved arguments. + $this->assertEquals( $value_field['id'], '' ); + $this->assertEquals( $value_field['name'], '' ); + $this->assertEquals( $value_field['parent'], '' ); + $this->assertEquals( $value_field['group'], '' ); + $this->assertNull( $value_field['value'] ); + } + + /** + * @covers Value_Field::init + * @covers Value_Field::__toString + */ + public function test_init() { + $this->assertTrue( method_exists( Value_Field::class, 'init' ), 'Method init does not exist' ); + + $value_field = Value_Field::init( $this->pods_object_group ); + + $this->assertInstanceOf( Value_Field::class, $value_field ); + + $to = (string) $value_field; + + $this->assertInternalType( 'string', $to ); + $this->assertEquals( $this->pods_object_group->get_identifier(), $to ); + } + + /** + * @covers Value_Field::offsetGet + * @covers Value_Field::offsetSet + * @covers Value_Field::__get + * @covers Value_Field::__set + */ + public function test_backcompat_pod() { + $value_field = new Value_Field( $this->pods_object_pod ); + + $this->assertCount( 1, $value_field['fields'] ); + $this->assertCount( 1, $value_field['groups'] ); + $this->assertCount( 24, $value_field['object_fields'] ); + $this->assertCount( 28, $value_field['table_info'] ); + + $this->assertArrayHasKey( 'test-field', $value_field['fields'] ); + $this->assertEquals( 'Test field', $value_field['fields']['test-field']['label'] ); + $this->assertEquals( 'Test field', $value_field['fields']['test-field']['options']['label'] ); + $this->assertArrayHasKey( 'test-group', $value_field['groups'] ); + $this->assertEquals( 'Test group', $value_field['groups']['test-group']['label'] ); + $this->assertEquals( 'Test group', $value_field['groups']['test-group']['options']['label'] ); + + if ( ! pods_version_check( 'php', '7.0' ) ) { + return; + } + + $value_field['fields']['test-field']['options']['label'] = 'Something else'; + + // Backcompat does not throw PHP errors but does not save the variables. + // This is acceptable because the PHP errors cause more breakage. + $this->assertNotEquals( 'Something else', $value_field['fields']['test-field']['label'] ); + $this->assertNotEquals( 'Something else', $value_field['fields']['test-field']['options']['label'] ); + } + +} diff --git a/tests/codeception/wpunit/Pods/APITest.php b/tests/codeception/wpunit/Pods/APITest.php new file mode 100644 index 0000000000..8baf8e66cd --- /dev/null +++ b/tests/codeception/wpunit/Pods/APITest.php @@ -0,0 +1,228 @@ +api = pods_api(); + } + + /** + * + */ + public function tearDown(): void { + $this->pod_id = null; + $this->pod_id2 = null; + $this->api = null; + + parent::tearDown(); + } + + /** + * + */ + public function populate() { + $this->pod_id = $this->api->save_pod( array( + 'storage' => 'meta', + 'type' => 'post_type', + 'name' => $this->pod_name, + ) ); + + $this->pod_id2 = $this->api->save_pod( array( + 'storage' => 'meta', + 'type' => 'post_type', + 'name' => $this->pod_name2, + ) ); + + $params = array( + 'pod_id' => $this->pod_id, + 'name' => 'number1', + 'type' => 'number', + ); + + $this->api->save_field( $params ); + + $params = array( + 'pod_id' => $this->pod_id2, + 'name' => 'number2', + 'type' => 'number', + ); + + $this->api->save_field( $params ); + + $params = array( + 'pod_id' => $this->pod_id, + 'name' => 'related_field', + 'type' => 'pick', + 'pick_object' => 'post_type', + 'pick_val' => $this->pod_name2, + 'pick_format_type' => 'multi', + ); + + $this->api->save_field( $params ); + + $params = array( + 'pod_id' => $this->pod_id2, + 'name' => 'related_field2', + 'type' => 'pick', + 'pick_object' => 'post_type', + 'pick_val' => $this->pod_name, + 'pick_format_type' => 'multi', + ); + + $this->api->save_field( $params ); + } + + /** + * @covers PodsAPI::init + * @since 2.8.0 + */ + public function test_method_exists_init() { + $this->assertTrue( method_exists( 'PodsAPI', 'init' ), 'Method init does not exist' ); + } + + /** + * Test the init method with no pod defined + * @covers PodsAPI::init + * @depends test_method_exists_init + * @since 2.8.0 + */ + public function test_method_init_no_pod() { + $this->assertInstanceOf( 'PodsAPI', PodsAPI::init(), 'Object returned is not of type Pods_API' ); + } + + /** + * @covers PodsAPI::__construct + * @since 2.8.0 + */ + public function test_method_construct_no_pod() { + $this->assertTrue( $this->api->display_errors, 'Property display_errors not true' ); + $this->assertNull( $this->api->pod_data, 'Property pod_data not null' ); + $this->assertNull( $this->api->pod, 'Property pod not null' ); + $this->assertNull( $this->api->pod_id, 'Property pod_id not null' ); + $this->assertEmpty( $this->api->fields, 'Property fields not empty' ); + $this->assertNull( $this->api->format, 'Property format not null' ); + } + + /** + * @covers PodsAPI::traverse_fields + * @throws \Exception + * @since 2.8.0 + */ + public function test_method_traverse_fields() { + $this->assertTrue( method_exists( $this->api, 'traverse_fields' ), 'Method traverse_fields does not exist' ); + + $this->populate(); + + // Test getting just one related field. + $params = array( + 'expand' => array( + 'related_field', + ), + 'pod' => $this->pod_name, + ); + + $traversed = $this->api->traverse_fields( $params ); + + $this->assertCount( 1, $traversed ); + $this->assertInstanceOf( Field::class, $traversed[0] ); + + // Test getting just one related field with another non-related field. + $params = array( + 'expand' => array( + 'related_field', + 'number1', + ), + 'pod' => $this->pod_name, + ); + + $traversed = $this->api->traverse_fields( $params ); + + $this->assertCount( 1, $traversed ); + $this->assertInstanceOf( Field::class, $traversed[0] ); + + // Test getting just multiple related fields. + $params = array( + 'expand' => array( + 'related_field', + 'related_field2', + 'related_field', + 'related_field2', + ), + 'pod' => $this->pod_name, + ); + + $traversed = $this->api->traverse_fields( $params ); + + $this->assertCount( 4, $traversed ); + $this->assertInstanceOf( Field::class, $traversed[0] ); + $this->assertEquals( $this->pod_name, $traversed[0]['pod'] ); + $this->assertInstanceOf( Field::class, $traversed[1] ); + $this->assertEquals( $this->pod_name2, $traversed[1]['pod'] ); + $this->assertInstanceOf( Field::class, $traversed[2] ); + $this->assertEquals( $this->pod_name, $traversed[2]['pod'] ); + $this->assertInstanceOf( Field::class, $traversed[3] ); + $this->assertEquals( $this->pod_name2, $traversed[3]['pod'] ); + + // Test getting just multiple related fields with another non-related field. + $params = array( + 'expand' => array( + 'related_field', + 'related_field2', + 'related_field', + 'related_field2', + 'number2', + ), + 'pod' => $this->pod_name, + ); + + $traversed = $this->api->traverse_fields( $params ); + + $this->assertCount( 4, $traversed ); + $this->assertInstanceOf( Field::class, $traversed[0] ); + $this->assertEquals( $this->pod_name, $traversed[0]['pod'] ); + $this->assertInstanceOf( Field::class, $traversed[1] ); + $this->assertEquals( $this->pod_name2, $traversed[1]['pod'] ); + $this->assertInstanceOf( Field::class, $traversed[2] ); + $this->assertEquals( $this->pod_name, $traversed[2]['pod'] ); + $this->assertInstanceOf( Field::class, $traversed[3] ); + $this->assertEquals( $this->pod_name2, $traversed[3]['pod'] ); + } +} diff --git a/tests/codeception/wpunit/Pods/AdminTest.php b/tests/codeception/wpunit/Pods/AdminTest.php new file mode 100644 index 0000000000..b2c9e0ad8b --- /dev/null +++ b/tests/codeception/wpunit/Pods/AdminTest.php @@ -0,0 +1,585 @@ +api = pods_api(); + $this->admin = new PodsAdmin(); + } + + /** + * + */ + public function tearDown(): void { + $this->api = null; + $this->admin = null; + + parent::tearDown(); + } + + /** + * Provide get_* methods to be tested. + * + * @return array + */ + public function provider_global_config_checks() { + $groups_for_group = [ + 'basic', + 'advanced', + ]; + + $groups_for_field = [ + 'basic', + 'additional-field-text', + 'additional-field-website', + 'additional-field-phone', + 'additional-field-email', + 'additional-field-password', + 'additional-field-paragraph', + 'additional-field-wysiwyg', + 'additional-field-code', + 'additional-field-datetime', + 'additional-field-date', + 'additional-field-time', + 'additional-field-number', + 'additional-field-currency', + 'additional-field-file', + 'additional-field-oembed', + 'additional-field-pick', + 'additional-field-boolean', + 'additional-field-heading', + 'additional-field-html', + 'advanced', + ]; + + yield 'new post type with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'new-post-type-meta', + 'type' => 'post_type', + 'storage' => 'meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'labels', + 'admin-ui', + 'connections', + 'advanced', + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'new post type with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'new-post-type-table', + 'type' => 'post_type', + 'storage' => 'table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'labels', + 'admin-ui', + 'connections', + 'advanced', + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended post type with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'ext-post-type-meta', + 'type' => 'post_type', + 'storage' => 'meta', + 'object' => 'ext-post-type-meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended post type with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'ext-post-type-table', + 'type' => 'post_type', + 'storage' => 'table', + 'object' => 'ext-post-type-table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'new taxonomy with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'new-taxonomy-meta', + 'type' => 'taxonomy', + 'storage' => 'meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'labels', + 'admin-ui', + 'connections', + 'advanced', + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'new taxonomy with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'new-taxonomy-table', + 'type' => 'taxonomy', + 'storage' => 'table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'labels', + 'admin-ui', + 'connections', + 'advanced', + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended taxonomy with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'ext-taxonomy-meta', + 'type' => 'taxonomy', + 'storage' => 'meta', + 'object' => 'ext-taxonomy-meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended taxonomy with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'ext-taxonomy-table', + 'type' => 'taxonomy', + 'storage' => 'table', + 'object' => 'ext-taxonomy-table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended media with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'media', + 'type' => 'media', + 'storage' => 'meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended media with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'media', + 'type' => 'media', + 'storage' => 'table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => array_merge( $groups_for_field, [ 'rest' ] ), + ], + ], + ], + ]; + + yield 'extended comment with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'comment', + 'type' => 'comment', + 'storage' => 'meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => $groups_for_field, + ], + ], + ], + ]; + + yield 'extended comment with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'comment', + 'type' => 'comment', + 'storage' => 'table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => $groups_for_field, + ], + ], + ], + ]; + + yield 'extended user with meta storage' => [ + [ + 'pod_args' => [ + 'name' => 'user', + 'type' => 'user', + 'storage' => 'meta', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => [ + 'basic', + 'additional-field-text', + 'additional-field-website', + 'additional-field-phone', + 'additional-field-email', + 'additional-field-password', + 'additional-field-paragraph', + 'additional-field-wysiwyg', + 'additional-field-code', + 'additional-field-datetime', + 'additional-field-date', + 'additional-field-time', + 'additional-field-number', + 'additional-field-currency', + 'additional-field-file', + 'additional-field-avatar', + 'additional-field-oembed', + 'additional-field-pick', + 'additional-field-boolean', + 'additional-field-heading', + 'additional-field-html', + 'advanced', + 'rest', + ], + ], + ], + ], + ]; + + yield 'extended user with table storage' => [ + [ + 'pod_args' => [ + 'name' => 'user', + 'type' => 'user', + 'storage' => 'table', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'pods-pfat', + 'rest-api', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => [ + 'basic', + 'additional-field-text', + 'additional-field-website', + 'additional-field-phone', + 'additional-field-email', + 'additional-field-password', + 'additional-field-paragraph', + 'additional-field-wysiwyg', + 'additional-field-code', + 'additional-field-datetime', + 'additional-field-date', + 'additional-field-time', + 'additional-field-number', + 'additional-field-currency', + 'additional-field-file', + 'additional-field-avatar', + 'additional-field-oembed', + 'additional-field-pick', + 'additional-field-boolean', + 'additional-field-heading', + 'additional-field-html', + 'advanced', + 'rest', + ], + ], + ], + ], + ]; + + yield 'settings' => [ + [ + 'pod_args' => [ + 'name' => 'settings-pod', + 'type' => 'settings', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'labels', + 'admin-ui', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => $groups_for_field, + ], + ], + ], + ]; + + yield 'advanced content type' => [ + [ + 'pod_args' => [ + 'name' => 'act-pod', + 'type' => 'pod', + ], + 'config' => [ + 'pod' => [ + 'groups' => [ + 'labels', + 'admin-ui', + 'advanced', + ], + ], + 'group' => [ + 'groups' => $groups_for_group, + ], + 'field' => [ + 'groups' => [ + 'basic', + 'additional-field-text', + 'additional-field-website', + 'additional-field-phone', + 'additional-field-email', + 'additional-field-password', + 'additional-field-paragraph', + 'additional-field-wysiwyg', + 'additional-field-code', + 'additional-field-datetime', + 'additional-field-date', + 'additional-field-time', + 'additional-field-number', + 'additional-field-currency', + 'additional-field-file', + 'additional-field-oembed', + 'additional-field-pick', + 'additional-field-boolean', + 'additional-field-slug', + 'additional-field-heading', + 'additional-field-html', + 'advanced', + ], + ], + ], + ], + ]; + } + + /** + * @dataProvider provider_global_config_checks + */ + public function test_admin_get_global_config( $test ) { + $check_params = [ + 'name' => $test['pod_args']['name'], + ]; + + if ( $pod = $this->api->load_pod( $check_params ) ) { + $this->api->delete_pod( $check_params ); + } + + $this->api->save_pod( $test['pod_args'] ); + + $pod = $this->api->load_pod( $check_params ); + + $this->assertInstanceOf( Pod::class, $pod ); + + $config = $this->admin->get_global_config( $pod ); + + $this->assertCount( 3, $config ); + $this->assertArrayHasKey( 'pod', $config ); + $this->assertArrayHasKey( 'group', $config ); + $this->assertArrayHasKey( 'field', $config ); + + $pod_names = wp_list_pluck( $config['pod']['groups'], 'name' ); + $group_names = wp_list_pluck( $config['group']['groups'], 'name' ); + $field_names = wp_list_pluck( $config['field']['groups'], 'name' ); + + $this->assertEquals( '_pods_pod', $config['pod']['name'] ); + $this->assertEquals( $test['config']['pod']['groups'], $pod_names ); + $this->assertEquals( '_pods_group', $config['group']['name'] ); + $this->assertEquals( $test['config']['group']['groups'], $group_names ); + $this->assertEquals( '_pods_field', $config['field']['name'] ); + $this->assertEquals( $test['config']['field']['groups'], $field_names ); + } +} diff --git a/tests/codeception/wpunit/Pods/Bug/Bug3451Test.php b/tests/codeception/wpunit/Pods/Bug/Bug3451Test.php new file mode 100644 index 0000000000..6aa3dc5585 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Bug/Bug3451Test.php @@ -0,0 +1,196 @@ + 0, + 'post_title' => 'Test 3451 Draft post', + 'post_content' => 'Content here', + 'post_status' => 'draft', + 'post_date' => '2021-01-01 01:01:01', + ]; + private $private_post = [ + 'ID' => 0, + 'post_title' => 'Test 3451 Private post', + 'post_content' => 'Content here', + 'post_status' => 'private', + 'post_date' => '2021-01-01 01:01:01', + ]; + private $public_post = [ + 'ID' => 0, + 'post_title' => 'Test 3451 Public post', + 'post_content' => 'Content here', + 'post_status' => 'publish', + 'post_date' => '2021-01-01 01:01:01', + ]; + private $user_id = 0; + + public function setUp() { + parent::setUp(); + + $params = [ + 'name' => $this->pod_name, + 'type' => 'post_type', + 'storage' => 'meta', + ]; + + $api = pods_api(); + + // Save Pod similar to PodsAdmin. + $pod_id = $api->save_pod( $params ); + + $field_params = [ + 'pod_id' => $pod_id, + 'name' => $this->pod_name . '_related', + 'type' => 'pick', + 'pick_object' => 'post_type', + 'pick_val' => $this->pod_name, + ]; + + $api->save_field( $field_params ); + + $pod = pods( $this->pod_name ); + + $this->user_id = $this->factory()->user->create( [ 'role' => 'administrator' ] ); + + $this->draft_post['post_author'] = $this->user_id; + $this->private_post['post_author'] = $this->user_id; + $this->public_post['post_author'] = $this->user_id; + + $this->draft_post['ID'] = $pod->add( $this->draft_post ); + $this->private_post['ID'] = $pod->add( $this->private_post ); + $this->public_post['ID'] = $pod->add( $this->public_post ); + } + + public function tearDown() : void { + $api = pods_api(); + + // Delete all posts. + $api->reset_pod( [ 'name' => $this->pod_name ] ); + + // Delete the pod config. + $api->delete_pod( [ 'name' => $this->pod_name ] ); + + // Reset current user. + global $current_user; + + $current_user = null; + + wp_set_current_user( 0 ); + + parent::tearDown(); + } + + /* + * Test that private posts show in find() for user. + */ + public function test_private_posts_show_in_find_for_user() { + $this->markTestIncomplete( 'This test is for an enhancement that is not ready yet' ); + + wp_set_current_user( $this->user_id ); + + $pod = pods( $this->pod_name ); + + $params = [ + 'pagination' => false, + 'search' => false, + 'limit' => 5, + ]; + + $pod->find( $params ); + + codecept_debug( $pod->sql ); + + $data = $pod->data(); + + $titles = wp_list_pluck( $data, 'post_title' ); + + $this->assertNotContains( $this->draft_post['post_title'], $titles ); + $this->assertContains( $this->private_post['post_title'], $titles ); + $this->assertContains( $this->public_post['post_title'], $titles ); + } + + /* + * Test that private posts show in find() with WHERE post_status. + */ + public function test_private_posts_show_in_find_with_where_post_status() { + wp_set_current_user( $this->user_id ); + + $pod = pods( $this->pod_name ); + + $params = [ + 'pagination' => false, + 'search' => false, + 'limit' => 5, + 'where' => 't.post_status = "publish" OR ( t.post_status = "private" AND t.post_author = ' . get_current_user_id() . ' )', + ]; + + $pod->find( $params ); + + $data = $pod->data(); + + $titles = wp_list_pluck( $data, 'post_title' ); + + $this->assertNotContains( $this->draft_post['post_title'], $titles ); + $this->assertContains( $this->private_post['post_title'], $titles ); + $this->assertContains( $this->public_post['post_title'], $titles ); + } + + /* + * Test that private posts do not show in find() if no access. + */ + public function test_private_posts_do_not_show_in_find_if_no_access() { + $pod = pods( $this->pod_name ); + + $params = [ + 'pagination' => false, + 'search' => false, + 'limit' => 5, + ]; + + $pod->find( $params ); + + $data = $pod->data(); + + $titles = wp_list_pluck( $data, 'post_title' ); + + $this->assertNotContains( $this->draft_post['post_title'], $titles ); + $this->assertNotContains( $this->private_post['post_title'], $titles ); + $this->assertContains( $this->public_post['post_title'], $titles ); + } + + /* + * Test that private post shows in fetch(). + */ + public function test_private_post_shows_in_fetch() { + wp_set_current_user( $this->user_id ); + + $pod = pods( $this->pod_name ); + + $this->assertNotEmpty( $pod->fetch( $this->draft_post['ID'] ) ); + $this->assertNotEmpty( $pod->fetch( $this->private_post['ID'] ) ); + $this->assertNotEmpty( $pod->fetch( $this->public_post['ID'] ) ); + } + + /* + * Test that private posts show in relationship lists for user. + */ + public function test_private_posts_show_in_relationship_lists_for_user() { + // @todo Work on this. + } + + /* + * Test that private posts do not show in relationship lists if no access. + */ + public function test_private_posts_do_not_show_in_relationship_lists_if_no_access() { + // @todo Work on this. + } +} diff --git a/tests/codeception/wpunit/Pods/Bug/Bug4097Test.php b/tests/codeception/wpunit/Pods/Bug/Bug4097Test.php new file mode 100644 index 0000000000..3dbe8c8579 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Bug/Bug4097Test.php @@ -0,0 +1,122 @@ +pod_name . '_' . substr( $storage, 2 ) . '_' . substr( $type, 2 ); + + $api = pods_api(); + + $this->pod_id = $api->save_pod( array( + 'storage' => $storage, + 'type' => $type, + 'name' => $pod_name, + ) ); + + $params = array( + 'pod' => $pod_name, + 'pod_id' => $this->pod_id, + 'name' => 'color', + 'type' => 'pick', + 'pick_object' => 'custom-simple', + 'pick_custom' => "yellow|Kollane\ngreen|Roheline\nbrown|Pruun\nred|Punane\n", + 'pick_format_type' => 'multi', + 'pick_format_multi' => 'checkbox', + ); + + $api->save_field( $params ); + + return $pod_name; + } + + public function tearDown(): void { + $this->pod_id = null; + } + + /** + * @param $type + * @param $storage + * + * @dataProvider setup_providers + */ + public function test_setups( $type, $storage ) { + $pod_name = $this->setup_pod( $type, $storage ); + + codecept_debug( 'Test setup: ' . $type . ' | ' . $storage ); + + $pod = pods( $pod_name ); + + $this->assertNotFalse( $pod ); + + $id = $pod->add( array( + 'color' => array( + 0 => 'green', + 1 => 'brown', + 2 => 'red', + ), + ) ); + + $pod->fetch( $id ); + + $value = $pod->display( 'color' ); + + $this->assertEquals( 'Roheline, Pruun, and Punane', $value ); + + $id = $pod->add( array( + 'color' => array( + 2 => 'green', + 3 => 'brown', + 4 => 'red', + ), + ) ); + + $pod->fetch( $id ); + + $value = $pod->display( 'color' ); + + $this->assertEquals( 'Roheline, Pruun, and Punane', $value ); + + $id = $pod->add( array( + 'color' => array( + 'yellow', + 'green', + 'brown', + 'red' + ) + ) ); + + $pod->fetch( $id ); + + $value = $pod->display( 'color' ); + + $this->assertEquals( 'Kollane, Roheline, Pruun, and Punane', $value ); + } + + public function setup_providers() { + return array( + array( 'meta', 'post_type' ), + array( 'table', 'post_type' ), + array( 'table', 'pod' ), + ); + } + +} diff --git a/tests/codeception/wpunit/Pods/Bug/Bug5254Test.php b/tests/codeception/wpunit/Pods/Bug/Bug5254Test.php new file mode 100644 index 0000000000..972ab0b9da --- /dev/null +++ b/tests/codeception/wpunit/Pods/Bug/Bug5254Test.php @@ -0,0 +1,30 @@ +assertFalse( $result ); + + $params = array( 'bypass_helpers' => false ); + $result = pods_str_replace( '@wp_', '{prefix}', $params ); + $this->assertFalse( $result['bypass_helpers'] ); + + $params = array( 'nested' => array( 'bypass_helpers' => false ) ); + $result = pods_str_replace( '@wp_', '{prefix}', $params ); + $this->assertFalse( $result['nested']['bypass_helpers'] ); + + } +} diff --git a/tests/codeception/wpunit/Pods/Bug/Bug5476Test.php b/tests/codeception/wpunit/Pods/Bug/Bug5476Test.php new file mode 100644 index 0000000000..62dde5c92f --- /dev/null +++ b/tests/codeception/wpunit/Pods/Bug/Bug5476Test.php @@ -0,0 +1,38 @@ +load(); + $active = $components->activate_component('migrate-packages'); + $this->assertTrue( $active ); + + $components->load(); + + // The WordPress test framework rolls back during tearDown, so we can safely delete the data without affecting other tests + pods_api()->delete_pod( 'page' ); + + /** @var \Pods_Migrate_Packages $migrate */ + $migrate = $components->components['migrate-packages']['object']; + $result = $migrate->import( $import, true ); + $this->assertNotFalse( $result ); + + $banana_content = 'This failure is brought [pods] to you by migrate-packages'; + + $pod = pods( 'page' ); + $id = $pod->add( array( 'banana' => $banana_content ) ); + $pod->fetch( $id ); + $this->assertEquals( wpautop( trim( strip_shortcodes( $banana_content ) ) ), $pod->display( 'banana' ) ); + + } +} diff --git a/tests/codeception/wpunit/Pods/Bug/Bug5909Test.php b/tests/codeception/wpunit/Pods/Bug/Bug5909Test.php new file mode 100644 index 0000000000..ebdc167f64 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Bug/Bug5909Test.php @@ -0,0 +1,46 @@ + 'sanitize5909', + 'fields' => [ + $_field_json, + ], + ]; + + $api = pods_api(); + + // Save Pod similar to PodsAdmin. + $api->save_pod( $params ); + + // Fetch the stored data. + $pod = pods( $params['name'] ); + + $rel_field = $pod->fields( $_field_json['name'] ); + + $this->assertNotEmpty( $rel_field ); + $this->assertEquals( $where, $rel_field['pick_where'] ); + $this->assertEquals( $where, $rel_field['options']['pick_where'] ); + } +} diff --git a/tests/codeception/wpunit/Pods/Field/PodsField_BooleanTest.php b/tests/codeception/wpunit/Pods/Field/PodsField_BooleanTest.php new file mode 100644 index 0000000000..c5f181245f --- /dev/null +++ b/tests/codeception/wpunit/Pods/Field/PodsField_BooleanTest.php @@ -0,0 +1,544 @@ +field = new PodsField_Boolean(); + } + + public function tearDown(): void { + unset( $this->field ); + } + + /** + * @covers ::options + */ + public function test_method_options_exists() { + $this->assertTrue( method_exists( $this->field, 'options' ), 'Method ::options does not exist.' ); + } + + /** + * @covers ::options + * @depends test_method_options_exists + */ + public function test_method_options_returns_array() { + $this->assertInternalType( 'array', $this->field->options() ); + } + + /** + * @covers ::options + * @depends test_method_options_exists + * @depends test_method_options_returns_array + */ + public function test_method_options_key_boolean_format_type_present() { + $this->assertArrayHasKey( 'boolean_format_type', $this->field->options() ); + } + + /** + * @covers ::options + * @depends test_method_options_exists + * @depends test_method_options_returns_array + */ + public function test_method_options_key_boolean_yes_label_present() { + $this->assertArrayHasKey( 'boolean_yes_label', $this->field->options() ); + } + + /** + * @covers ::options + * @depends test_method_options_exists + * @depends test_method_options_returns_array + */ + public function test_method_options_key_boolean_no_label_present() { + $this->assertArrayHasKey( 'boolean_no_label', $this->field->options() ); + } + + /** + * @covers ::schema + */ + public function test_method_schema_exists() { + $this->assertTrue( method_exists( $this->field, 'schema' ), 'Method ::schema does not exist.' ); + } + + /** + * @covers ::schema + * @depends test_method_schema_exists + */ + public function test_method_schema() { + $this->assertEquals( 'BOOL DEFAULT 0', $this->field->schema() ); + } + + /** + * @covers ::display + */ + public function test_method_display_exists() { + $this->assertTrue( method_exists( $this->field, 'display' ), 'Method ::display does not exist.' ); + } + + /** + * @covers ::display + * @depends test_method_display_exists + * @uses ::pods_v + */ + public function test_method_display_defaults() { + $this->assertNull( $this->field->display() ); + } + + /** + * @covers ::display + * @depends test_method_display_exists + * @uses ::pods_v + */ + public function test_method_display_true() { + $this->assertEquals( 1, $this->field->display( 1 ) ); + } + + /** + * @covers ::display + * @depends test_method_display_exists + * @uses ::pods_v + */ + public function test_method_display_false() { + $this->assertEquals( 0, $this->field->display( 0 ) ); + } + + /** + * @covers ::input + */ + public function test_method_input_exists() { + $this->assertTrue( method_exists( $this->field, 'input' ), 'Method ::input does not exist.' ); + } + + /** + * @covers ::data + */ + public function test_method_data_exists() { + $this->assertTrue( method_exists( $this->field, 'data' ), 'Method ::data does not exist.' ); + } + + /** + * @covers ::data + * @depends test_method_data_exists + * @uses ::pods_v + */ + public function test_method_data_defaults() { + $this->assertEquals( array( + 1 => null, + 0 => null, + ), $this->field->data( 'foo' ) ); + } + + /** + * @covers ::data + * @depends test_method_data_exists + * @uses ::pods_v + */ + public function test_method_data_format_type_radio() { + $this->assertEquals( array( + 1 => 'bar', + 0 => 'baz', + ), $this->field->data( 'foo', null, array( + 'boolean_format_type' => 'radio', + 'boolean_yes_label' => 'bar', + 'boolean_no_label' => 'baz', + ) ) ); + } + + /** + * @covers ::data + * @depends test_method_data_exists + * @uses ::pods_v + */ + public function test_method_data_format_type_checkbox() { + $this->assertEquals( array( 1 => 'bar' ), $this->field->data( 'foo', null, array( + 'boolean_format_type' => 'checkbox', + 'boolean_yes_label' => 'bar', + ) ) ); + } + + /** + * @covers ::regex + */ + public function test_method_regex_exists() { + $this->assertTrue( method_exists( $this->field, 'regex' ), 'Method ::regex does not exist.' ); + } + + /** + * @covers ::regex + * @depends test_method_regex_exists + */ + public function test_method_regex() { + $this->assertFalse( $this->field->regex() ); + } + + /** + * @covers ::validate + */ + public function test_method_validate_exists() { + $this->assertTrue( method_exists( $this->field, 'validate' ), 'Method ::validate does not exist.' ); + } + + /** + * @covers ::validate + * @depends test_method_validate_exists + */ + public function test_method_validate() { + + // All values are valid as they are parsed to integers (1 or 0). + + $options = array( + 'boolean_format_type' => 'radio', + 'required' => false, + ); + + // Empty values. + $this->assertTrue( $this->field->validate( true, null, $options ) ); + $this->assertTrue( $this->field->validate( 1, null, $options ) ); + $this->assertTrue( $this->field->validate( '1', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); + $this->assertTrue( $this->field->validate( 'On', null, $options ) ); + $this->assertTrue( $this->field->validate( 'True', null, $options ) ); + + // Non empty values. + $this->assertTrue( $this->field->validate( false, null, $options ) ); + $this->assertTrue( $this->field->validate( 0, null, $options ) ); + $this->assertTrue( $this->field->validate( '0', null, $options ) ); + $this->assertTrue( $this->field->validate( 'No', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Off', null, $options ) ); + $this->assertTrue( $this->field->validate( 'False', null, $options ) ); + + // Other + $this->assertTrue( $this->field->validate( '', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Foobar', null, $options ) ); + + $options = array( + 'boolean_format_type' => 'radio', + 'required' => true, + ); + + // Empty values. + $this->assertTrue( $this->field->validate( true, null, $options ) ); + $this->assertTrue( $this->field->validate( 1, null, $options ) ); + $this->assertTrue( $this->field->validate( '1', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); + $this->assertTrue( $this->field->validate( 'On', null, $options ) ); + $this->assertTrue( $this->field->validate( 'True', null, $options ) ); + + // Non empty values. + $this->assertTrue( $this->field->validate( false, null, $options ) ); + $this->assertTrue( $this->field->validate( 0, null, $options ) ); + $this->assertTrue( $this->field->validate( '0', null, $options ) ); + $this->assertTrue( $this->field->validate( 'No', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Off', null, $options ) ); + $this->assertTrue( $this->field->validate( 'False', null, $options ) ); + + // Other + $this->assertTrue( $this->field->validate( '', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Foobar', null, $options ) ); + + $options = array( + 'boolean_format_type' => 'checkbox', + 'required' => false, + ); + + // Empty values. + $this->assertTrue( $this->field->validate( true, null, $options ) ); + $this->assertTrue( $this->field->validate( 1, null, $options ) ); + $this->assertTrue( $this->field->validate( '1', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); + $this->assertTrue( $this->field->validate( 'On', null, $options ) ); + $this->assertTrue( $this->field->validate( 'True', null, $options ) ); + + // Non empty values. + $this->assertTrue( $this->field->validate( false, null, $options ) ); + $this->assertTrue( $this->field->validate( 0, null, $options ) ); + $this->assertTrue( $this->field->validate( '0', null, $options ) ); + $this->assertTrue( $this->field->validate( 'No', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Off', null, $options ) ); + $this->assertTrue( $this->field->validate( 'False', null, $options ) ); + + // Other + $this->assertTrue( $this->field->validate( '', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Foobar', null, $options ) ); + + + /** + * Required checkbox. + * Only non_empty values are valid since a required checkbox only has one value. + */ + + $options = array( + 'boolean_format_type' => 'checkbox', + 'required' => true, + ); + + // Empty values. + $this->assertTrue( $this->field->validate( true, null, $options ) ); + $this->assertTrue( $this->field->validate( 1, null, $options ) ); + $this->assertTrue( $this->field->validate( '1', null, $options ) ); + $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); + $this->assertTrue( $this->field->validate( 'On', null, $options ) ); + $this->assertTrue( $this->field->validate( 'True', null, $options ) ); + + // Non empty values. + $this->assertNotTrue( $this->field->validate( false, null, $options ) ); + $this->assertNotTrue( $this->field->validate( 0, null, $options ) ); + $this->assertNotTrue( $this->field->validate( '0', null, $options ) ); + $this->assertNotTrue( $this->field->validate( 'No', null, $options ) ); + $this->assertNotTrue( $this->field->validate( 'Off', null, $options ) ); + $this->assertNotTrue( $this->field->validate( 'False', null, $options ) ); + + // Other + $this->assertNotTrue( $this->field->validate( '', null, $options ) ); // Parses to 0. + $this->assertNotTrue( $this->field->validate( 'Foobar', null, $options ) ); // Parses to 0. + } + + /** + * @covers ::is_empty + */ + public function test_method_is_empty() { + + // Empty values. + $this->assertTrue( $this->field->is_empty( false ) ); + $this->assertTrue( $this->field->is_empty( 0 ) ); + $this->assertTrue( $this->field->is_empty( '0' ) ); + $this->assertTrue( $this->field->is_empty( 'No' ) ); + $this->assertTrue( $this->field->is_empty( 'Off' ) ); + $this->assertTrue( $this->field->is_empty( 'False' ) ); + + // Non empty values. + $this->assertFalse( $this->field->is_empty( true ) ); + $this->assertFalse( $this->field->is_empty( 1 ) ); + $this->assertFalse( $this->field->is_empty( '1' ) ); + $this->assertFalse( $this->field->is_empty( 'Yes' ) ); + $this->assertFalse( $this->field->is_empty( 'On' ) ); + $this->assertFalse( $this->field->is_empty( 'True' ) ); + + // Other + $this->assertTrue( $this->field->is_empty( '' ) ); // Parses to 0. + $this->assertTrue( $this->field->is_empty( 'Foobar' ) ); // Parses to 0. + } + + /** + * @covers ::is_required + */ + public function test_method_is_required() { + + // Default + $options = array(); + $this->assertFalse( $this->field->is_required( $options ) ); + + // Int value. + $options['required'] = 1; + $this->assertTrue( $this->field->is_required( $options ) ); + $options['required'] = 0; + $this->assertFalse( $this->field->is_required( $options ) ); + + // Bool value. + $options['required'] = true; + $this->assertTrue( $this->field->is_required( $options ) ); + $options['required'] = false; + $this->assertFalse( $this->field->is_required( $options ) ); + + // String values. + $options['required'] = '1'; + $this->assertTrue( $this->field->is_required( $options ) ); + $options['required'] = '0'; + $this->assertFalse( $this->field->is_required( $options ) ); + $options['required'] = 'true'; + $this->assertTrue( $this->field->is_required( $options ) ); + $options['required'] = 'false'; + $this->assertFalse( $this->field->is_required( $options ) ); + $options['required'] = 'yes'; + $this->assertTrue( $this->field->is_required( $options ) ); + $options['required'] = 'no'; + $this->assertFalse( $this->field->is_required( $options ) ); + } + + /** + * @covers ::pre_save + */ + public function test_method_pre_save_exists() { + $this->assertTrue( method_exists( $this->field, 'pre_save' ), 'Method ::pre_save does not exist.' ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_1() { + $this->assertEquals( 1, $this->field->pre_save( 1 ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_yes() { + $this->assertEquals( 1, $this->field->pre_save( 'yes' ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_capitalized_yes() { + $this->assertEquals( 1, $this->field->pre_save( 'Yes' ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_0() { + $this->assertEquals( 0, $this->field->pre_save( 0 ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_no() { + $this->assertEquals( 0, $this->field->pre_save( 'no' ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_captialized_no() { + $this->assertEquals( 0, $this->field->pre_save( 'No' ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_foo_no_label_match() { + $this->assertEquals( 0, $this->field->pre_save( 'foo' ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_foo_matches_yes_label() { + $this->assertEquals( 1, $this->field->pre_save( 'foo', null, null, array( 'boolean_yes_label' => 'foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_capitalized_foo_matches_yes_label() { + $this->assertEquals( 1, $this->field->pre_save( 'Foo', null, null, array( 'boolean_yes_label' => 'foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_foo_matches_capitalized_yes_label() { + $this->assertEquals( 1, $this->field->pre_save( 'foo', null, null, array( 'boolean_yes_label' => 'Foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_capitalized_foo_matches_capitalized_yes_label() { + $this->assertEquals( 1, $this->field->pre_save( 'Foo', null, null, array( 'boolean_yes_label' => 'Foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_foo_matches_no_label() { + $this->assertEquals( 0, $this->field->pre_save( 'foo', null, null, array( 'boolean_no_label' => 'foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_capitalized_foo_matches_no_label() { + $this->assertEquals( 0, $this->field->pre_save( 'Foo', null, null, array( 'boolean_no_label' => 'foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_foo_matches_capitalized_no_label() { + $this->assertEquals( 0, $this->field->pre_save( 'foo', null, null, array( 'boolean_no_label' => 'Foo' ) ) ); + } + + /** + * @covers ::pre_save + * @depends test_method_pre_save_exists + */ + public function test_method_pre_save_value_capitalized_foo_matches_capitalized_no_label() { + $this->assertEquals( 0, $this->field->pre_save( 'Foo', null, null, array( 'boolean_no_label' => 'Foo' ) ) ); + } + + /** + * @covers ::ui + */ + public function test_method_ui_exists() { + $this->assertTrue( method_exists( $this->field, 'ui' ), 'Method ::ui does not exist.' ); + } + + /** + * @covers ::ui + * @depends test_method_ui_exists + */ + public function test_method_ui_defaults_to_no() { + $this->assertEquals( 'No', $this->field->ui( 'foo', 'bar' ) ); + } + + /** + * @covers ::ui + * @depends test_method_ui_exists + */ + public function test_method_ui_default_no_label() { + $this->assertEquals( 'No', $this->field->ui( 'foo', 0 ) ); + } + + /** + * @covers ::ui + * @depends test_method_ui_exists + */ + public function test_method_ui_default_yes_label() { + $this->assertEquals( 'Yes', $this->field->ui( 'foo', 1 ) ); + } + + /** + * @covers ::ui + * @depends test_method_ui_exists + */ + public function test_method_ui_custom_yes_label() { + $this->assertEquals( 'Bar', $this->field->ui( 'foo', 1, null, array( 'boolean_yes_label' => 'Bar' ) ) ); + } + + /** + * @covers ::ui + * @depends test_method_ui_exists + */ + public function test_method_ui_custom_no_label() { + $this->assertEquals( 'Bar', $this->field->ui( 'foo', 0, null, array( 'boolean_no_label' => 'Bar' ) ) ); + } +} diff --git a/tests/codeception/wpunit/Pods/Field/PodsField_CurrencyTest.php b/tests/codeception/wpunit/Pods/Field/PodsField_CurrencyTest.php new file mode 100644 index 0000000000..e26d5ba56f --- /dev/null +++ b/tests/codeception/wpunit/Pods/Field/PodsField_CurrencyTest.php @@ -0,0 +1,430 @@ + 'number', + 'currency_format_sign' => 'usd', + 'currency_format_placement' => 'before', + 'currency_format' => '9,999.99', + 'currency_decimals' => 2, + 'currency_decimal_handling' => 'default', + ]; + + public function setUp(): void { + $this->field = new PodsField_Currency(); + + parent::setUp(); + } + + public function tearDown(): void { + unset( $this->field ); + + parent::tearDown(); + } + + /** + * @dataProvider formatDefaultsProvider + */ + public function test_format_defaults( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); + } + + public function formatDefaultsProvider() { + return [ + [ '-1', '-1.00' ], + [ '0', '0.00' ], + [ '1', '1.00' ], + [ '1.', '1.00' ], + [ '1.5', '1.50' ], + [ '10', '10.00' ], + [ '10.01', '10.01' ], + [ '100', '100.00' ], + [ '1000', '1,000.00' ], + [ '10000', '10,000.00' ], + [ '1000000', '1,000,000.00' ], + ]; + } + + /** + * @dataProvider formatDecimalCommaProvider + */ + public function test_format_decimal_comma( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format'] = '9.999,99'; + + $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); + } + + public function formatDecimalCommaProvider() { + return [ + [ '-1', '-1,00' ], + [ '0', '0,00' ], + [ '1', '1,00' ], + [ '1.', '1,00' ], + [ '1.5', '1,50' ], + [ '10', '10,00' ], + [ '10.01', '10,01' ], + [ '100', '100,00' ], + [ '1000', '1.000,00' ], + [ '10000', '10.000,00' ], + [ '1000000', '1.000.000,00' ], + ]; + } + + /** + * @dataProvider formatThousandsQuoteProvider + */ + public function test_format_thousands_quote( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format'] = '9\'999.99'; + + $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); + } + + public function formatThousandsQuoteProvider() { + return [ + [ '1000', '1\'000.00' ], + [ '10000', '10\'000.00' ], + [ '1000000', '1\'000\'000.00' ], + ]; + } + + /** + * @dataProvider formatSpaceCommaProvider + */ + public function test_format_space_comma( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format'] = '9 999,99'; + + $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); + } + + public function formatSpaceCommaProvider() { + return [ + [ '1000', '1 000,00' ], + [ '10000', '10 000,00' ], + [ '1000000', '1 000 000,00' ], + ]; + } + + /** + * @dataProvider formatDecimalDashProvider + * @covers ::trim_decimals + */ + public function test_format_decimal_dash( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_decimal_handling'] = 'dash'; + + $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); + } + + public function formatDecimalDashProvider() { + return [ + [ '-1', '-1.-' ], + [ '0', '0.-' ], + [ '1', '1.-' ], + [ '1.', '1.-' ], + [ '1.5', '1.50' ], + [ '10', '10.-' ], + [ '10.01', '10.01' ], + [ '100', '100.-' ], + [ '1000', '1,000.-' ], + [ '10000', '10,000.-' ], + [ '1000000', '1,000,000.-' ], + ]; + } + + /** + * @dataProvider displayDefaultProvider + */ + public function test_display_default( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayDefaultProvider() { + return [ + [ '-1', '$-1.00' ], + [ '0', '$0.00' ], + [ '1', '$1.00' ], + [ '1.', '$1.00' ], + [ '1.5', '$1.50' ], + [ '10', '$10.00' ], + [ '10.01', '$10.01' ], + [ '100', '$100.00' ], + [ '1000', '$1,000.00' ], + [ '10000', '$10,000.00' ], + [ '1000000', '$1,000,000.00' ], + ]; + } + + /** + * @dataProvider displayFormatCurrencyAfterProvider + */ + public function test_display_format_currency_after( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format_placement'] = 'after'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayFormatCurrencyAfterProvider() { + return [ + [ '-1', '-1.00$' ], + [ '0', '0.00$' ], + [ '1', '1.00$' ], + [ '1.', '1.00$' ], + [ '1.5', '1.50$' ], + [ '10', '10.00$' ], + [ '10.01', '10.01$' ], + [ '100', '100.00$' ], + [ '1000', '1,000.00$' ], + [ '10000', '10,000.00$' ], + [ '1000000', '1,000,000.00$' ], + ]; + } + + /** + * @dataProvider displayFormatCurrencyAfterSpaceProvider + */ + public function test_display_format_currency_after_space( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format_placement'] = 'after_space'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayFormatCurrencyAfterSpaceProvider() { + return [ + [ '-1', '-1.00 $' ], + [ '0', '0.00 $' ], + [ '1', '1.00 $' ], + [ '1.', '1.00 $' ], + [ '1.5', '1.50 $' ], + [ '10', '10.00 $' ], + [ '10.01', '10.01 $' ], + [ '100', '100.00 $' ], + [ '1000', '1,000.00 $' ], + [ '10000', '10,000.00 $' ], + [ '1000000', '1,000,000.00 $' ], + ]; + } + + /** + * @dataProvider saveDefaultsProvider + */ + public function test_save_defaults( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveDefaultsProvider() { + return [ + [ '-1.00', '-1.00' ], + [ '0.00', '0.00' ], + [ '1', '1.00' ], + [ '1.00', '1.00' ], + [ '1.0000', '1.00' ], + [ '1.50', '1.50' ], + [ '10.00', '10.00' ], + [ '10.01', '10.01' ], + [ '100.00', '100.00' ], + [ '1,000.00', '1000.00' ], + [ '10,000.00', '10000.00' ], + [ '1,000,000.00', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatDecimalCommaProvider + */ + public function test_save_format_decimal_comma( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format'] = '9.999,99'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatDecimalCommaProvider() { + return [ + [ '-1,00', '-1.00' ], + [ '0,00', '0.00' ], + [ '1', '1.00' ], + [ '1,', '1.00' ], + [ '1,00', '1.00' ], + [ '1,0000', '1.00' ], + [ '1,50', '1.50' ], + [ '10,00', '10.00' ], + [ '10,01', '10.01' ], + [ '100,00', '100.00' ], + [ '1.000,00', '1000.00' ], + [ '10.000,00', '10000.00' ], + [ '1.000.000,00', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatThousandsQuoteProvider + */ + public function test_save_format_thousands_quote( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format'] = '9\'999.99'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatThousandsQuoteProvider() { + return [ + [ '1\'000.00', '1000.00' ], + [ '10\'000.00', '10000.00' ], + [ '1\'000\'000.00', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatSpaceCommaProvider + */ + public function test_save_format_space_comma_formats( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format'] = '9 999,99'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatSpaceCommaProvider() { + return [ + [ '1 000,00', '1000.00' ], + [ '10 000,00', '10000.00' ], + [ '1 000 000,00', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatDecimalDashProvider + */ + public function test_save_format_decimal_dash( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_decimal_handling'] = 'dash'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatDecimalDashProvider() { + return [ + [ '-1.-', '-1.00' ], + [ '0.-', '0.00' ], + [ '1', '1.00' ], + [ '1.-', '1.00' ], + [ '1.--', '1.00' ], + [ '1.00', '1.00' ], + [ '1.0000', '1.00' ], + [ '1.50', '1.50' ], + [ '10.-', '10.00' ], + [ '10.01', '10.01' ], + [ '100.-', '100.00' ], + [ '1,000.-', '1000.00' ], + [ '10,000.-', '10000.00' ], + [ '1,000,000.-', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatCurrencyDefaultProvider + */ + public function test_save_format_defaults_currency( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatCurrencyDefaultProvider() { + return [ + [ '$-1.00', '-1.00' ], + [ '$0.00', '0.00' ], + [ '$1', '1.00' ], + [ '$1.00', '1.00' ], + [ '$1.0000', '1.00' ], + [ '$1.50', '1.50' ], + [ '$10.00', '10.00' ], + [ '$10.01', '10.01' ], + [ '$100.00', '100.00' ], + [ '$1,000.00', '1000.00' ], + [ '$10,000.00', '10000.00' ], + [ '$1,000,000.00', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatCurrencyAfterProvider + */ + public function test_save_format_currency_after( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format_placement'] = 'after'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatCurrencyAfterProvider() { + return [ + [ '-1.00$', '-1.00' ], + [ '0.00$', '0.00' ], + [ '1$', '1.00' ], + [ '1.00$', '1.00' ], + [ '1.0000$', '1.00' ], + [ '1.50$', '1.50' ], + [ '10.00$', '10.00' ], + [ '10.01$', '10.01' ], + [ '100.00$', '100.00' ], + [ '1,000.00$', '1000.00' ], + [ '10,000.00$', '10000.00' ], + [ '1,000,000.00$', '1000000.00' ], + ]; + } + + /** + * @dataProvider saveFormatCurrencyAfterSpaceProvider + */ + public function test_save_format_currency_after_space( $value, $expected ) { + $options = $this->defaultOptions; + $options['currency_format_placement'] = 'after_space'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveFormatCurrencyAfterSpaceProvider() { + return [ + [ '-1.00 $', '-1.00' ], + [ '0.00 $', '0.00' ], + [ '1 $', '1.00' ], + [ '1.00 $', '1.00' ], + [ '1.0000 $', '1.00' ], + [ '1.50 $', '1.50' ], + [ '10.00 $', '10.00' ], + [ '10.01 $', '10.01' ], + [ '100.00 $', '100.00' ], + [ '1,000.00 $', '1000.00' ], + [ '10,000.00 $', '10000.00' ], + [ '1,000,000.00 $', '1000000.00' ], + ]; + } + +} diff --git a/tests/codeception/wpunit/Pods/Field/PodsField_DateTimeTest.php b/tests/codeception/wpunit/Pods/Field/PodsField_DateTimeTest.php new file mode 100644 index 0000000000..a4fbd88731 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Field/PodsField_DateTimeTest.php @@ -0,0 +1,179 @@ + 'format', + 'datetime_format_custom' => '', + 'datetime_format_custom_js' => '', + 'datetime_format' => 'mdy', + 'datetime_time_type' => '12', + 'datetime_time_format_custom' => '', + 'datetime_time_format_custom_js' => '', + 'datetime_time_format' => 'h_mma', + 'datetime_time_format_24' => 'hh_mm', + 'datetime_allow_empty' => 1, + ]; + + public function setUp(): void { + $this->field = new PodsField_DateTime(); + + parent::setUp(); + } + + public function tearDown(): void { + unset( $this->field ); + + parent::tearDown(); + } + + /** + * @dataProvider displayDefaultProvider + */ + public function test_display_default( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayDefaultProvider() { + return [ + [ '2017-12-06', '12/06/2017 12:00am' ], + [ '2017-12-06 15:04', '12/06/2017 3:04pm' ], + [ '2017-12-06 15:04:50', '12/06/2017 3:04pm' ], + [ '2017-06-12 15:04:50', '06/12/2017 3:04pm' ], + ]; + } + + /** + * @dataProvider displayCustomFormatDMYProvider + */ + public function test_display_custom_format_dmy( $value, $expected ) { + $options = $this->defaultOptions; + + $options['datetime_type'] = 'custom'; + $options['datetime_format_custom'] = 'd/m/Y'; // Days and months switched. + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayCustomFormatDMYProvider() { + return [ + [ '2017-12-06', '06/12/2017 12:00am' ], + [ '2017-12-06 15:04', '06/12/2017 3:04pm' ], + [ '2017-12-06 15:04:50', '06/12/2017 3:04pm' ], + [ '2017-06-12 15:04:50', '12/06/2017 3:04pm' ], + ]; + } + + /** + * @dataProvider saveDefaultsProvider + */ + public function test_save_defaults( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveDefaultsProvider() { + return [ + [ '2017-12-06', '2017-12-06 00:00:00' ], + [ '2017-12-06 15:04', '2017-12-06 15:04:00' ], + [ '2017-12-06 15:04:50', '2017-12-06 15:04:50' ], + [ '2017-06-12 15:04:50', '2017-06-12 15:04:50' ], + // Display format. + [ '12/06/2017 12:00am', '2017-12-06 00:00:00' ], + [ '12/06/2017 3:04pm', '2017-12-06 15:04:00' ], + [ '06/12/2017 3:04pm', '2017-06-12 15:04:00' ], + ]; + } + + /** + * @dataProvider saveCustomFormatDMYProvider + */ + public function test_save_custom_format_dmy( $value, $expected ) { + $options = $this->defaultOptions; + + $options['datetime_type'] = 'custom'; + $options['datetime_format_custom'] = 'd/m/Y'; // Days and months switched. + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveCustomFormatDMYProvider() { + return [ + [ '2017-12-06', '2017-12-06 00:00:00' ], + [ '2017-12-06 15:04', '2017-12-06 15:04:00' ], + [ '2017-12-06 15:04:50', '2017-12-06 15:04:50' ], + [ '2017-06-12 15:04:50', '2017-06-12 15:04:50' ], + // Display format d/m/Y. + [ '12/06/2017 12:00am', '2017-06-12 00:00:00' ], + [ '12/06/2017 3:04pm', '2017-06-12 15:04:00' ], + [ '06/12/2017 3:04pm', '2017-12-06 15:04:00' ], + ]; + } + + /** + * @dataProvider validateDefaultsProvider + */ + public function test_validate_defaults( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->validate( $value, null, null, $options ) ); + } + + public function validateDefaultsProvider() { + return [ + [ '2017-12-06', true ], + [ '2017-12-06 15:04', true ], + [ '2017-12-06 15:04:50', true ], + [ '2017-06-12 15:04:50', true ], + // Display format. + [ '12/06/2017 12:00am', true ], + [ '12/06/2017 3:04pm', true ], + [ '06/12/2017 3:04pm', true ], + ]; + } + + /** + * @dataProvider validateCustomFormatDMYProvider + */ + public function test_validate_custom_format_dmy( $value, $expected ) { + $options = $this->defaultOptions; + + $options['datetime_type'] = 'custom'; + $options['datetime_format_custom'] = 'd/m/Y'; // Days and months switched. + + $this->assertEquals( $expected, $this->field->validate( $value, null, null, $options ) ); + } + + public function validateCustomFormatDMYProvider() { + return [ + [ '2017-12-06', true ], + [ '2017-12-06 15:04', true ], + [ '2017-12-06 15:04:50', true ], + [ '2017-06-12 15:04:50', true ], + // Display format. + [ '12/06/2017 12:00am', true ], + [ '12/06/2017 3:04pm', true ], + [ '06/12/2017 3:04pm', true ], + ]; + } + +} diff --git a/tests/codeception/wpunit/Pods/Field/PodsField_PhoneTest.php b/tests/codeception/wpunit/Pods/Field/PodsField_PhoneTest.php new file mode 100644 index 0000000000..6e87a9785b --- /dev/null +++ b/tests/codeception/wpunit/Pods/Field/PodsField_PhoneTest.php @@ -0,0 +1,268 @@ + '999-999-9999 x999', + 'phone_enable_phone_extension' => '0', + 'phone_max_length' => '25', + 'phone_html5' => '0', + 'phone_placeholder' => '', + ]; + + public function setUp() : void { + $this->field = new PodsField_Phone(); + + parent::setUp(); + } + + public function tearDown() : void { + unset( $this->field ); + + parent::tearDown(); + } + + /** + * @dataProvider displayDefaultProvider + */ + public function test_display_default( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayDefaultProvider() { + // Display does not reformat, formatting happens on save. + return [ + [ '123-123-1234', '123-123-1234' ], + [ '(123) 123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123.123.1234', '+1 123.123.1234' ], + [ '123-123-1234 x555', '123-123-1234 x555' ], + [ '(123) 123-1234 x555', '(123) 123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123.123.1234 x555', '+1 123.123.1234 x555' ], + ]; + } + + /** + * @dataProvider displayParenthesisProvider + */ + public function test_display_parenthesis( $value, $expected ) { + $options = $this->defaultOptions; + + $options['phone_format'] = '(999) 999-9999 x999'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayParenthesisProvider() { + // Display does not reformat, formatting happens on save. + return [ + [ '123-123-1234', '123-123-1234' ], + [ '(123) 123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123.123.1234', '+1 123.123.1234' ], + [ '123-123-1234 x555', '123-123-1234 x555' ], + [ '(123) 123-1234 x555', '(123) 123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123.123.1234 x555', '+1 123.123.1234 x555' ], + ]; + } + + /** + * @dataProvider displayDotProvider + */ + public function test_display_dot( $value, $expected ) { + $options = $this->defaultOptions; + + $options['phone_format'] = '999.999.9999 x999'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayDotProvider() { + // Display does not reformat, formatting happens on save. + return [ + [ '123-123-1234', '123-123-1234' ], + [ '(123) 123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123.123.1234', '+1 123.123.1234' ], + [ '123-123-1234 x555', '123-123-1234 x555' ], + [ '(123) 123-1234 x555', '(123) 123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123.123.1234 x555', '+1 123.123.1234 x555' ], + ]; + } + + /** + * @dataProvider displayInternationalProvider + */ + public function test_display_international( $value, $expected ) { + $options = $this->defaultOptions; + + $options['phone_format'] = 'international'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + public function displayInternationalProvider() { + // Display does not reformat, formatting happens on save. + return [ + [ '123-123-1234', '123-123-1234' ], + [ '(123) 123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123.123.1234', '+1 123.123.1234' ], + [ '123-123-1234 x555', '123-123-1234 x555' ], + [ '(123) 123-1234 x555', '(123) 123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123.123.1234 x555', '+1 123.123.1234 x555' ], + ]; + } + + /** + * @dataProvider saveDefaultsProvider + */ + public function test_save_defaults( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveDefaultsProvider() { + return [ + [ '123-123-1234', '123-123-1234' ], + [ '(123) 123-1234', '123-123-1234' ], + [ '+1 123-123-1234', '123-123-1234' ], + [ '+1 123-123-1234', '123-123-1234' ], + [ '+1 123.123.1234', '123-123-1234' ], + [ '123-123-1234 x555', '123-123-1234' ], + [ '(123) 123-1234 x555', '123-123-1234' ], + [ '+1 123-123-1234 x555', '123-123-1234' ], + [ '+1 123-123-1234 x555', '123-123-1234' ], + [ '+1 123.123.1234 x555', '123-123-1234' ], + ]; + } + + /** + * @dataProvider saveParenthesisProvider + */ + public function test_save_parenthesis( $value, $expected ) { + $options = $this->defaultOptions; + + $options['phone_format'] = '(999) 999-9999 x999'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveParenthesisProvider() { + return [ + [ '123-123-1234', '(123) 123-1234' ], + [ '(123) 123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '(123) 123-1234' ], + [ '+1 123.123.1234', '(123) 123-1234' ], + [ '123-123-1234 x555', '(123) 123-1234' ], + [ '(123) 123-1234 x555', '(123) 123-1234' ], + [ '+1 123-123-1234 x555', '(123) 123-1234' ], + [ '+1 123-123-1234 x555', '(123) 123-1234' ], + [ '+1 123.123.1234 x555', '(123) 123-1234' ], + ]; + } + + /** + * @dataProvider saveDotProvider + */ + public function test_save_dot( $value, $expected ) { + $options = $this->defaultOptions; + + $options['phone_format'] = '999.999.9999 x999'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveDotProvider() { + return [ + [ '123-123-1234', '123.123.1234' ], + [ '(123) 123-1234', '123.123.1234' ], + [ '+1 123-123-1234', '123.123.1234' ], + [ '+1 123-123-1234', '123.123.1234' ], + [ '+1 123.123.1234', '123.123.1234' ], + [ '123-123-1234 x555', '123.123.1234' ], + [ '(123) 123-1234 x555', '123.123.1234' ], + [ '+1 123-123-1234 x555', '123.123.1234' ], + [ '+1 123-123-1234 x555', '123.123.1234' ], + [ '+1 123.123.1234 x555', '123.123.1234' ], + ]; + } + + /** + * @dataProvider saveInternationalProvider + */ + public function test_save_international( $value, $expected ) { + $options = $this->defaultOptions; + + $options['phone_format'] = 'international'; + + $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); + } + + public function saveInternationalProvider() { + return [ + [ '123-123-1234', '123-123-1234' ], + [ '(123) 123-1234', '(123) 123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123-123-1234', '+1 123-123-1234' ], + [ '+1 123.123.1234', '+1 123.123.1234' ], + [ '123-123-1234 x555', '123-123-1234 x555' ], + [ '(123) 123-1234 x555', '(123) 123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123-123-1234 x555', '+1 123-123-1234 x555' ], + [ '+1 123.123.1234 x555', '+1 123.123.1234 x555' ], + ]; + } + + /** + * @dataProvider validateDefaultsProvider + */ + public function test_validate_defaults( $value, $expected ) { + $options = $this->defaultOptions; + + $this->assertEquals( $expected, $this->field->validate( $value, null, null, $options ) ); + } + + public function validateDefaultsProvider() { + return [ + [ '123-123-1234', true ], + [ '(123) 123-1234', true ], + [ '+1 123-123-1234', true ], + [ '+1 123-123-1234', true ], + [ '+1 123.123.1234', true ], + [ '123-123-1234 x555', true ], + [ '(123) 123-1234 x555', true ], + [ '+1 123-123-1234 x555', true ], + [ '+1 123-123-1234 x555', true ], + [ '+1 123.123.1234 x555', true ], + ]; + } + +} diff --git a/tests/codeception/wpunit/Pods/Field/PodsField_PickTest.php b/tests/codeception/wpunit/Pods/Field/PodsField_PickTest.php new file mode 100644 index 0000000000..2cf0b2a504 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Field/PodsField_PickTest.php @@ -0,0 +1,101 @@ + 'single', + 'pick_format_single' => 'dropdown', + 'pick_format_multi' => 'checkbox', + 'pick_display_format_multi' => 'default', + 'pick_display_format_separator' => ', ', + ]; + + public function setUp(): void { + $this->field = new PodsField_Pick(); + + parent::setUp(); + } + + public function tearDown(): void { + unset( $this->field ); + + parent::tearDown(); + } + + /** + * Single values. + */ + public function test_format_defaults() { + $options = $this->defaultOptions; + + $value = [ + 'item1', + ]; + + $expected = 'item1'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + /** + * Multiple values and display formats. + */ + public function test_display_format_multi_simple() { + $options = $this->defaultOptions; + $options['pick_format_type'] = 'multi'; + + $value = [ + 'item1', + 'item2', + 'item3', + ]; + + $expected = 'item1, item2, and item3'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + + // no_serial display format. + $options['pick_display_format_multi'] = 'non_serial'; + + $expected = 'item1, item2 and item3'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + + // custom display format. + $options['pick_display_format_multi'] = 'custom'; + + $expected = 'item1, item2, item3'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + + // custom display format separator. + $options['pick_display_format_multi'] = 'custom'; + $options['pick_display_format_separator'] = ' | '; + + $expected = 'item1 | item2 | item3'; + + $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); + } + + /** + * @todo Cover display tests with actual relationship values. + */ + public function test_display_format_multi_relationship() { + $this->markTestSkipped( 'not yet implemented' ); + } + +} diff --git a/tests/codeception/wpunit/Pods/Field/PodsField_TextTest.php b/tests/codeception/wpunit/Pods/Field/PodsField_TextTest.php new file mode 100644 index 0000000000..f2d7953f42 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Field/PodsField_TextTest.php @@ -0,0 +1,320 @@ +field = new PodsField_Text(); + } + + public function tearDown(): void { + if ( shortcode_exists( 'fooshortcode' ) ) { + remove_shortcode( 'fooshortcode' ); + } + + unset( $this->field ); + } + + /** + * @covers PodsField_Text::options + */ + public function test_method_exists_options() { + $this->assertTrue( method_exists( 'PodsField_Text', 'options' ) ); + } + + /** + * @covers PodsField_Text::options + * @depends test_method_exists_options + */ + public function test_method_options_returns_array() { + $this->assertInternalType( 'array', $this->field->options() ); + } + + /** + * @covers PodsField_Text::options + * @depends test_method_exists_options + */ + public function test_method_options_key_exists_text_repeatable() { + $this->assertArrayHasKey( 'text_repeatable', $this->field->options() ); + } + + /** + * @covers PodsField_Text::options + * @depends test_method_exists_options + */ + public function test_method_options_key_exists_output_options() { + $this->assertArrayHasKey( 'output_options', $this->field->options() ); + } + + /** + * @covers PodsField_Text::options + * @depends test_method_exists_options + */ + public function test_method_options_key_exists_text_allowed_html_tags() { + $this->assertArrayHasKey( 'text_allowed_html_tags', $this->field->options() ); + } + + /** + * @covers PodsField_Text::options + * @depends test_method_exists_options + */ + public function test_method_options_key_exists_text_max_length() { + $this->assertArrayHasKey( 'text_max_length', $this->field->options() ); + } + + /** + * @covers PodsField_Text::schema + */ + public function test_method_exists_schema() { + $this->assertTrue( method_exists( 'PodsField_Text', 'schema' ) ); + } + + /** + * @covers PodsField_Text::schema + * @depends test_method_exists_schema + */ + public function test_method_schema_returns_string() { + $this->assertInternalType( 'string', $this->field->schema() ); + } + + /** + * @covers PodsField_Text::schema + * @depends test_method_exists_schema + * @uses ::pods_v + */ + public function test_method_schema_returns_varchar_default() { + $this->assertEquals( 'VARCHAR(255)', $this->field->schema() ); + } + + /** + * @covers PodsField_Text::schema + * @depends test_method_exists_schema + * @uses ::pods_v + */ + public function test_method_schema_returns_longtext() { + $this->assertEquals( 'LONGTEXT', $this->field->schema( array( 'text_max_length' => 16777216 ) ) ); + } + + /** + * @covers PodsField_Text::display + */ + public function test_method_exists_display() { + $this->assertTrue( method_exists( 'PodsField_Text', 'display' ) ); + } + + /** + * @covers PodsField_Text::display + * @depends test_method_exists_display + * @uses PodsField_Text::strip_html + * @uses ::pods_v + */ + public function test_method_display_defaults() { + $this->assertEquals( '', $this->field->display() ); + } + + /** + * @covers PodsField_Text::display + * @depends test_method_exists_display + * @uses PodsField_Text::strip_html + * @uses ::pods_v + */ + public function test_method_display_value() { + $this->assertEquals( 'foo', $this->field->display( 'foo' ) ); + } + + /** + * @covers PodsField_Text::display + * @depends test_method_exists_display + * @uses PodsField_Text::strip_html + * @uses ::pods_v + */ + public function test_method_display_value_allow_shortcode() { + add_shortcode( 'fooshortcode', static function() { + return 'foobar'; + } ); + + $this->assertEquals( 'foobar', $this->field->display( '[fooshortcode]content not used[/fooshortcode]', 'bar', array( 'text_allow_shortcode' => 1 ) ) ); + $this->assertEquals( '', $this->field->display( '[fooshortcode]content not used[/fooshortcode]', 'bar', array( 'text_allow_shortcode' => 0 ) ) ); + $this->assertEquals( '', $this->field->display( '[fooshortcode]content not used[/fooshortcode]', 'bar' ) ); + } + + /** + * @covers PodsField_Text::pre_save + */ + public function test_method_exists_pre_save() { + $this->assertTrue( method_exists( 'PodsField_Text', 'pre_save' ), 'PodsField_Text::pre_save does not exist.' ); + } + + /** + * @covers PodsField_Text::pre_save + * @depends test_method_exists_pre_save + * @uses PodsField_Text::strip_html + * @uses ::pods_v + * @uses ::pods_mb_strlen + * @uses ::pods_mb_substr + */ + public function test_method_pre_save_defaults() { + $this->assertEquals( 'foo', $this->field->pre_save( 'foo' ) ); + } + + /** + * @covers PodsField_Text::pre_save + * @depends test_method_exists_pre_save + * @uses PodsField_Text::strip_html + * @uses ::pods_v + * @uses ::pods_mb_strlen + * @uses ::pods_mb_substr + */ + public function test_method_pre_save_truncate() { + $this->assertEquals( 'foo', $this->field->pre_save( 'foobar', null, null, array( 'text_max_length' => 3 ) ) ); + } + + /** + * @covers PodsField_Text::validate + */ + public function test_method_exists_validate() { + $this->assertTrue( method_exists( 'PodsField_Text', 'validate' ), 'PodsField_Text::validate does not exist.' ); + } + + /** + * @covers PodsField_Text::validate + * @depends test_method_exists_validate + * @uses PodsField_Text::strip_html + * @uses ::pods_v + * @uses ::pods_mb_strlen + * @uses ::pods_mb_substr + */ + public function test_method_validate() { + $this->assertTrue( $this->field->validate( 'foobar' ) ); + } + + /** + * @covers PodsField_Text::validate + * @depends test_method_exists_validate + * @uses PodsField_Text::strip_html + * @uses ::pods_v + * @uses ::pods_mb_strlen + * @uses ::pods_mb_substr + */ + public function test_method_validate_empty_value() { + $this->assertTrue( $this->field->validate( '' ) ); + } + + /** + * @covers PodsField_Text::ui + */ + public function test_method_exists_ui() { + $this->assertTrue( method_exists( 'PodsField_Text', 'ui' ), 'PodsField_Text::ui does not exist.' ); + } + + /** + * @covers PodsField_Text::ui + * @depends test_method_exists_ui + */ + public function test_method_ui() { + $this->assertEquals( 'foo', $this->field->ui( 1, 'foo' ) ); + } + + /** + * @covers PodsField_Text::strip_html + */ + public function test_method_exists_strip_html() { + $this->assertTrue( method_exists( 'PodsField_Text', 'strip_html' ), 'PodsField_Text::strip_html does not exist.' ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_array_value() { + $this->assertEquals( array( 'foo', 'bar', 'baz' ), $this->field->strip_html( array( 'foo', 'bar', 'baz' ) ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + */ + public function test_method_strip_html_empty_array_value() { + $this->assertEquals( array(), $this->field->strip_html( array() ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_defaults() { + $this->assertEquals( 'foo', $this->field->strip_html( 'foo' ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_default_options() { + $this->assertEquals( 'foo', $this->field->strip_html( '
              1. foo
            ', $this->field->options() ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_default_tags_allowed() { + $options['text_allow_html'] = 1; + $options['text_allowed_html_tags'] = 'strong em a ul ol li b i'; + + $this->assertEquals( '
              1. foo
            ', $this->field->strip_html( '
              1. foo
            ', $options ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_br_tags_allowed() { + $options['text_allow_html'] = 1; + $options['text_allowed_html_tags'] = 'br'; + + $this->assertEquals( 'foo
            ', $this->field->strip_html( 'foo
            ', $options ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_hr_tags_allowed() { + $options['text_allow_html'] = 1; + $options['text_allowed_html_tags'] = 'hr'; + + $this->assertEquals( 'foo
            ', $this->field->strip_html( 'foo
            ', $options ) ); + } + + /** + * @covers PodsField_Text::strip_html + * @depends test_method_exists_strip_html + * @uses ::pods_v + */ + public function test_method_strip_html_tags_allowed() { + $options['text_allow_html'] = 1; + $options['text_allowed_html_tags'] = 'strong em'; + + $this->assertEquals( 'foo', $this->field->strip_html( '
            foo
            ', $options ) ); + } +} diff --git a/tests/phpunit/includes/tests-media.php b/tests/codeception/wpunit/Pods/Field/tests-media.php similarity index 100% rename from tests/phpunit/includes/tests-media.php rename to tests/codeception/wpunit/Pods/Field/tests-media.php diff --git a/tests/codeception/wpunit/Pods/MappingTest.php b/tests/codeception/wpunit/Pods/MappingTest.php new file mode 100644 index 0000000000..0283ddfd55 --- /dev/null +++ b/tests/codeception/wpunit/Pods/MappingTest.php @@ -0,0 +1,288 @@ + $this->pod_name, + 'label' => $this->pod_label, + 'type' => $this->pod_type, + 'storage' => $this->pod_storage, + ]; + + $api = pods_api(); + + // Save Pod similar to PodsAdmin. + $this->pod_id = $api->save_pod( $params ); + + $field_params = [ + 'pod_id' => $this->pod_id, + 'name' => $this->field_name, + 'label' => $this->field_label, + 'type' => $this->field_type, + ]; + + $this->field_id = $api->save_field( $field_params ); + + $pod = pods( $this->pod_name ); + + $this->item_id = $pod->add( [ + 'post_title' => 'Test title', + 'post_content' => 'Test content', + 'post_status' => 'publish', + ] ); + } + + public function tearDown() : void { + $api = pods_api(); + + // Delete all posts. + $api->reset_pod( [ 'name' => $this->pod_name ] ); + + // Delete the pod config. + $api->delete_pod( [ 'name' => $this->pod_name ] ); + + parent::tearDown(); + } + + /** + * @covers \Pods\Data\Map_Field_Values::map_value + */ + public function test_default() { + $pod = pods( $this->pod_name, $this->item_id ); + + $this->assertEquals( [], $pod->field( 'any_map' ) ); + } + + /** + * @covers \Pods\Data\Map_Field_Values::custom + */ + public function test_custom() { + add_filter( 'pods_data_map_field_values_custom', '__return_zero' ); + + $pod = pods( $this->pod_name, $this->item_id ); + + $this->assertEquals( 0, $pod->field( 'any_map' ) ); + + remove_filter( 'pods_data_map_field_values_custom', '__return_zero' ); + } + + /** + * @covers \Pods\Data\Map_Field_Values::pod_info + */ + public function test_pod_info() { + $pod = pods( $this->pod_name, $this->item_id ); + + $this->assertEquals( $this->pod_name, $pod->field( '_pod' ) ); + + $this->assertEquals( $this->pod_id, $pod->field( '_pod.id' ) ); + $this->assertEquals( $this->pod_id, $pod->field( '_pod.ID' ) ); + $this->assertEquals( $this->pod_name, $pod->field( '_pod.name' ) ); + $this->assertEquals( $this->pod_label, $pod->field( '_pod.label' ) ); + $this->assertEquals( $this->pod_type, $pod->field( '_pod.type' ) ); + $this->assertEquals( $this->pod_storage, $pod->field( '_pod.storage' ) ); + + $this->assertEquals( '', $pod->field( '_pod.any_non_option' ) ); + } + + /** + * @covers \Pods\Data\Map_Field_Values::field_info + */ + public function test_field_info() { + $pod = pods( $this->pod_name, $this->item_id ); + + $this->assertEquals( $this->field_label, $pod->field( '_field.' . $this->field_name ) ); + + $this->assertEquals( $this->field_id, $pod->field( '_field.' . $this->field_name . '.id' ) ); + $this->assertEquals( $this->field_id, $pod->field( '_field.' . $this->field_name . '.ID' ) ); + $this->assertEquals( $this->field_name, $pod->field( '_field.' . $this->field_name . '.name' ) ); + $this->assertEquals( $this->field_label, $pod->field( '_field.' . $this->field_name . '.label' ) ); + $this->assertEquals( $this->field_type, $pod->field( '_field.' . $this->field_name . '.type' ) ); + + $this->assertEquals( '', $pod->field( '_field.' . $this->field_name . '.any_non_option' ) ); + } + + /** + * @covers \Pods\Data\Map_Field_Values::context_info + */ + public function test_context_info() { + $pod = pods( $this->pod_name, $this->item_id ); + + // Test $_GET. + $_GET['some-value'] = '123'; + + $this->assertEquals( $_GET['some-value'], $pod->field( '_context.get.some-value' ) ); + + // Test $_POST. + $_POST['some-value2'] = '456'; + + $this->assertEquals( $_POST['some-value2'], $pod->field( '_context.post.some-value2' ) ); + + // Test removal of HTML in value. + $_POST['some-value3'] = 'Go somewhere'; + + $this->assertEquals( 'Go somewhere', $pod->field( '_context.post.some-value3' ) ); + + // Test HTML in raw value. + $_POST['some-value3'] = 'Go somewhere'; + + $this->assertEquals( $_POST['some-value3'], $pod->field( '_context.post.some-value3.raw' ) ); + + // Test prefix. + global $wpdb; + + $this->assertEquals( $wpdb->prefix, $pod->field( '_context.prefix' ) ); + } + + /** + * @covers \Pods\Data\Map_Field_Values::calculation + */ + public function test_calculation() { + $pod = pods( $this->pod_name ); + + // Add 4 more tests so we have 5 total. + $pod->add( [ + 'post_title' => 'Test title 2', + 'post_name' => 'test-title-2', + 'post_content' => 'Test content', + 'post_status' => 'publish', + ] ); + + $pod->add( [ + 'post_title' => 'Test title 3', + 'post_name' => 'test-title-3', + 'post_content' => 'Test content', + 'post_status' => 'publish', + ] ); + + $pod->add( [ + 'post_title' => 'Test title 4', + 'post_name' => 'test-title-4', + 'post_content' => 'Test content', + 'post_status' => 'publish', + ] ); + + $pod->add( [ + 'post_title' => 'Test title 5', + 'post_name' => 'test-title-5', + 'post_content' => 'Test content', + 'post_status' => 'publish', + ] ); + + $pod->find( [ + // Limit to 2 and expect 3 pages. + 'limit' => 2, + ] ); + + // Defaults prior to loop. + $zebra = true; + $position = 0; + + $this->assertEquals( (int) $zebra, $pod->zebra() ); + $this->assertEquals( $position, $pod->position() ); + $this->assertEquals( 2, $pod->total() ); + $this->assertEquals( 5, $pod->total_found() ); + $this->assertEquals( 3, $pod->total_pages() ); + + while ( $pod->fetch() ) { + $position ++; + $zebra = ! $zebra; + + $this->assertEquals( (int) $zebra, $pod->field( '_zebra' ) ); + $this->assertEquals( $position, $pod->field( '_position' ) ); + $this->assertEquals( 2, $pod->field( '_total' ) ); + $this->assertEquals( 5, $pod->field( '_total_found' ) ); + $this->assertEquals( 3, $pod->field( '_total_pages' ) ); + } + } + + /** + * @covers \Pods\Data\Map_Field_Values::image_fields + */ + public function test_image_fields_post_thumbnail() { + $image_path = codecept_data_dir( 'images/zoltar.jpg' ); + + $attachment_id = $this->factory()->attachment->create_upload_object( $image_path, $this->item_id ); + + set_post_thumbnail( $this->item_id, $attachment_id ); + + $pod = pods( $this->pod_name, $this->item_id ); + + $this->assertStringStartsWith( 'factory()->attachment->create(); + $image_ids[] = $this->factory()->attachment->create(); + $image_ids[] = $this->factory()->attachment->create(); + + $this->pod->save( [ + 'ID' => $main_id, + 'images' => $image_ids, + ] ); + + $content = base64_encode( '/{@_src}/' ); + $compare = ''; + foreach ( $image_ids as $img ) { + $compare .= '/' . pods_image_url( $img, 'medium' ) . '/'; + } + + // Should return all image links. + $this->assertEquals( $compare, do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='images']{$content}[/pod_sub_template]" ) ); + + // Use media object for Pod related fields. + $content = base64_encode( '/{@title}/' ); + $compare = ''; + foreach ( $image_ids as $img ) { + $compare .= '/' . get_the_title( $img ) . '/'; + } + + // Should still return all image links. + $this->assertEquals( $compare, do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='images']{$content}[/pod_sub_template]" ) ); + } + + /** + * + */ + public function test_each_with_nested_if() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + $sub_ids = []; + + for ( $x = 1; $x <= 5; $x ++ ) { + $sub_ids[] = $this->pod->add( [ + 'post_status' => 'publish', + 'name' => $x, + 'number1' => $x, + 'number2' => $x * $x, + ] ); + } + + $main_id = $this->pod->add( [ + 'post_status' => 'publish', + 'name' => 'main post', + 'number1' => 123, + 'number2' => 456, + 'related_field' => $sub_ids, + ] ); + + $content = base64_encode( '[if number1]/{@number1}_{@number2}/[/if]' ); + + $this->assertEquals( '/1_1//2_4//3_9//4_16//5_25/', do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_sub_template]" ) ); + + // Testing [each] inside [if] + $inner_content = base64_encode( '[if number1]/{@number1}_{@number2}/[/if]' ); + $content = base64_encode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$inner_content}[/pod_sub_template]" ); + + $this->assertEquals( '/1_1//2_4//3_9//4_16//5_25/', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_if_field]" ) ); + + // Testing [each] inside [if] with [else] + $inner_content = base64_encode( '[if number1]/{@number1}_{@number2}/[/if]' ); + $content = base64_encode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$inner_content}[/pod_sub_template][else]No related field" ); + + $this->assertEquals( '/1_1//2_4//3_9//4_16//5_25/', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_if_field]" ) ); + + // Testing [each] inside [if] with [else] and no relationships + $main_id = $this->pod->add( [ + 'post_status' => 'publish', + 'name' => 'post with no related fields', + 'number1' => 123, + 'number2' => 456, + ] ); + + $inner_content = base64_encode( '[if number1]/{@number1}_{@number2}/[/if]' ); + $content = base64_encode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$inner_content}[/pod_sub_template][else]No related field" ); + + $this->assertEquals( 'No related field', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_if_field]" ) ); + } + + /** + * + */ + public function test_each_nested_in_external() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + $sub_ids = []; + + for ( $x = 1; $x <= 5; $x ++ ) { + $sub_ids[] = $this->pod->add( [ + 'post_status' => 'publish', + 'name' => $x, + 'number1' => $x, + 'number2' => $x * $x, + ] ); + } + + $main_id = $this->pod->add( [ + 'post_status' => 'publish', + 'name' => 'main post', + 'number1' => 123, + 'number2' => 456, + 'related_field' => $sub_ids, + ] ); + + $content = base64_encode( '/{@number1}_{@number2}/' ); + + $this->assertEquals( '/1_1//2_4//3_9//4_16//5_25/', do_shortcode( "[test_each_recurse][pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_sub_template][/test_each_recurse]" ) ); + } +} diff --git a/tests/codeception/wpunit/Pods/Shortcode/IfTest.php b/tests/codeception/wpunit/Pods/Shortcode/IfTest.php new file mode 100644 index 0000000000..0dd37bab8c --- /dev/null +++ b/tests/codeception/wpunit/Pods/Shortcode/IfTest.php @@ -0,0 +1,916 @@ +pod_id = $api->save_pod( array( + 'type' => 'post_type', + 'name' => $this->pod_name, + ) ); + + $params = array( + 'pod_id' => $this->pod_id, + 'name' => 'number1', + 'type' => 'number', + ); + + $api->save_field( $params ); + + $params = array( + 'pod_id' => $this->pod_id, + 'name' => 'number2', + 'type' => 'number', + ); + + $api->save_field( $params ); + + $params = array( + 'pod_id' => $this->pod_id, + 'name' => 'related_field', + 'type' => 'pick', + 'pick_object' => 'post_type', + 'pick_val' => $this->pod_name, + 'pick_format_type' => 'single', + ); + + $api->save_field( $params ); + + $this->pod = pods( $this->pod_name ); + } + + /** + * + */ + public function tearDown(): void { + if ( shortcode_exists( 'test_if_text' ) ) { + remove_shortcode( 'test_if_text' ); + } + if ( shortcode_exists( 'test_if_recurse' ) ) { + remove_shortcode( 'test_if_recurse' ); + } + + $this->pod_id = null; + $this->pod = null; + + parent::tearDown(); + } + + /** + * Render the template and handle shortcode. + * + * @param string $template + * + * @return string The rendered template. + */ + private function render_template( $template ) { + return trim( $this->pod->template( null, $template ) ); + } + + /** + * + */ + public function test_psuedo_shortcodes() { + // Make sure our pseudo shortcodes are working properly + $this->assertEquals( 'abc123', do_shortcode( '[test_if_text]' ) ); + $this->assertEquals( 'abc123', do_shortcode( '[test_if_recurse][test_if_text][/test_if_recurse]' ) ); + } + + /** + * + */ + public function test_if_simple() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + $template = ' + [if number1] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if number1] + ABC + [else] + DEF + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if invalid_field] + ABC + [else] + DEF + [/if] + '; + + $this->assertEquals( 'DEF', $this->render_template( $template ) ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '2', + 'number1' => 456, + 'number2' => 0, + ) ); + + $this->pod->fetch( $id ); + + $template = ' + [if number2] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_equals() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + $template = ' + [if number1="123"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if number1="123"] + ABC + [else] + DEF + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if invalid_field="123"] + ABC + [else] + DEF + [/if] + '; + + $this->assertEquals( 'DEF', $this->render_template( $template ) ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '2', + 'number1' => 123, + 'number2' => 0, + ) ); + + $this->pod->fetch( $id ); + + $template = ' + [if number2="456"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_not_supported() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test a comparison operator that is not supported. + */ + + $template = ' + [if field="number1" value="123" compare="not supported comparison operator"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_equals() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test === comparison. + */ + + $template = ' + [if field="number1" value="123"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="123" compare="="] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="124" compare="="] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_not_equals() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test !== comparison. + */ + + $template = ' + [if field="number1" value="124" compare="!="] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="123" compare="!="] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_lt() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test < comparison. + */ + + $template = ' + [if field="number1" value="124" compare="<"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="123" compare="<"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_lt_or_equals() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test <= comparison. + */ + + $template = ' + [if field="number1" value="124" compare="<="] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="123" compare="<="] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="122" compare="<="] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_gt() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test > comparison. + */ + + $template = ' + [if field="number1" value="122" compare=">"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="123" compare=">"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_gt_or_equals() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test >= comparison. + */ + + $template = ' + [if field="number1" value="122" compare=">="] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="123" compare=">="] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" value="124" compare=">="] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_like() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test LIKE comparison. + */ + + $template = ' + [if field="post_title" value="if_compare" compare="like"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="if_compare" compare="LIKE"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="if_compare_like_not_how_it_is" compare="LIKE"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_like_wildcard() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test LIKE comparison. + */ + + $template = ' + [if field="post_title" value="%if_compare%" compare="like"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="%if_compare%" compare="LIKE"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="%if_compare" compare="LIKE"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="%if_compare_like_not_how_it_is%" compare="LIKE"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_not_like() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test NOT LIKE comparison. + */ + + $template = ' + [if field="post_title" value="if_compare_something_else" compare="not like"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="if_compare_something_else" compare="NOT LIKE"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="if_compare_not_like" compare="NOT LIKE"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_not_like_wildcard() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test NOT LIKE comparison. + */ + + $template = ' + [if field="post_title" value="%if_compare_something_else%" compare="not like"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="%if_compare_something_else%" compare="NOT LIKE"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="%if_compare_something_else" compare="NOT LIKE"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="post_title" value="%if_compare_not_like_wildcard%" compare="NOT LIKE"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_exists() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 0, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test EXISTS comparison. + */ + + $template = ' + [if field="number1" compare="exists"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number2" compare="EXISTS"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="invalid_field" compare="EXISTS"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_compare_not_exists() { + $this->assertNotFalse( $this->pod ); + + $id = $this->pod->add( array( + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 0, + ) ); + + $this->pod->fetch( $id ); + + /** + * Test NOT EXISTS comparison. + */ + + $template = ' + [if field="invalid_field" compare="not exists"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="invalid_field" compare="NOT EXISTS"] + ABC + [/if] + '; + + $this->assertEquals( 'ABC', $this->render_template( $template ) ); + + $template = ' + [if field="number1" compare="NOT EXISTS"] + ABC + [/if] + '; + + $this->assertNotEquals( 'ABC', $this->render_template( $template ) ); + } + + /** + * + */ + public function test_if_nested() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + $id = $this->pod->add( [ + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ] ); + + $inner_content = base64_encode( 'XYZ' ); + $content = base64_encode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$inner_content}[/pod_if_field]" ); + + $this->assertEquals( 'XYZ', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); + + $inner_content = base64_encode( 'XYZ' ); + $content = base64_encode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$inner_content}[/pod_if_field]" ); + + $this->assertEquals( 'XYZ', do_shortcode( "[test_if_recurse][pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field][/test_if_recurse]" ) ); + + //$this->markTestSkipped( 'Nested shortcodes currently broken, test disabled until issue resolved' ); + + return; + + $inner_content = base64_encode( '[test_if_recurse]XYZ[/test_if_recurse]' ); + $content = base64_encode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$inner_content}[/pod_if_field]" ); + + $this->assertEquals( 'XYZ', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); + } + + /** + * + */ + public function _test_if_nested_external_shortcodes() { + $this->assertNotFalse( $this->pod ); + + $this->markTestSkipped( 'Nested shortcodes currently broken, test disabled until issue resolved' ); + + $pod_name = $this->pod_name; + + $id = $this->pod->add( [ + 'post_title' => __FUNCTION__ . '1', + 'number1' => 123, + 'number2' => 456, + ] ); + + $content = base64_encode( '[test_if_text][else]INVALID' ); + + $this->assertEquals( 'abc123', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); + } + + /** + * + */ + public function test_if_with_magic_tags() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + $id = $this->pod->add( [ + 'post_title' => 'my post title', + 'number1' => 123, + 'number2' => 456, + ] ); + + $content = base64_encode( '{@post_title}' ); + $this->assertEquals( 'my post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); + + $content = base64_encode( '{@number1}' ); + $this->assertEquals( '123', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); + + $id = $this->pod->add( [ + 'post_title' => 'my post title', + 'number1' => 456, + 'number2' => 0, + ] ); + + $content = base64_encode( '{@number2}[else]{@number1}' ); + $this->assertEquals( '456', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$content}[/pod_if_field]" ) ); + } + + /** + * + */ + public function test_if_in_html() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + $id = $this->pod->add( [ + 'post_title' => 'my post title', + 'number1' => 123, + 'number2' => 456, + ] ); + $content = base64_encode( '{@number1}[else]{@number2}' ); + // This isn't supposed to be perfect HTML, just good enough for the test + $this->assertEquals( '', do_shortcode( "" ) ); + } + + /** + * @group bug-4403 + */ + public function test_if_related_field() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + $id1 = $this->pod->add( [ + 'post_status' => 'publish', + 'post_title' => 'first post title', + 'number1' => 123, + 'number2' => 456, + ] ); + $id2 = $this->pod->add( [ + 'post_status' => 'publish', + 'post_title' => 'second post title', + 'number1' => 987, + 'number2' => 654, + 'related_field' => $id1, + ] ); + + // Not exactly related to the shortcode test but lets make sure we can at least retrieve the proper data + $this->assertEquals( '123', pods( $pod_name, $id2 )->field( 'related_field.number1' ) ); + + $content = base64_encode( '{@related_field.post_title}' ); + $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id2}' field='related_field']{$content}[/pod_if_field]" ) ); + + $content = base64_encode( '{@related_field.post_title}' ); + + $site_url = site_url(); + + $valid = [ + 'first post title', + 'first post title', + 'first post title', + ]; + + $this->assertContains( do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id2}' field='related_field']{$content}[/pod_if_field]" ), $valid ); + + $this->assertEquals( 'first post title', do_shortcode( "[pods name='{$pod_name}' id='{$id2}'][if related_field]{@related_field.post_title}[/if][/pods]" ) ); + } +} diff --git a/tests/codeception/wpunit/Pods/Shortcode/PodsTest.php b/tests/codeception/wpunit/Pods/Shortcode/PodsTest.php new file mode 100644 index 0000000000..04368bb344 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Shortcode/PodsTest.php @@ -0,0 +1,149 @@ +pod_id = $api->save_pod( array( + 'type' => 'pod', + 'name' => $this->pod_name, + ) ); + + $params = array( + 'pod_id' => $this->pod_id, + 'name' => 'number1', + 'type' => 'number', + ); + + $api->save_field( $params ); + + $this->pod = pods( $this->pod_name ); + } + + /** + * + */ + public function tearDown(): void { + $this->pod_id = null; + $this->pod = null; + + parent::tearDown(); + } + + /** + * + */ + public function test_shortcode_pods() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + // add an item + $this->pod->add( array( + 'name' => 'Tatooine', + 'number1' => 5, + ) ); + + // test shortcode + $this->assertEquals( '5', do_shortcode( '[pods name="' . $pod_name . '" where="t.number1=5"]{@number1}[/pods]' ) ); + + // add another item + $this->pod->add( array( + 'name' => 'Alderaan', + 'number1' => 7, + ) ); + + // test shortcode + $this->assertEquals( '5', do_shortcode( '[pods name="' . $pod_name . '" where="t.number1=5"]{@number1}[/pods]' ) ); + + // add third item + $this->pod->add( array( + 'name' => 'Hoth', + 'number1' => 5, + ) ); + + // test shortcode + $this->assertEquals( '55', do_shortcode( '[pods name="' . $pod_name . '" where="t.number1=5"]{@number1}[/pods]' ) ); + + // Test the pagination parameter + /** @see http://php.net/manual/en/filter.filters.validate.php FILTER_VALIDATE_BOOLEAN */ + $this->assertContains( 'assertContains( 'assertContains( 'assertContains( 'assertContains( 'assertContains( 'assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="0" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="false" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="off" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="no" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="0" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="false" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="-1" limit="2"]~[/pods]' ) ); + $this->assertEquals( '~~', do_shortcode( '[pods name="' . $pod_name . '" pagination="xyzzy" limit="2"]~[/pods]' ) ); + + // Not enough records to trigger pagination even if on + $this->assertNotContains( 'assertEquals( '57', do_shortcode( '[pods name="' . $pod_name . '" page="1" limit="2"]{@number1}[/pods]' ) ); + $this->assertEquals( '5', do_shortcode( '[pods name="' . $pod_name . '" page="2" limit="2"]{@number1}[/pods]' ) ); + } + + /** + * PR 2339 + * + * @link https://github.com/pods-framework/pods/pull/2339 + * @since 2.8.0 + */ + public function test_shortcode_pods_field_in_shortcode() { + $this->assertNotFalse( $this->pod ); + + $pod_name = $this->pod_name; + + // add an item + $this->pod->add( array( + 'name' => 'Dagobah', + 'number1' => 5, + ) ); + + $this->pod->find( array( 'where' => 't.number1=5' ) ); + + // test shortcode + $this->assertEquals( '5', do_shortcode( '[pods name="' . $pod_name . '" where="t.number1=5" field="number1"]' ) ); + } + +} diff --git a/tests/codeception/wpunit/Pods/Whatsit/Storage/Post_TypeTest.php b/tests/codeception/wpunit/Pods/Whatsit/Storage/Post_TypeTest.php new file mode 100644 index 0000000000..e913c4cbd8 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Whatsit/Storage/Post_TypeTest.php @@ -0,0 +1,659 @@ +pods_object_storage->fallback_mode( true ); + + parent::tearDown(); + } + + /** + * @covers Post_Type::get_storage_type + */ + public function test_get_storage_type() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'get_storage_type' ), 'Method get_storage_type does not exist' ); + + $this->assertEquals( 'post_type', $this->pods_object_storage->get_storage_type() ); + } + + /** + * @covers Post_Type::get + */ + public function test_get() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'get' ), 'Method get does not exist' ); + + $this->assertNull( $this->pods_object_storage->get() ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $this->assertCount( 0, $this->pods_object_storage->find() ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_object_type() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'fallback_mode' => false, + 'object_type' => 'pod', + 'refresh' => true, + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $this->setup_pods_object(); + + $this->assertCount( 2, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_secondary() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_field->get_parent(), + 'type' => $this->pods_object_field->get_arg( 'type' ), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_pod->get_object_type(), + 'object' => $this->pods_object_pod->get_arg( 'object' ), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_field->get_parent(), + 'group' => $this->pods_object_field->get_arg( 'group' ), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_args() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_field->get_parent(), + 'args' => [ + 'custom1' => $this->pods_object_field->get_arg( 'custom1' ), + ], + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_field->get_parent(), + 'args' => [ + 'custom1' => 'something-else', + ], + ]; + + $this->assertCount( 0, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_field->get_parent(), + 'args' => [ + 'custom1' => '', + ], + ]; + + $this->assertCount( 0, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_field->get_parent(), + 'args' => [ + 'custom2' => null, + ], + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_id() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'id' => $this->pods_object_field->get_id(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_group->get_object_type(), + 'id' => $this->pods_object_group->get_id(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_pod->get_object_type(), + 'id' => $this->pods_object_pod->get_id(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_name() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'name' => $this->pods_object_field->get_name(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_group->get_object_type(), + 'name' => $this->pods_object_group->get_name(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_pod->get_object_type(), + 'name' => $this->pods_object_pod->get_name(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_parent() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'object_type' => $this->pods_object_field->get_object_type(), + 'parent' => $this->pods_object_pod->get_id(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_group->get_object_type(), + 'parent' => $this->pods_object_pod->get_id(), + ]; + + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => $this->pods_object_pod->get_object_type(), + ]; + + // Post type + Collection (_pods_pod, _pods_group, _pods_field, _pods_template, _pods_page, plus an additional) + $this->assertCount( 6, $this->pods_object_storage->find( $args ) ); + + $this->pods_object_storage->fallback_mode( false ); + + // Post type only + $this->assertCount( 1, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_status() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $args = [ + 'object_type' => 'pod', + 'status' => 'draft', + ]; + + $this->assertCount( 0, $this->pods_object_storage->find( $args ) ); + + $args = [ + 'object_type' => 'pod', + 'status' => 'publish', + ]; + + // Post type + Collection (_pods_pod, _pods_group, _pods_field, _pods_template, _pods_page, plus an additional) + $this->assertCount( 6, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_order() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + // Add test pods. + $args = [ + 'object_type' => 'pod', + 'name' => 'fiver', + 'label' => 'Fiver', + 'type' => 'custom', + 'fourohfour' => 405, + ]; + + $this->setup_pods_object( $args ); + + $args2 = [ + 'object_type' => 'pod', + 'name' => 'sixer', + 'label' => 'Sixer', + 'type' => 'custom', + 'fourohfour' => 405, + ]; + + $this->setup_pods_object( $args2 ); + + // Do find. + $find_args = [ + 'object_type' => 'pod', + 'type' => 'custom', + 'order' => 'ASC', + ]; + + $objects = $this->pods_object_storage->find( $find_args ); + + $this->assertCount( 2, $objects ); + $this->assertEquals( [ 'fiver' => 'fiver', 'sixer' => 'sixer' ], wp_list_pluck( $objects, 'name' ) ); + + // Do find. + $find_args = [ + 'object_type' => 'pod', + 'type' => 'custom', + 'order' => 'DESC', + ]; + + $objects = $this->pods_object_storage->find( $find_args ); + + $this->assertCount( 2, $objects ); + $this->assertEquals( [ 'sixer' => 'sixer', 'fiver' => 'fiver' ], wp_list_pluck( $objects, 'name' ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_orderby() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + // Add test pods. + $args = [ + 'object_type' => 'pod', + 'name' => 'sixer', + 'label' => 'Sixer', + 'type' => 'custom', + 'fourohfour' => 405, + ]; + + $this->setup_pods_object( $args ); + + $args2 = [ + 'object_type' => 'pod', + 'name' => 'fiver', + 'label' => 'Fiver', + 'type' => 'custom', + 'fourohfour' => 405, + ]; + + $this->setup_pods_object( $args2 ); + + // Do find. + $find_args = [ + 'object_type' => 'pod', + 'type' => 'custom', + 'orderby' => 'title', + 'order' => 'ASC', + ]; + + $objects = $this->pods_object_storage->find( $find_args ); + + $this->assertCount( 2, $objects ); + $this->assertEquals( [ 'fiver' => 'fiver', 'sixer' => 'sixer' ], wp_list_pluck( $objects, 'name' ) ); + + // Do find. + $find_args = [ + 'object_type' => 'pod', + 'type' => 'custom', + 'orderby' => 'title', + 'order' => 'DESC', + ]; + + $objects = $this->pods_object_storage->find( $find_args ); + + $this->assertCount( 2, $objects ); + $this->assertEquals( [ 'sixer' => 'sixer', 'fiver' => 'fiver' ], wp_list_pluck( $objects, 'name' ) ); + } + + /** + * @covers Post_Type::find + * @covers Collection::find + */ + public function test_find_limit() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + // Add test pods. + $args = [ + 'object_type' => 'pod', + 'name' => 'fiver', + 'label' => 'Fiver', + 'type' => 'custom', + 'fourohfour' => 405, + ]; + + $this->setup_pods_object( $args ); + + $args2 = [ + 'object_type' => 'pod', + 'name' => 'sixer', + 'label' => 'Sixer', + 'type' => 'custom', + 'fourohfour' => 405, + ]; + + $this->setup_pods_object( $args2 ); + + $args = [ + 'object_type' => 'pod', + 'limit' => 2, + ]; + + $this->assertCount( 2, $this->pods_object_storage->find( $args ) ); + } + + /** + * @covers Post_Type::add + * @covers Post_Type::add_object + * @covers Collection::add + * @covers Collection::add_object + */ + public function test_add() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'add' ), 'Method add does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + ]; + + $object = $this->setup_pods_object( $args ); + + $id = $object->get_id(); + + $post = get_post( $id ); + + $this->assertInternalType( 'integer', $id ); + $this->assertInstanceOf( WP_Post::class, $post ); + $this->assertEquals( $id, $object->get_id() ); + $this->assertEquals( $object->get_label(), $post->post_title ); + $this->assertEquals( $object->get_name(), $post->post_name ); + $this->assertEquals( $object->get_parent(), $post->post_parent ); + $this->assertEquals( $object->get_parent_id(), $post->post_parent ); + $this->assertEquals( '_pods_field', $post->post_type ); + $this->assertEquals( 'post_type', $object->get_storage_type() ); + $this->assertEquals( $object->get_arg( 'group' ), get_post_meta( $id, 'group', true ) ); + $this->assertEquals( $object->get_arg( 'fourohfour' ), get_post_meta( $id, 'fourohfour', true ) ); + $this->assertEquals( $object->get_arg( 'custom1' ), get_post_meta( $id, 'custom1', true ) ); + $this->assertCount( 3, get_post_meta( $id ) ); + } + + /** + * @covers Post_Type::save + * @covers Post_Type::save_object + * @covers Collection::save + * @covers Collection::save_object + */ + public function test_save() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'save' ), 'Method save does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + ]; + + $object = $this->setup_pods_object( $args ); + + $object->set_arg( 'label', 'New label' ); + + $id = $this->pods_object_storage->save( $object ); + + $post = get_post( $id ); + + $this->assertInternalType( 'integer', $id ); + $this->assertInstanceOf( WP_Post::class, $post ); + $this->assertEquals( $id, $object->get_id() ); + $this->assertEquals( $object->get_label(), $post->post_title ); + $this->assertEquals( $object->get_name(), $post->post_name ); + $this->assertEquals( $object->get_parent(), $post->post_parent ); + $this->assertEquals( $object->get_parent_id(), $post->post_parent ); + $this->assertEquals( '_pods_' . $object->get_object_type(), $post->post_type ); + $this->assertEquals( 'post_type', $object->get_storage_type() ); + $this->assertEquals( $object->get_arg( 'group' ), get_post_meta( $id, 'group', true ) ); + $this->assertEquals( $object->get_arg( 'fourohfour' ), get_post_meta( $id, 'fourohfour', true ) ); + $this->assertEquals( $object->get_arg( 'custom1' ), get_post_meta( $id, 'custom1', true ) ); + $this->assertCount( 3, get_post_meta( $id ) ); + } + + /** + * @covers Post_Type::get_args + * @covers Collection::get_args + */ + public function test_get_args() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'get_args' ), 'Method get_args does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + 'custom2' => 'value2', + ]; + + $object = $this->setup_pods_object( $args ); + + $id = $object->get_id(); + + // Set an empty field. + update_post_meta( $id, 'custom3', '' ); + + // Set a multiple value field. + add_post_meta( $id, 'custom4', 'value1' ); + add_post_meta( $id, 'custom4', 'value2' ); + add_post_meta( $id, 'custom4', 'value3' ); + add_post_meta( $id, 'custom4', 'value4' ); + + $args = $this->pods_object_storage->get_args( $object ); + + $this->assertEquals( $object->get_arg( 'group' ), $args['group'] ); + $this->assertEquals( $object->get_arg( 'fourohfour' ), $args['fourohfour'] ); + $this->assertEquals( $object->get_arg( 'custom1' ), $args['custom1'] ); + $this->assertEquals( $object->get_arg( 'custom2' ), $args['custom2'] ); + $this->assertArrayNotHasKey( 'custom3', $args ); + $this->assertCount( 4, $args['custom4'] ); + } + + /** + * @covers Post_Type::save_args + * @covers Collection::save_args + */ + public function test_save_args() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'save_args' ), 'Method save_args does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + 'custom2' => 'value2', + ]; + + $object = $this->setup_pods_object( $args ); + + $id = $object->get_id(); + + $this->assertTrue( $this->pods_object_storage->save_args( $object ) ); + $this->assertEquals( $object->get_arg( 'group' ), get_post_meta( $id, 'group', true ) ); + $this->assertEquals( $object->get_arg( 'fourohfour' ), get_post_meta( $id, 'fourohfour', true ) ); + $this->assertEquals( $object->get_arg( 'custom1' ), get_post_meta( $id, 'custom1', true ) ); + $this->assertEquals( $object->get_arg( 'custom2' ), get_post_meta( $id, 'custom2', true ) ); + $this->assertCount( 4, get_post_meta( $id ) ); + } + + /** + * @covers Post_Type::duplicate + * @covers Post_Type::add + * @covers Post_Type::add_object + * @covers Collection::duplicate + * @covers Collection::add + * @covers Collection::add_object + */ + public function test_duplicate() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'duplicate' ), 'Method duplicate does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + ]; + + $object = $this->setup_pods_object( $args ); + + $id = $this->pods_object_storage->duplicate( $object ); + + $post = get_post( $id ); + + $duplicated_object = $this->pods_object_storage->to_object( $post ); + + $this->assertInternalType( 'integer', $id ); + $this->assertInstanceOf( WP_Post::class, $post ); + $this->assertEquals( $id, $duplicated_object->get_id() ); + $this->assertEquals( $duplicated_object->get_label(), $post->post_title ); + $this->assertEquals( $duplicated_object->get_name(), $post->post_name ); + $this->assertEquals( $duplicated_object->get_parent(), $post->post_parent ); + $this->assertEquals( $duplicated_object->get_parent_id(), $post->post_parent ); + $this->assertEquals( '_pods_field', $post->post_type ); + $this->assertEquals( 'post_type', $duplicated_object->get_storage_type() ); + $this->assertEquals( $duplicated_object->get_arg( 'group' ), get_post_meta( $id, 'group', true ) ); + $this->assertEquals( $duplicated_object->get_arg( 'fourohfour' ), get_post_meta( $id, 'fourohfour', true ) ); + $this->assertEquals( $duplicated_object->get_arg( 'custom1' ), get_post_meta( $id, 'custom1', true ) ); + } + + /** + * @covers Post_Type::delete + * @covers Collection::delete + */ + public function test_delete() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'delete' ), 'Method delete does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + ]; + + $object = $this->setup_pods_object( $args ); + + $id = $object->get_id(); + + $this->assertEquals( $id, $object->get_id() ); + $this->assertTrue( $this->pods_object_storage->delete( $object ) ); + $this->assertNull( $object->get_id() ); + } + + /** + * @covers Post_Type::reset + * @covers Collection::reset + */ + public function test_reset() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'reset' ), 'Method reset does not exist' ); + + $args = [ + 'object_type' => 'field', + 'name' => 'fiver', + 'parent' => $this->pods_object_pod->get_id(), + 'group' => $this->pods_object_group->get_id(), + 'fourohfour' => 405, + ]; + + $object = $this->setup_pods_object( $args ); + + $this->assertFalse( $this->pods_object_storage->reset( $object ) ); + } + + /** + * @covers Post_Type::to_object + */ + public function test_to_object() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'to_object' ), 'Method to_object does not exist' ); + + $post = get_post( $this->pods_object_field->get_id() ); + + $to = $this->pods_object_storage->to_object( $post ); + + $this->assertInstanceOf( Whatsit::class, $to ); + $this->assertEquals( $this->pods_object_field->get_object_type(), $to->get_object_type() ); + $this->assertEquals( $this->pods_object_field->get_id(), $to->get_id() ); + $this->assertEquals( $this->pods_object_field->get_name(), $to->get_name() ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to->get_parent() ); + $this->assertEquals( $this->pods_object_field->get_group(), $to->get_group() ); + } + +} diff --git a/tests/codeception/wpunit/Pods/Whatsit/StorageTest.php b/tests/codeception/wpunit/Pods/Whatsit/StorageTest.php new file mode 100644 index 0000000000..462497c262 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Whatsit/StorageTest.php @@ -0,0 +1,148 @@ +pods_object_storage = $this->getMockBuilder( Storage::class )->getMockForAbstractClass(); + } + + public function tearDown(): void { + unset( $this->pods_object_storage ); + } + + /** + * Setup and return a Whatsit. + * + * @param array $args Object arguments. + * + * @return Whatsit + */ + public function setup_pods_object( array $args = array() ) { + $defaults = array( + 'id' => 123, + 'name' => 'test', + 'label' => 'Test', + 'description' => 'Testing', + 'parent' => '', + 'group' => '', + ); + + $this->args = array_merge( $defaults, $args ); + + /** @var Whatsit $object */ + $object = $this->getMockBuilder( Whatsit::class )->getMockForAbstractClass(); + $object->setup( $this->args ); + + return $object; + } + + /** + * @covers Storage::get_storage_type + */ + public function test_get_storage_type() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'get_storage_type' ), 'Method get_storage_type does not exist' ); + + $this->assertEquals( '', $this->pods_object_storage->get_storage_type() ); + } + + /** + * @covers Storage::get + */ + public function test_get() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'get' ), 'Method get does not exist' ); + + $this->assertNull( $this->pods_object_storage->get() ); + } + + /** + * @covers Storage::find + */ + public function test_find() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'find' ), 'Method find does not exist' ); + + $this->assertEquals( array(), $this->pods_object_storage->find() ); + } + + /** + * @covers Storage::add + */ + public function test_add() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'add' ), 'Method add does not exist' ); + + $object = $this->setup_pods_object(); + + $this->assertFalse( $this->pods_object_storage->add( $object ) ); + } + + /** + * @covers Storage::save + */ + public function test_save() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'save' ), 'Method save does not exist' ); + + $object = $this->setup_pods_object(); + + $this->assertFalse( $this->pods_object_storage->save( $object ) ); + } + + /** + * @covers Storage::save_args + */ + public function test_save_args() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'save_args' ), 'Method save_args does not exist' ); + + $object = $this->setup_pods_object(); + + $this->assertFalse( $this->pods_object_storage->save_args( $object ) ); + } + + /** + * @covers Storage::duplicate + */ + public function test_duplicate() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'duplicate' ), 'Method duplicate does not exist' ); + + $object = $this->setup_pods_object(); + + $this->assertFalse( $this->pods_object_storage->duplicate( $object ) ); + } + + /** + * @covers Storage::delete + */ + public function test_delete() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'delete' ), 'Method delete does not exist' ); + + $object = $this->setup_pods_object(); + + $this->assertFalse( $this->pods_object_storage->delete( $object ) ); + } + + /** + * @covers Storage::reset + */ + public function test_reset() { + $this->assertTrue( method_exists( $this->pods_object_storage, 'reset' ), 'Method reset does not exist' ); + + $object = $this->setup_pods_object(); + + $this->assertFalse( $this->pods_object_storage->reset( $object ) ); + } + +} diff --git a/tests/codeception/wpunit/Pods/Whatsit/StoreTest.php b/tests/codeception/wpunit/Pods/Whatsit/StoreTest.php new file mode 100644 index 0000000000..3df4758e51 --- /dev/null +++ b/tests/codeception/wpunit/Pods/Whatsit/StoreTest.php @@ -0,0 +1,492 @@ +pods_object_collection = Store::get_instance(); + } + + public function tearDown(): void { + Store::destroy(); + } + + /** + * Setup and return a Whatsit. + * + * @param array $args Object arguments. + * + * @return Whatsit + */ + public function setup_pods_object( array $args = array() ) { + $defaults = array( + 'object_type' => 'object', // For test reference. + 'id' => 123, + 'name' => 'test', + 'label' => 'Test', + 'description' => 'Testing', + 'parent' => '', + 'group' => '', + ); + + $this->args = array_merge( $defaults, $args ); + + /** @var Whatsit $object */ + $object = $this->getMockBuilder( Whatsit::class )->getMockForAbstractClass(); + $object->setup( $this->args ); + + return $object; + } + + /** + * @covers Store::get_instance + */ + public function test_get_instance() { + $this->assertTrue( method_exists( Store::class, 'get_instance' ), 'Method get_instance does not exist' ); + + $this->assertInstanceOf( Store::class, Store::get_instance() ); + } + + /** + * @covers Store::destroy + */ + public function test_destroy() { + $this->assertTrue( method_exists( Store::class, 'destroy' ), 'Method destroy does not exist' ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $object = $this->setup_pods_object( array( 'object_type' => 'custom' ) ); + + $this->pods_object_collection->register_object( $object ); + + $this->assertCount( 10, $this->pods_object_collection->get_object_types() ); + $this->assertCount( 3, $this->pods_object_collection->get_storage_types() ); + $this->assertCount( 6, $this->pods_object_collection->get_objects() ); + + Store::destroy(); + + $this->pods_object_collection = Store::get_instance(); + + $this->assertCount( 9, $this->pods_object_collection->get_object_types() ); + $this->assertCount( 2, $this->pods_object_collection->get_storage_types() ); + $this->assertCount( 5, $this->pods_object_collection->get_objects() ); + } + + /** + * @covers Store::register_object_type + * @covers Store::get_object_types + */ + public function test_register_object_type() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'register_object_type' ), 'Method register_object_type does not exist' ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + + $this->assertCount( 10, $this->pods_object_collection->get_object_types() ); + } + + /** + * @covers Store::unregister_object_type + * @covers Store::register_object_type + * @covers Store::get_object_types + */ + public function test_unregister_object_type() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'unregister_object_type' ), 'Method unregister_object_type does not exist' ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + + $this->assertCount( 10, $this->pods_object_collection->get_object_types() ); + + $this->assertTrue( $this->pods_object_collection->unregister_object_type( 'custom' ) ); + + $this->assertCount( 9, $this->pods_object_collection->get_object_types() ); + + $this->assertFalse( $this->pods_object_collection->unregister_object_type( 'nope' ) ); + } + + /** + * @covers Store::flush_object_types + * @covers Store::register_object_type + * @covers Store::get_object_types + */ + public function test_flush_object_types() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'flush_object_types' ), 'Method flush_object_types does not exist' ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + + $this->assertCount( 10, $this->pods_object_collection->get_object_types() ); + + $this->pods_object_collection->flush_object_types(); + + $this->assertCount( 9, $this->pods_object_collection->get_object_types() ); + } + + /** + * @covers Store::get_object_types + * @covers Store::register_object_type + */ + public function test_get_object_types() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_object_types' ), 'Method get_object_types does not exist' ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + + $this->assertCount( 10, $this->pods_object_collection->get_object_types() ); + } + + /** + * @covers Store::get_object_type + * @covers Store::register_object_type + */ + public function test_get_object_type() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_object_type' ), 'Method get_object_type does not exist' ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + + $this->assertEquals( Whatsit__Custom::class, $this->pods_object_collection->get_object_type( 'custom' ) ); + } + + /** + * @covers Store::register_storage_type + * @covers Store::get_storage_types + */ + public function test_register_storage_type() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'register_storage_type' ), 'Method register_storage_type does not exist' ); + + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $this->assertCount( 3, $this->pods_object_collection->get_storage_types() ); + } + + /** + * @covers Store::unregister_storage_type + * @covers Store::register_storage_type + * @covers Store::get_storage_types + */ + public function test_unregister_storage_type() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'unregister_storage_type' ), 'Method unregister_storage_type does not exist' ); + + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $this->assertCount( 3, $this->pods_object_collection->get_storage_types() ); + + $this->assertTrue( $this->pods_object_collection->unregister_storage_type( 'custom' ) ); + + $this->assertCount( 2, $this->pods_object_collection->get_storage_types() ); + + $this->assertFalse( $this->pods_object_collection->unregister_storage_type( 'nope' ) ); + } + + /** + * @covers Store::flush_storage_types + * @covers Store::register_storage_type + * @covers Store::get_storage_types + */ + public function test_flush_storage_types() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'flush_storage_types' ), 'Method flush_storage_types does not exist' ); + + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $this->assertCount( 3, $this->pods_object_collection->get_storage_types() ); + + $this->pods_object_collection->flush_storage_types(); + + $this->assertCount( 2, $this->pods_object_collection->get_storage_types() ); + } + + /** + * @covers Store::get_storage_types + * @covers Store::register_storage_type + */ + public function test_get_storage_types() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_storage_types' ), 'Method get_storage_types does not exist' ); + + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $this->assertCount( 3, $this->pods_object_collection->get_storage_types() ); + } + + /** + * @covers Store::get_storage_type + * @covers Store::register_storage_type + */ + public function test_get_storage_type() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_storage_type' ), 'Method get_storage_type does not exist' ); + + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $this->assertEquals( Whatsit__Storage__Custom::class, $this->pods_object_collection->get_storage_type( 'custom' ) ); + } + + /** + * @covers Store::get_storage_object + * @covers Store::register_storage_type + */ + public function test_get_storage_object() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_storage_object' ), 'Method get_storage_object does not exist' ); + + $this->pods_object_collection->register_storage_type( 'custom', Whatsit__Storage__Custom::class ); + + $this->assertInstanceOf( Whatsit__Storage__Custom::class, $this->pods_object_collection->get_storage_object( 'custom' ) ); + } + + /** + * @covers Store::register_object + * @covers Store::get_objects + */ + public function test_register_object() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'register_object' ), 'Method register_object does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $this->assertCount( 6, $this->pods_object_collection->get_objects() ); + } + + /** + * @covers Store::unregister_object + * @covers Store::register_object + * @covers Store::get_objects + */ + public function test_unregister_object() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'unregister_object' ), 'Method unregister_object does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $this->assertCount( 6, $this->pods_object_collection->get_objects() ); + + $this->assertTrue( $this->pods_object_collection->unregister_object( $object ) ); + + $objects = $this->pods_object_collection->get_objects(); + + $this->assertCount( 5, $objects ); + + // Setup another object that is not registered. + $args = array( + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + ); + + $object2 = $this->setup_pods_object( $args ); + + $this->assertFalse( $this->pods_object_collection->unregister_object( $object2 ) ); + } + + /** + * @covers Store::flush_objects + * @covers Store::register_object + * @covers Store::get_objects + */ + public function test_flush_objects() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'flush_objects' ), 'Method flush_objects does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $args = array( + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + ); + + $object2 = $this->setup_pods_object( $args ); + + $this->pods_object_collection->register_object( $object2 ); + + $this->assertCount( 7, $this->pods_object_collection->get_objects() ); + + $this->pods_object_collection->flush_objects(); + + $this->assertCount( 5, $this->pods_object_collection->get_objects() ); + } + + /** + * @covers Store::delete_objects + * @covers Store::flush_objects + * @covers Store::register_object + * @covers Store::get_objects + */ + public function test_delete_objects() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'delete_objects' ), 'Method delete_objects does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $args = array( + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + ); + + $object2 = $this->setup_pods_object( $args ); + + $this->pods_object_collection->register_object( $object2 ); + + $this->assertCount( 7, $this->pods_object_collection->get_objects() ); + + $this->pods_object_collection->delete_objects(); + + $this->assertCount( 5, $this->pods_object_collection->get_objects() ); + } + + /** + * @covers Store::get_objects + * @covers Store::register_object + */ + public function test_get_objects() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_objects' ), 'Method get_objects does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $args = array( + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + ); + + $object2 = $this->setup_pods_object( $args ); + + $this->pods_object_collection->register_object( $object2 ); + + $objects = $this->pods_object_collection->get_objects(); + + $this->assertCount( 7, $objects ); + + $this->assertEquals( $object, $objects[ $object->get_identifier() ] ); + $this->assertEquals( $object2, $objects[ $object2->get_identifier() ] ); + } + + /** + * @covers Store::get_object + * @covers Store::register_object + */ + public function test_get_object() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_object' ), 'Method get_object does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $this->assertEquals( $object, $this->pods_object_collection->get_object( $object->get_identifier() ) ); + $this->assertEquals( $object, $this->pods_object_collection->get_object( $object->get_id() ) ); + } + + /** + * @covers Store::register_object + * @covers Store::get_object + */ + public function test_messy_object() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'get_object' ), 'Method get_object does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $object->set_arg( 'something', 'anotherthing' ); + + $this->assertNotEquals( $object, $this->pods_object_collection->get_object( $object->get_identifier() ) ); + } + + /** + * @covers Store::get_object + * @covers Store::register_object_type + * @covers Store::register_object + * @covers Store::get_objects + */ + public function test_array_object() { + $args = array( + 'object_type' => 'custom', + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + $this->pods_object_collection->register_object( $args ); + + $this->assertCount( 6, $this->pods_object_collection->get_objects() ); + + $identifier = Whatsit::get_identifier_from_args( $args ); + + $this->assertInstanceOf( Whatsit__Custom::class, $this->pods_object_collection->get_object( 555 ) ); + $this->assertInstanceOf( Whatsit__Custom::class, $this->pods_object_collection->get_object( $identifier ) ); + } + + /** + * @covers Store::setup_object + * @covers Store::register_object_type + * @covers Store::register_object + */ + public function test_setup_object() { + $this->assertTrue( method_exists( $this->pods_object_collection, 'setup_object' ), 'Method setup_object does not exist' ); + + $object = $this->setup_pods_object(); + + $this->pods_object_collection->register_object( $object ); + + $args = array( + 'object_type' => 'custom', + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + ); + + $identifier = Whatsit::get_identifier_from_args( $args ); + + $this->pods_object_collection->register_object_type( 'custom', Whatsit__Custom::class ); + $this->pods_object_collection->register_object( $args ); + + $this->assertEquals( $object, $this->pods_object_collection->get_object( $object->get_identifier() ) ); + $this->assertEquals( $object, $this->pods_object_collection->get_object( $object->get_id() ) ); + + $this->assertInstanceOf( Whatsit__Custom::class, $this->pods_object_collection->get_object( 555 ) ); + $this->assertInstanceOf( Whatsit__Custom::class, $this->pods_object_collection->get_object( $identifier ) ); + } + +} diff --git a/tests/codeception/wpunit/Pods/WhatsitTest.php b/tests/codeception/wpunit/Pods/WhatsitTest.php new file mode 100644 index 0000000000..7e0f0a4ac3 --- /dev/null +++ b/tests/codeception/wpunit/Pods/WhatsitTest.php @@ -0,0 +1,885 @@ +assertTrue( method_exists( $this->pods_object_field, '__sleep' ), 'Method __sleep does not exist' ); + + $serialized = serialize( $this->pods_object_field ); + + $class_name = get_class( $this->pods_object_field ); + + // Convert serialized object to array for testing against. + $serialized_pattern = sprintf( 'O:%d:"%s":', strlen( $class_name ), $class_name ); + + $serialized = str_replace( $serialized_pattern, 'a:', $serialized ); + $serialized = str_replace( "s:7:\"\0*\0args\"", 's:4:"args"', $serialized ); + + $to = unserialize( $serialized ); + + $this->assertInternalType( 'array', $to ); + $this->assertArrayHasKey( 'args', $to ); + $this->assertInternalType( 'array', $to['args'] ); + + $to = $to['args']; + + $this->assertEquals( $this->pods_object_field->get_args(), $to ); + $this->assertEquals( $this->pods_object_field->get_id(), $to['id'] ); + $this->assertEquals( $this->pods_object_field->get_name(), $to['name'] ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to['parent'] ); + $this->assertEquals( $this->pods_object_field->get_group(), $to['group'] ); + } + + /** + * @covers Whatsit::jsonSerialize + */ + public function test_json() { + $this->assertTrue( method_exists( $this->pods_object_field, 'jsonSerialize' ), 'Method jsonSerialize does not exist' ); + + $json = json_encode( $this->pods_object_field ); + + $to = json_decode( $json, true ); + + $this->assertInternalType( 'array', $to ); + $this->assertEquals( $this->pods_object_field->get_args(), $to ); + $this->assertEquals( $this->pods_object_field->get_id(), $to['id'] ); + $this->assertEquals( $this->pods_object_field->get_name(), $to['name'] ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to['parent'] ); + $this->assertEquals( $this->pods_object_field->get_group(), $to['group'] ); + } + + /** + * @covers Whatsit::__toString + */ + public function test_string() { + $this->assertTrue( method_exists( $this->pods_object_field, '__toString' ), 'Method __toString does not exist' ); + + $to = (string) $this->pods_object_field; + + $this->assertInternalType( 'string', $to ); + $this->assertEquals( $this->pods_object_field->get_identifier(), $to ); + } + + /** + * @covers Whatsit::from_serialized + */ + public function test_from_serialized() { + $this->assertTrue( method_exists( $this->pods_object_field, 'from_serialized' ), 'Method from_serialized does not exist' ); + + $serialized = serialize( $this->pods_object_field ); + + $to = $this->pods_object_field->from_serialized( $serialized ); + + $this->assertInstanceOf( Whatsit::class, $to ); + $this->assertEquals( $this->pods_object_field->get_object_type(), $to->get_object_type() ); + $this->assertEquals( $this->pods_object_field->get_id(), $to->get_id() ); + $this->assertEquals( $this->pods_object_field->get_name(), $to->get_name() ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to->get_parent() ); + $this->assertEquals( $this->pods_object_field->get_group(), $to->get_group() ); + } + + /** + * @covers Whatsit::from_serialized + */ + public function test_from_serialized_args() { + $this->assertTrue( method_exists( $this->pods_object_field, 'from_serialized' ), 'Method from_serialized does not exist' ); + + $serialized = serialize( $this->pods_object_field ); + + $to = $this->pods_object_field->from_serialized( $serialized, true ); + + $this->assertInternalType( 'array', $to ); + $this->assertEquals( $this->pods_object_field->get_args(), $to ); + $this->assertEquals( $this->pods_object_field->get_id(), $to['id'] ); + $this->assertEquals( $this->pods_object_field->get_name(), $to['name'] ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to['parent'] ); + $this->assertEquals( $this->pods_object_field->get_group(), $to['group'] ); + } + + /** + * @covers Whatsit::from_json + */ + public function test_from_json() { + $this->assertTrue( method_exists( $this->pods_object_field, 'from_json' ), 'Method from_json does not exist' ); + + $json = json_encode( $this->pods_object_field ); + + $to = $this->pods_object_field->from_json( $json ); + + $this->assertInstanceOf( Whatsit::class, $to ); + $this->assertEquals( $this->pods_object_field->get_object_type(), $to->get_object_type() ); + $this->assertEquals( $this->pods_object_field->get_id(), $to->get_id() ); + $this->assertEquals( $this->pods_object_field->get_name(), $to->get_name() ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to->get_parent() ); + $this->assertEquals( $this->pods_object_field->get_group(), $to->get_group() ); + } + + /** + * @covers Whatsit::from_json + */ + public function test_from_json_args() { + $this->assertTrue( method_exists( $this->pods_object_field, 'from_json' ), 'Method from_json does not exist' ); + + $json = json_encode( $this->pods_object_field ); + + $to = $this->pods_object_field->from_json( $json, true ); + + $this->assertInternalType( 'array', $to ); + $this->assertEquals( $this->pods_object_field->get_args(), $to ); + $this->assertEquals( $this->pods_object_field->get_id(), $to['id'] ); + $this->assertEquals( $this->pods_object_field->get_name(), $to['name'] ); + $this->assertEquals( $this->pods_object_field->get_parent(), $to['parent'] ); + $this->assertEquals( $this->pods_object_field->get_group(), $to['group'] ); + } + + /** + * @covers Whatsit::offsetExists + * @covers Whatsit::offsetGet + * @covers Whatsit::offsetSet + * @covers Whatsit::offsetUnset + * @covers Whatsit::get_arg + * @covers Whatsit::set_arg + */ + public function test_array_access_pod() { + // Confirm methods exist. + $this->assertTrue( method_exists( $this->pods_object_pod, 'offsetExists' ), 'Method offsetExists does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_pod, 'offsetGet' ), 'Method offsetGet does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_pod, 'offsetSet' ), 'Method offsetSet does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_pod, 'offsetUnset' ), 'Method offsetUnset does not exist' ); + + // Confirm argument get matches ArrayAccess. + $this->assertEquals( $this->pods_object_pod->get_id(), $this->pods_object_pod['id'] ); + $this->assertEquals( $this->pods_object_pod->get_name(), $this->pods_object_pod['name'] ); + $this->assertEquals( $this->pods_object_pod->get_parent(), $this->pods_object_pod['parent'] ); + $this->assertEquals( $this->pods_object_pod->get_group(), $this->pods_object_pod['group'] ); + $this->assertEquals( $this->pods_object_pod->get_fields(), $this->pods_object_pod['fields'] ); + $this->assertEquals( $this->pods_object_pod->get_object_fields(), $this->pods_object_pod['object_fields'] ); + $this->assertEquals( $this->pods_object_pod->get_all_fields(), $this->pods_object_pod['all_fields'] ); + $this->assertEquals( $this->pods_object_pod->get_groups(), $this->pods_object_pod['groups'] ); + $this->assertEquals( $this->pods_object_pod->get_table_info(), $this->pods_object_pod['table_info'] ); + $this->assertEquals( $this->pods_object_pod->get_args(), $this->pods_object_pod['options'] ); + + // Confirm argument get matches Object __get. + $this->assertEquals( $this->pods_object_pod->get_id(), $this->pods_object_pod->id ); + $this->assertEquals( $this->pods_object_pod->get_name(), $this->pods_object_pod->name ); + $this->assertEquals( $this->pods_object_pod->get_parent(), $this->pods_object_pod->parent ); + $this->assertEquals( $this->pods_object_pod->get_group(), $this->pods_object_pod->group ); + $this->assertEquals( $this->pods_object_pod->get_fields(), $this->pods_object_pod->fields ); + $this->assertEquals( $this->pods_object_pod->get_object_fields(), $this->pods_object_pod->object_fields ); + $this->assertEquals( $this->pods_object_pod->get_all_fields(), $this->pods_object_pod->all_fields ); + $this->assertEquals( $this->pods_object_pod->get_groups(), $this->pods_object_pod->groups ); + $this->assertEquals( $this->pods_object_pod->get_table_info(), $this->pods_object_pod->table_info ); + $this->assertEquals( $this->pods_object_pod->get_args(), $this->pods_object_pod->options ); + + $list = array( $this->pods_object_pod ); + + $this->assertEquals( array( $this->pods_object_pod->get_id() ), wp_list_pluck( $list, 'id' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_name() ), wp_list_pluck( $list, 'name' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_parent() ), wp_list_pluck( $list, 'parent' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_group() ), wp_list_pluck( $list, 'group' ) ); + $this->assertEquals( array( $this->pods_object_pod->get_arg( 'custom1' ) ), wp_list_pluck( $list, 'custom1' ) ); + + // Test non-existent arguments and handling for ArrayAccess. + $this->assertNull( $this->pods_object_pod->get_arg( 'fourohfour' ) ); + $this->assertEquals( $this->pods_object_pod->get_arg( 'fourohfour' ), $this->pods_object_pod['fourohfour'] ); + $this->assertFalse( isset( $this->pods_object_pod['fourohfour'] ) ); + + // Test isset for ArrayAccess. + $this->assertTrue( isset( $this->pods_object_pod['id'] ) ); + $this->assertTrue( isset( $this->pods_object_pod['name'] ) ); + $this->assertTrue( isset( $this->pods_object_pod['parent'] ) ); + $this->assertTrue( isset( $this->pods_object_pod['group'] ) ); + + // Test unset handling for ArrayAccess served arguments. + unset( $this->pods_object_pod['id'], $this->pods_object_pod['name'], $this->pods_object_pod['parent'], $this->pods_object_pod['group'] ); + + // Confirm ArrayAccess arguments are now empty strings for reserved arguments. + $this->assertEquals( $this->pods_object_pod['id'], '' ); + $this->assertEquals( $this->pods_object_pod['name'], '' ); + $this->assertEquals( $this->pods_object_pod['parent'], '' ); + $this->assertEquals( $this->pods_object_pod['group'], '' ); + } + + /** + * @covers Whatsit::offsetExists + * @covers Whatsit::offsetGet + * @covers Whatsit::offsetSet + * @covers Whatsit::offsetUnset + * @covers Whatsit::get_arg + * @covers Whatsit::set_arg + */ + public function test_array_access_group() { + // Confirm methods exist. + $this->assertTrue( method_exists( $this->pods_object_group, 'offsetExists' ), 'Method offsetExists does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_group, 'offsetGet' ), 'Method offsetGet does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_group, 'offsetSet' ), 'Method offsetSet does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_group, 'offsetUnset' ), 'Method offsetUnset does not exist' ); + + // Confirm argument get matches ArrayAccess. + $this->assertEquals( $this->pods_object_group->get_id(), $this->pods_object_group['id'] ); + $this->assertEquals( $this->pods_object_group->get_name(), $this->pods_object_group['name'] ); + $this->assertEquals( $this->pods_object_group->get_parent(), $this->pods_object_group['parent'] ); + $this->assertEquals( $this->pods_object_group->get_group(), $this->pods_object_group['group'] ); + $this->assertEquals( $this->pods_object_group->get_fields(), $this->pods_object_group['fields'] ); + $this->assertEquals( $this->pods_object_group->get_object_fields(), $this->pods_object_group['object_fields'] ); + $this->assertEquals( $this->pods_object_group->get_all_fields(), $this->pods_object_group['all_fields'] ); + $this->assertEquals( $this->pods_object_group->get_groups(), $this->pods_object_group['groups'] ); + $this->assertEquals( $this->pods_object_group->get_table_info(), $this->pods_object_group['table_info'] ); + $this->assertEquals( $this->pods_object_group->get_args(), $this->pods_object_group['options'] ); + + // Confirm argument get matches Object __get. + $this->assertEquals( $this->pods_object_group->get_id(), $this->pods_object_group->id ); + $this->assertEquals( $this->pods_object_group->get_name(), $this->pods_object_group->name ); + $this->assertEquals( $this->pods_object_group->get_parent(), $this->pods_object_group->parent ); + $this->assertEquals( $this->pods_object_group->get_group(), $this->pods_object_group->group ); + $this->assertEquals( $this->pods_object_group->get_fields(), $this->pods_object_group->fields ); + $this->assertEquals( $this->pods_object_group->get_object_fields(), $this->pods_object_group->object_fields ); + $this->assertEquals( $this->pods_object_group->get_all_fields(), $this->pods_object_group->all_fields ); + $this->assertEquals( $this->pods_object_group->get_groups(), $this->pods_object_group->groups ); + $this->assertEquals( $this->pods_object_group->get_table_info(), $this->pods_object_group->table_info ); + $this->assertEquals( $this->pods_object_group->get_args(), $this->pods_object_group->options ); + + $list = array( $this->pods_object_group ); + + $this->assertEquals( array( $this->pods_object_group->get_id() ), wp_list_pluck( $list, 'id' ) ); + $this->assertEquals( array( $this->pods_object_group->get_name() ), wp_list_pluck( $list, 'name' ) ); + $this->assertEquals( array( $this->pods_object_group->get_parent() ), wp_list_pluck( $list, 'parent' ) ); + $this->assertEquals( array( $this->pods_object_group->get_group() ), wp_list_pluck( $list, 'group' ) ); + $this->assertEquals( array( $this->pods_object_group->get_arg( 'custom1' ) ), wp_list_pluck( $list, 'custom1' ) ); + + // Test non-existent arguments and handling for ArrayAccess. + $this->assertNull( $this->pods_object_group->get_arg( 'fourohfour' ) ); + $this->assertEquals( $this->pods_object_group->get_arg( 'fourohfour' ), $this->pods_object_group['fourohfour'] ); + $this->assertFalse( isset( $this->pods_object_group['fourohfour'] ) ); + + // Test isset for ArrayAccess. + $this->assertTrue( isset( $this->pods_object_group['id'] ) ); + $this->assertTrue( isset( $this->pods_object_group['name'] ) ); + $this->assertTrue( isset( $this->pods_object_group['parent'] ) ); + $this->assertTrue( isset( $this->pods_object_group['group'] ) ); + + // Test unset handling for ArrayAccess served arguments. + unset( $this->pods_object_group['id'], $this->pods_object_group['name'], $this->pods_object_group['parent'], $this->pods_object_group['group'] ); + + // Confirm ArrayAccess arguments are now empty strings for reserved arguments. + $this->assertEquals( $this->pods_object_group['id'], '' ); + $this->assertEquals( $this->pods_object_group['name'], '' ); + $this->assertEquals( $this->pods_object_group['parent'], '' ); + $this->assertEquals( $this->pods_object_group['group'], '' ); + } + + /** + * @covers Whatsit::offsetExists + * @covers Whatsit::offsetGet + * @covers Whatsit::offsetSet + * @covers Whatsit::offsetUnset + * @covers Whatsit::get_arg + * @covers Whatsit::set_arg + */ + public function test_array_access_field() { + // Confirm methods exist. + $this->assertTrue( method_exists( $this->pods_object_field, 'offsetExists' ), 'Method offsetExists does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_field, 'offsetGet' ), 'Method offsetGet does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_field, 'offsetSet' ), 'Method offsetSet does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_field, 'offsetUnset' ), 'Method offsetUnset does not exist' ); + + // Confirm argument get matches ArrayAccess. + $this->assertEquals( $this->pods_object_field->get_id(), $this->pods_object_field['id'] ); + $this->assertEquals( $this->pods_object_field->get_name(), $this->pods_object_field['name'] ); + $this->assertEquals( $this->pods_object_field->get_parent(), $this->pods_object_field['parent'] ); + $this->assertEquals( $this->pods_object_field->get_group(), $this->pods_object_field['group'] ); + $this->assertEquals( $this->pods_object_field->get_fields(), $this->pods_object_field['fields'] ); + $this->assertEquals( $this->pods_object_field->get_object_fields(), $this->pods_object_field['object_fields'] ); + $this->assertEquals( $this->pods_object_field->get_all_fields(), $this->pods_object_field['all_fields'] ); + $this->assertEquals( $this->pods_object_field->get_groups(), $this->pods_object_field['groups'] ); + $this->assertEquals( $this->pods_object_field->get_table_info(), $this->pods_object_field['table_info'] ); + $this->assertEquals( $this->pods_object_field->get_args(), $this->pods_object_field['options'] ); + + // Confirm argument get matches Object __get. + $this->assertEquals( $this->pods_object_field->get_id(), $this->pods_object_field->id ); + $this->assertEquals( $this->pods_object_field->get_name(), $this->pods_object_field->name ); + $this->assertEquals( $this->pods_object_field->get_parent(), $this->pods_object_field->parent ); + $this->assertEquals( $this->pods_object_field->get_group(), $this->pods_object_field->group ); + $this->assertEquals( $this->pods_object_field->get_fields(), $this->pods_object_field->fields ); + $this->assertEquals( $this->pods_object_field->get_object_fields(), $this->pods_object_field->object_fields ); + $this->assertEquals( $this->pods_object_field->get_all_fields(), $this->pods_object_field->all_fields ); + $this->assertEquals( $this->pods_object_field->get_groups(), $this->pods_object_field->groups ); + $this->assertEquals( $this->pods_object_field->get_table_info(), $this->pods_object_field->table_info ); + $this->assertEquals( $this->pods_object_field->get_args(), $this->pods_object_field->options ); + + $list = array( $this->pods_object_field ); + + $this->assertEquals( array( $this->pods_object_field->get_id() ), wp_list_pluck( $list, 'id' ) ); + $this->assertEquals( array( $this->pods_object_field->get_name() ), wp_list_pluck( $list, 'name' ) ); + $this->assertEquals( array( $this->pods_object_field->get_parent() ), wp_list_pluck( $list, 'parent' ) ); + $this->assertEquals( array( $this->pods_object_field->get_group() ), wp_list_pluck( $list, 'group' ) ); + $this->assertEquals( array( $this->pods_object_field->get_arg( 'custom1' ) ), wp_list_pluck( $list, 'custom1' ) ); + + // Test non-existent arguments and handling for ArrayAccess. + $this->assertNull( $this->pods_object_field->get_arg( 'fourohfour' ) ); + $this->assertEquals( $this->pods_object_field->get_arg( 'fourohfour' ), $this->pods_object_field['fourohfour'] ); + $this->assertFalse( isset( $this->pods_object_field['fourohfour'] ) ); + + // Test isset for ArrayAccess. + $this->assertTrue( isset( $this->pods_object_field['id'] ) ); + $this->assertTrue( isset( $this->pods_object_field['name'] ) ); + $this->assertTrue( isset( $this->pods_object_field['parent'] ) ); + $this->assertTrue( isset( $this->pods_object_field['group'] ) ); + + // Test unset handling for ArrayAccess served arguments. + unset( $this->pods_object_field['id'], $this->pods_object_field['name'], $this->pods_object_field['parent'], $this->pods_object_field['group'] ); + + // Confirm ArrayAccess arguments are now empty strings for reserved arguments. + $this->assertEquals( $this->pods_object_field['id'], '' ); + $this->assertEquals( $this->pods_object_field['name'], '' ); + $this->assertEquals( $this->pods_object_field['parent'], '' ); + $this->assertEquals( $this->pods_object_field['group'], '' ); + } + + /** + * @covers Whatsit::setup + * @covers Whatsit::get_args + * @covers Whatsit::get_arg + * @covers Whatsit::get_group + */ + public function test_setup() { + $this->assertTrue( method_exists( $this->pods_object_field, 'setup' ), 'Method setup does not exist' ); + + $args = array( + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + 'fourohfour' => 405, + ); + + $this->pods_object_field->setup( $args ); + + $this->assertArraySubset( $args, $this->pods_object_field->get_args() ); + $this->assertEquals( '', $this->pods_object_field->get_arg( 'label' ) ); + $this->assertEquals( '', $this->pods_object_field->get_arg( 'description' ) ); + + $args2 = array( + 'name' => 'seven', + 'id' => 777, + 'parent' => 7777, + ); + + $this->pods_object_field->setup( $args2 ); + + $this->assertArraySubset( $args2, $this->pods_object_field->get_args() ); + $this->assertEquals( '', $this->pods_object_field->get_group() ); + $this->assertEquals( '', $this->pods_object_field->get_arg( 'label' ) ); + $this->assertEquals( '', $this->pods_object_field->get_arg( 'description' ) ); + $this->assertNull( $this->pods_object_field->get_arg( 'fourohfour' ) ); + } + + /** + * @covers Whatsit::get_arg + * @covers Whatsit::set_arg + */ + public function test_get_set_arg() { + // Confirm methods exist. + $this->assertTrue( method_exists( $this->pods_object_field, 'get_arg' ), 'Method get_arg does not exist' ); + $this->assertTrue( method_exists( $this->pods_object_field, 'set_arg' ), 'Method set_arg does not exist' ); + + // Confirm get_arg matches method access. + $this->assertEquals( $this->pods_object_field->get_id(), $this->pods_object_field->get_arg( 'id' ) ); + $this->assertEquals( $this->pods_object_field->get_name(), $this->pods_object_field->get_arg( 'name' ) ); + $this->assertEquals( $this->pods_object_field->get_parent(), $this->pods_object_field->get_arg( 'parent' ) ); + $this->assertEquals( $this->pods_object_field->get_group(), $this->pods_object_field->get_arg( 'group' ) ); + + // Test non-existent arguments and handling for ArrayAccess. + $this->assertNull( $this->pods_object_field->get_arg( 'fourohfour' ) ); + + $args = array( + 'name' => 'fiver', + 'id' => 555, + 'parent' => 5555, + 'group' => 55555, + 'fourohfour' => 405, + ); + + $this->pods_object_field->set_arg( 'name', $args['name'] ); + $this->pods_object_field->set_arg( 'id', $args['id'] ); + $this->pods_object_field->set_arg( 'parent', $args['parent'] ); + $this->pods_object_field->set_arg( 'group', $args['group'] ); + $this->pods_object_field->set_arg( 'fourohfour', $args['fourohfour'] ); + + $this->assertEquals( $this->pods_object_field->get_arg( 'name' ), $args['name'] ); + $this->assertEquals( $this->pods_object_field->get_arg( 'id' ), $args['id'] ); + $this->assertEquals( $this->pods_object_field->get_arg( 'parent' ), $args['parent'] ); + $this->assertEquals( $this->pods_object_field->get_arg( 'group' ), $args['group'] ); + $this->assertEquals( $this->pods_object_field->get_arg( 'fourohfour' ), $args['fourohfour'] ); + } + + /** + * @covers Whatsit::is_valid + */ + public function test_is_valid() { + $this->assertTrue( method_exists( $this->pods_object_field, 'is_valid' ), 'Method is_valid does not exist' ); + + $this->assertTrue( $this->pods_object_field->is_valid() ); + + $args = array( + 'name' => '', + 'id' => '', + 'parent' => '', + 'group' => '', + ); + + $this->pods_object_field->setup( $args ); + + $this->assertFalse( $this->pods_object_field->is_valid() ); + } + + /** + * @covers Whatsit::get_identifier_from_args + */ + public function test_get_identifier_from_args() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_identifier_from_args' ), 'Method get_identifier_from_args does not exist' ); + + $this->assertEquals( $this->pods_object_field->get_identifier(), Whatsit::get_identifier_from_args( $this->field_args ) ); + + $identifier = sprintf( '%s/%s/%s', $this->pods_object_field->get_object_type(), $this->pods_object_field->get_parent(), $this->pods_object_field->get_name() ); + + $this->assertEquals( $identifier, Whatsit::get_identifier_from_args( $this->pods_object_field->get_args() ) ); + + // Unset parent. + $this->pods_object_field->set_arg( 'parent', null ); + + $identifier = sprintf( '%s/%s', $this->pods_object_field->get_object_type(), $this->pods_object_field->get_name() ); + + $this->assertEquals( $identifier, Whatsit::get_identifier_from_args( $this->pods_object_field->get_args() ) ); + } + + /** + * @covers Whatsit::get_identifier + */ + public function test_get_identifier() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_identifier' ), 'Method get_identifier does not exist' ); + + $identifier = sprintf( '%s/%s/%s', $this->pods_object_field->get_object_type(), $this->pods_object_field->get_parent(), $this->pods_object_field->get_name() ); + + $this->assertEquals( $identifier, $this->pods_object_field->get_identifier() ); + + // Unset parent. + $this->pods_object_field->set_arg( 'parent', null ); + + $identifier = sprintf( '%s/%s', $this->pods_object_field->get_object_type(), $this->pods_object_field->get_name() ); + + $this->assertEquals( $identifier, $this->pods_object_field->get_identifier() ); + } + + /** + * @covers Whatsit::set_arg + * @covers Whatsit::get_arg + */ + public function test_set_arg() { + $this->assertTrue( method_exists( $this->pods_object_field, 'set_arg' ), 'Method set_arg does not exist' ); + + $this->pods_object_field->set_arg( 'custom5', 'Test5' ); + + $this->assertEquals( 'Test5', $this->pods_object_field->get_arg( 'custom5', 'Nope' ) ); + } + + /** + * @covers Whatsit::get_arg + */ + public function test_get_arg() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_arg' ), 'Method get_arg does not exist' ); + + $this->assertEquals( 'value1-test-field', $this->pods_object_field->get_arg( 'custom1' ) ); + + // Test default arg handling. + $this->assertNull( $this->pods_object_field->get_arg( 'custom6' ) ); + $this->assertEquals( 'Nope', $this->pods_object_field->get_arg( 'custom6', 'Nope' ) ); + } + + /** + * @covers Whatsit::get_args + */ + public function test_get_args() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_args' ), 'Method get_args does not exist' ); + + $this->assertEquals( $this->field_args, $this->pods_object_field->get_args() ); + } + + /** + * Provide get_* methods to be tested. + * + * @return array + */ + public function provider_methods() { + return array( + array( 'object_type' ), + array( 'storage_type' ), + array( 'name' ), + array( 'id' ), + array( 'parent' ), + array( 'group' ), + array( 'label' ), + array( 'description' ), + array( 'type' ), + ); + } + + /** + * @covers Whatsit::get_object_type + * @covers Whatsit::get_storage_type + * @covers Whatsit::get_name + * @covers Whatsit::get_id + * @covers Whatsit::get_parent + * @covers Whatsit::get_group + * @covers Whatsit::get_label + * @covers Whatsit::get_description + * + * @dataProvider provider_methods + * + * @param string $property Property to test. + */ + public function test_get( $property ) { + $method = 'get_' . $property; + + codecept_debug( 'Method: ' . $method ); + + $this->assertEquals( $this->field_args[ $property ], call_user_func( array( + $this->pods_object_field, + $method + ) ) ); + } + + /** + * Provide parent get_* methods to be tested. + * + * @return array + */ + public function provider_parent_methods() { + return array( + array( 'object_type' ), + array( 'storage_type' ), + array( 'name' ), + array( 'id' ), + array( 'label' ), + array( 'description' ), + array( 'type' ), + ); + } + + /** + * @covers Whatsit::get_parent_object_type + * @covers Whatsit::get_parent_storage_type + * @covers Whatsit::get_parent_name + * @covers Whatsit::get_parent_id + * @covers Whatsit::get_parent_label + * @covers Whatsit::get_parent_description + * + * @dataProvider provider_parent_methods + * + * @param string $property Property to test. + */ + public function test_get_parent( $property ) { + $method = 'get_parent_' . $property; + + codecept_debug( 'Method: ' . $method ); + + $this->assertEquals( $this->pod_args[ $property ], call_user_func( array( + $this->pods_object_field, + $method + ) ) ); + } + + /** + * Provide group get_* methods to be tested. + * + * @return array + */ + public function provider_group_methods() { + return array( + array( 'object_type' ), + array( 'storage_type' ), + array( 'name' ), + array( 'id' ), + array( 'label' ), + array( 'description' ), + array( 'type' ), + ); + } + + /** + * @covers Whatsit::get_group_object_type + * @covers Whatsit::get_group_storage_type + * @covers Whatsit::get_group_name + * @covers Whatsit::get_group_id + * @covers Whatsit::get_group_label + * @covers Whatsit::get_group_description + * + * @dataProvider provider_group_methods + * + * @param string $property Property to test. + */ + public function test_get_group( $property ) { + $method = 'get_group_' . $property; + + codecept_debug( 'Method: ' . $method ); + + $this->assertEquals( $this->group_args[ $property ], call_user_func( array( + $this->pods_object_field, + $method + ) ) ); + } + + /** + * @covers Whatsit::get_fields + */ + public function test_get_fields_pod() { + $this->assertTrue( method_exists( $this->pods_object_pod, 'get_fields' ), 'Method get_fields does not exist' ); + + $fields = $this->pods_object_pod->get_fields(); + + $this->assertCount( 1, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + + // Confirm internal cache still works. + $fields = $this->pods_object_pod->get_fields(); + + $this->assertCount( 1, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + } + + /** + * @covers Whatsit::get_fields + */ + public function test_get_fields_group() { + $this->assertTrue( method_exists( $this->pods_object_group, 'get_fields' ), 'Method get_fields does not exist' ); + + $fields = $this->pods_object_group->get_fields(); + + $this->assertCount( 1, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + + // Confirm internal cache still works. + $fields = $this->pods_object_group->get_fields(); + + $this->assertCount( 1, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + } + + /** + * @covers Whatsit::get_fields + */ + public function test_get_fields_field() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_fields' ), 'Method get_fields does not exist' ); + + $fields = $this->pods_object_field->get_fields(); + + $this->assertCount( 0, $fields ); + + // Confirm internal cache still works. + $fields = $this->pods_object_field->get_fields(); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers Whatsit::get_object_fields + */ + public function test_get_object_fields_pod() { + $this->assertTrue( method_exists( $this->pods_object_pod, 'get_object_fields' ), 'Method get_object_fields does not exist' ); + + $fields = $this->pods_object_pod->get_object_fields(); + + // Post types have 24 object fields. + $this->assertCount( 24, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + } + + /** + * @covers Whatsit::get_object_fields + */ + public function test_get_object_fields_group() { + $this->assertTrue( method_exists( $this->pods_object_group, 'get_object_fields' ), 'Method get_object_fields does not exist' ); + + $fields = $this->pods_object_group->get_object_fields(); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers Whatsit::get_object_fields + */ + public function test_get_object_fields_field() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_object_fields' ), 'Method get_object_fields does not exist' ); + + $fields = $this->pods_object_field->get_object_fields(); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers Whatsit::get_all_fields + */ + public function test_get_all_fields_pod() { + $this->assertTrue( method_exists( $this->pods_object_pod, 'get_all_fields' ), 'Method get_all_fields does not exist' ); + + $fields = $this->pods_object_pod->get_all_fields(); + + // Post types have 24 object fields. + $this->assertCount( 25, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + + // Confirm internal cache still works. + $fields = $this->pods_object_pod->get_all_fields(); + + $this->assertCount( 25, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + } + + /** + * @covers Whatsit::get_all_fields + */ + public function test_get_all_fields_group() { + $this->assertTrue( method_exists( $this->pods_object_group, 'get_all_fields' ), 'Method get_all_fields does not exist' ); + + $fields = $this->pods_object_group->get_all_fields(); + + $this->assertCount( 1, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + + // Confirm internal cache still works. + $fields = $this->pods_object_group->get_all_fields(); + + $this->assertCount( 1, $fields ); + $this->assertInstanceOf( Field::class, reset( $fields ) ); + } + + /** + * @covers Whatsit::get_all_fields + */ + public function test_get_all_fields_field() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_all_fields' ), 'Method get_all_fields does not exist' ); + + $fields = $this->pods_object_field->get_all_fields(); + + $this->assertCount( 0, $fields ); + + // Confirm internal cache still works. + $fields = $this->pods_object_field->get_all_fields(); + + $this->assertCount( 0, $fields ); + } + + /** + * @covers Whatsit::get_groups + */ + public function test_get_groups_pod() { + $this->assertTrue( method_exists( $this->pods_object_pod, 'get_groups' ), 'Method get_groups does not exist' ); + + $groups = $this->pods_object_pod->get_groups(); + + $this->assertCount( 1, $groups ); + $this->assertInstanceOf( Group::class, reset( $groups ) ); + } + + /** + * @covers Whatsit::get_groups + */ + public function test_get_groups_group() { + $this->assertTrue( method_exists( $this->pods_object_group, 'get_groups' ), 'Method get_groups does not exist' ); + + $groups = $this->pods_object_group->get_groups(); + + $this->assertCount( 0, $groups ); + } + + /** + * @covers Whatsit::get_groups + */ + public function test_get_groups_field() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_groups' ), 'Method get_groups does not exist' ); + + $groups = $this->pods_object_field->get_groups(); + + $this->assertCount( 0, $groups ); + } + + /** + * @covers Whatsit::get_table_info + */ + public function test_get_table_info_pod() { + $this->assertTrue( method_exists( $this->pods_object_pod, 'get_table_info' ), 'Method get_table_info does not exist' ); + + $table_info = $this->pods_object_pod->get_table_info(); + + $this->assertCount( 28, $table_info ); + } + + /** + * @covers Whatsit::get_table_info + */ + public function test_get_table_info_group() { + $this->assertTrue( method_exists( $this->pods_object_group, 'get_table_info' ), 'Method get_table_info does not exist' ); + + $table_info = $this->pods_object_group->get_table_info(); + + $this->assertCount( 0, $table_info ); + } + + /** + * @covers Whatsit::get_table_info + */ + public function test_get_table_info_field() { + $this->assertTrue( method_exists( $this->pods_object_field, 'get_table_info' ), 'Method get_table_info does not exist' ); + + $table_info = $this->pods_object_field->get_table_info(); + + $this->assertCount( 0, $table_info ); + } + + /** + * @covers Whatsit::get_fields + * @covers Whatsit::get_groups + * @covers Whatsit::get_object_fields + * @covers Whatsit::get_table_info + * @covers Whatsit::get_args + */ + public function test_backcompat_pod() { + $this->assertCount( 1, $this->pods_object_pod['fields'] ); + $this->assertCount( 1, $this->pods_object_pod['groups'] ); + $this->assertCount( 24, $this->pods_object_pod['object_fields'] ); + $this->assertCount( 28, $this->pods_object_pod['table_info'] ); + + $this->assertArrayHasKey( 'test-field', $this->pods_object_pod['fields'] ); + $this->assertEquals( 'Test field', $this->pods_object_pod['fields']['test-field']['label'] ); + $this->assertEquals( 'Test field', $this->pods_object_pod['fields']['test-field']['options']['label'] ); + $this->assertArrayHasKey( 'test-group', $this->pods_object_pod['groups'] ); + $this->assertEquals( 'Test group', $this->pods_object_pod['groups']['test-group']['label'] ); + $this->assertEquals( 'Test group', $this->pods_object_pod['groups']['test-group']['options']['label'] ); + + if ( ! pods_version_check( 'php', '7.0' ) ) { + return; + } + + $this->pods_object_pod['fields']['test-field']['options']['label'] = 'Something else'; + + // Backcompat does not throw PHP errors but does not save the variables. + // This is acceptable because the PHP errors cause more breakage. + $this->assertNotEquals( 'Something else', $this->pods_object_pod['fields']['test-field']['label'] ); + $this->assertNotEquals( 'Something else', $this->pods_object_pod['fields']['test-field']['options']['label'] ); + } + +} diff --git a/tests/codeception/wpunit/_bootstrap.php b/tests/codeception/wpunit/_bootstrap.php new file mode 100644 index 0000000000..7a05e39bdc --- /dev/null +++ b/tests/codeception/wpunit/_bootstrap.php @@ -0,0 +1,5 @@ +assertEquals( '', pods_sanitize( '' ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_returns_int() { + $this->assertEquals( 1, pods_sanitize( 1 ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_returns_float() { + $this->assertEquals( 12.348329, pods_sanitize( 12.348329 ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_null() { + $this->assertEquals( null, pods_sanitize( null ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_returns_object() { + $object = new stdClass(); + $object->foo = 1; + $object->bar = 'a test string'; + + $this->assertEquals( $object, pods_sanitize( $object ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_returns_array() { + $array = [ + 'foo' => 1, + 'bar' => 'a test string', + ]; + $this->assertEquals( $array, pods_sanitize( $array ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_string() { + $original = "'\\`"; + + $this->assertEquals( "\'\\\`", pods_sanitize( $original ) ); + } + + /** + * @covers ::pods_sanitize + */ + public function test_pods_sanitize_sql() { + $this->markTestSkipped( 'not yet implemented' ); + } + + /** + * @covers ::pods_sanitize_like + */ + public function test_pods_sanitize_like() { + $original = 'test%test%'; + + $this->assertEquals( 'test\\\\%test\\\\%', pods_sanitize_like( $original ) ); + } + + /** + * @covers ::pods_slash + */ + public function test_pods_slash() { + $original = "slash'this"; + + $this->assertEquals( "slash\\'this", pods_slash( $original ) ); + } + + /** + * @covers ::pods_unsanitize + */ + public function test_pods_unsanitize() { + $original = "unsanitize\\'this"; + + $this->assertEquals( "unsanitize'this", pods_unsanitize( $original ) ); + } + + /** + * @covers ::pods_unslash + */ + public function test_pods_unslash() { + $original = "unslash\\'this"; + + $this->assertEquals( "unslash'this", pods_unslash( $original ) ); + } + + /** + * @covers ::pods_trim + */ + public function test_pods_trim() { + $string = ' test '; + + $this->assertEquals( 'test', pods_trim( $string ) ); + + $this->assertEquals( ' test', pods_trim( $string, null, 'r' ) ); + + $this->assertEquals( 'test ', pods_trim( $string, null, 'l' ) ); + + $string = ' test & '; + + $this->assertEquals( 'test', pods_trim( $string, ' &' ) ); + + $this->assertEquals( ' test', pods_trim( $string, ' &', 'r' ) ); + + // Arrays. + + $array = [ + ' test ', + ' test2 ', + ]; + + $result = [ + 'test', + 'test2', + ]; + + $this->assertEquals( $result, pods_trim( $array ) ); + + $result = [ + ' test', + ' test2', + ]; + + $this->assertEquals( $result, pods_trim( $array, null, 'r' ) ); + + $array = [ + ' test & ', + ' test2 ', + ]; + + $result = [ + ' test', + ' test2', + ]; + + $this->assertEquals( $result, pods_trim( $array, ' &', 'r' ) ); + + // Objects. + + $object = new stdClass(); + $object->test = ' test '; + $object->test2 = ' test2 '; + + $result = new stdClass(); + $result->test = 'test'; + $result->test2 = 'test2'; + + $this->assertEquals( $result, pods_trim( $object ) ); + + $result->test = ' test'; + $result->test2 = ' test2'; + + $this->assertEquals( $result, pods_trim( $object, null, 'r' ) ); + + $object->test = ' test & '; + $object->test2 = ' test2 '; + + $result->test = ' test'; + $result->test2 = ' test2'; + + $this->assertEquals( $result, pods_trim( $object, ' &', 'r' ) ); + } + + /** + * @covers pods_traverse + */ + public function test_pods_traverse() { + + /** + * Array values. + */ + $value = array( + 'foobar', + 'one' => 1, + 'two' => '2', + 'decimals' => array( + 'no_key', + 'second_no_key', + 'third_no_key', + 'half' => 0.5, + 'onehalf' => 1.5, + ), + ); + + // No traversal. + $this->assertEquals( $value, pods_traverse( null, $value ) ); + + // String traversal. + $this->assertEquals( 1, pods_traverse( 'one', $value ) ); + $this->assertEquals( '2', pods_traverse( 'two', $value ) ); + $this->assertEquals( 1.5, pods_traverse( 'decimals.onehalf', $value ) ); + $this->assertEquals( null, pods_traverse( 'invalid', $value ) ); + $this->assertEquals( null, pods_traverse( 'decimals.invalid', $value ) ); + + // Array traversal. + $this->assertEquals( 1, pods_traverse( array( 'one' ), $value ) ); + $this->assertEquals( '2', pods_traverse( array( 'two' ), $value ) ); + $this->assertEquals( 1.5, pods_traverse( array( 'decimals', 'onehalf' ), $value ) ); + $this->assertEquals( null, pods_traverse( array( 'invalid' ), $value ) ); + $this->assertEquals( null, pods_traverse( array( 'decimals', 'invalid' ), $value ) ); + + // Numeric array keys. + $this->assertEquals( 'foobar', pods_traverse( 0, $value ) ); + $this->assertEquals( 'third_no_key', pods_traverse( 'decimals.2', $value ) ); + $this->assertEquals( 'foobar', pods_traverse( array( 0 ), $value ) ); + $this->assertEquals( 'third_no_key', pods_traverse( array( 'decimals', 2 ), $value ) ); + + /** + * Object values. + * Numeric keys not available in objects. + */ + $value = new stdClass(); + $value->one = 1; + $value->two = '2'; + $value->decimals = new stdClass(); + $value->decimals->half = 0.5; + $value->decimals->onehalf = 1.5; + + // No traversal. + $this->assertEquals( $value, pods_traverse( null, $value ) ); + + // String traversal. + $this->assertEquals( 1, pods_traverse( 'one', $value ) ); + $this->assertEquals( '2', pods_traverse( 'two', $value ) ); + $this->assertEquals( 1.5, pods_traverse( 'decimals.onehalf', $value ) ); + $this->assertEquals( null, pods_traverse( 'invalid', $value ) ); + $this->assertEquals( null, pods_traverse( 'decimals.invalid', $value ) ); + + // Array traversal. + $this->assertEquals( 1, pods_traverse( array( 'one' ), $value ) ); + $this->assertEquals( '2', pods_traverse( array( 'two' ), $value ) ); + $this->assertEquals( 1.5, pods_traverse( array( 'decimals', 'onehalf' ), $value ) ); + $this->assertEquals( null, pods_traverse( array( 'invalid' ), $value ) ); + $this->assertEquals( null, pods_traverse( array( 'decimals', 'invalid' ), $value ) ); + + } + + public function test_pods_v() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_v_sanitized() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_v_set() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_var() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_var_raw() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_var_set() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_query_arg() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_var_update() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_cast() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_create_slug() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_unique_slug() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_clean_name() { + $this->assertEquals( '_test_field_name_', pods_clean_name( ' _Test field! name_ ' ) ); + $this->assertEquals( '_test_field_name_', pods_clean_name( ' _Test field! name_ ' ) ); + $this->assertEquals( '_test_field__name_', pods_clean_name( ' _Test field! __name_ ' ) ); + $this->assertEquals( '_test_field__name_', pods_clean_name( ' _Test_field!__name_ ' ) ); + $this->assertEquals( 'test_field-name', pods_clean_name( ' Test field-name ' ) ); + $this->assertEquals( 'test_field-name', pods_clean_name( ' Test field--name ' ) ); + + $this->assertEquals( 'Test_field_name', pods_clean_name( ' Test field! name ', false ) ); + $this->assertEquals( 'Test_field_name', pods_clean_name( ' Test field! name ', false ) ); + $this->assertEquals( 'Test_field__name', pods_clean_name( ' Test field! __name ', false ) ); + $this->assertEquals( 'Test_field__name', pods_clean_name( ' Test_field!__name', false ) ); + + $this->assertEquals( 'test_field_name', pods_clean_name( ' _Test field! name_ ', true, true ) ); + $this->assertEquals( 'test_field_name', pods_clean_name( ' _Test field! name_ ', true, true ) ); + $this->assertEquals( 'test_field__name', pods_clean_name( ' _Test field! __name_ ', true, true ) ); + $this->assertEquals( 'test_field__name', pods_clean_name( ' _Test_field!__name_ ', true, true ) ); + } + + /** + * @covers ::pods_absint + */ + public function test_pods_absint() { + $this->assertEquals( 1, pods_absint( 1.234 ) ); + } + + /** + * @covers ::pods_absint + */ + public function test_pods_absint_no_negative() { + $this->assertEquals( 1, pods_absint( - 1.234 ) ); + } + + /** + * @covers ::pods_absint + */ + public function test_pods_absint_allows_negative() { + $this->assertEquals( - 1, pods_absint( - 1.234, true, true ) ); + } + + /** + * @covers ::pods_absint + */ + public function test_pods_absint_returns_zero_for_string() { + $this->assertEquals( 0, pods_absint( 'asdf' ) ); + } + + public function test_pods_str_replace() { + $this->markTestSkipped( 'not yet implemented' ); + } + + /** + * @covers ::pods_mb_strlen + */ + public function test_pods_mb_strlen() { + $this->assertEquals( 4, pods_mb_strlen( 'asdf' ) ); + } + + /** + * @covers ::pods_mb_substr + */ + public function test_pods_mb_substr() { + $this->assertEquals( 'sd', pods_mb_substr( 'asdf', 1, 2 ) ); + } + + /** + * @covers ::pods_evaluate_tags + * @covers ::pods_evaluate_tag + */ + public function test_pods_evaluate_tags() { + global $wpdb; + + /** + * Special magic tags. + * + * @link https://docs.pods.io/displaying-pods/magic-tags/special-magic-tags/ + */ + $this->assertEquals( $wpdb->prefix, pods_evaluate_tag( '{@prefix}' ) ); + $this->assertEquals( get_template_directory_uri(), pods_evaluate_tag( '{@template-url}' ) ); + $this->assertEquals( get_stylesheet_directory_uri(), pods_evaluate_tag( '{@stylesheet-url}' ) ); + $this->assertEquals( site_url(), pods_evaluate_tag( '{@site-url}' ) ); + $this->assertEquals( home_url(), pods_evaluate_tag( '{@home-url}' ) ); + $this->assertEquals( admin_url(), pods_evaluate_tag( '{@admin-url}' ) ); + $this->assertEquals( includes_url(), pods_evaluate_tag( '{@includes-url}' ) ); + $this->assertEquals( plugins_url(), pods_evaluate_tag( '{@plugins-url}' ) ); + $this->assertEquals( network_site_url(), pods_evaluate_tag( '{@network-site-url}' ) ); + $this->assertEquals( network_home_url(), pods_evaluate_tag( '{@network-home-url}' ) ); + $this->assertEquals( network_admin_url(), pods_evaluate_tag( '{@network-admin-url}' ) ); + $this->assertEquals( user_admin_url(), pods_evaluate_tag( '{@user-admin-url}' ) ); + $this->assertEquals( date_i18n( 'Y-m-d' ), pods_evaluate_tag( '{@date.Y-m-d}' ) ); + $this->assertEquals( date_i18n( 'Y-m-d', strtotime( 'tomorrow' ) ), pods_evaluate_tag( '{@date.Y-m-d|tomorrow}' ) ); + + // First log in the user. + $user_id = $this->factory()->user->create(); + wp_set_current_user( $user_id ); + + // Should be `ID` but added lowercase for backwards compatibility. + $this->assertEquals( get_current_user_id(), pods_evaluate_tag( '{@user.id}' ) ); + } + + /** + * @covers ::pods_evaluate_tag_sql + */ + public function test_pods_evaluate_tag_sql() { + + $params = array( + 'sanitize' => true, + 'fallback' => '""', + ); + + // EQUALS + + $sql = "value = {@get.test_sql_tag}"; + $compare = 'value = ""'; + + $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); + + $_GET['test_sql_tag'] = '5797'; + $compare = 'value = 5797'; + + $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); + + // LIKE + + $sql = "value LIKE '{@get.test_sql_tag_like}%'"; + $compare = "value LIKE '%'"; + + $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); + + $_GET['test_sql_tag_like'] = '5797'; + $compare = "value LIKE '5797%'"; + + $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); + } + + public function test_pods_evaluate_tag_sanitized() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_evaluate_tag() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_serial_comma() { + $values = [ + 'test1', + 'test2', + 'test3', + ]; + + $result = 'test1, test2, and test3'; + + $this->assertEquals( $result, pods_serial_comma( $values ) ); + + $args = [ + 'serial' => false, + ]; + + $result = 'test1, test2 and test3'; + + $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); + + $args = [ + 'separator' => ' | ', + 'serial' => false, + ]; + + $result = 'test1 | test2 and test3'; + + $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); + + $args = [ + 'and' => ' & ', + 'serial' => false, + ]; + + $result = 'test1, test2 & test3'; + + $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); + + $args = [ + 'separator' => ' | ', + 'and' => ' | ', + 'serial' => false, + ]; + + $result = 'test1 | test2 | test3'; + + $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); + } + + public function test_pods_var_user() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_hierarchical_list() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_hierarchical_list_recurse() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_hierarchical_select() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_hierarchical_select_recurse() { + $this->markTestSkipped( 'not yet implemented' ); + } + + public function test_pods_list_filter() { + // Test objects since that is not supported by wp_list_filter. + + $obj = new stdClass(); + $obj->obj1 = new stdClass(); + $obj->obj2 = new stdClass(); + $obj->obj3 = new stdClass(); + $obj->obj4 = new stdClass(); + + $obj->obj1->status = 'published'; + $obj->obj2->status = 'published'; + $obj->obj3->status = 'draft'; + $obj->obj4->status = 'published'; + + $obj->obj1->param = 'valid'; + $obj->obj2->param = 'invalid'; + $obj->obj3->param = 'valid'; + $obj->obj4->param = 'valid'; + + $args = [ + 'status' => 'published', + 'param' => 'valid', + ]; + + $result = $obj; + unset( $result->obj2 ); + unset( $result->obj3 ); + + $this->assertEquals( $result, pods_list_filter( $obj, $args ) ); + + // NOT operator. + + $args = [ + 'status' => 'published', + ]; + + $result = $obj; + unset( $result->obj1 ); + unset( $result->obj2 ); + unset( $result->obj4 ); + + $this->assertEquals( $result, pods_list_filter( $obj, $args, 'NOT' ) ); + } + +} diff --git a/tests/codeception/wpunit/functions/MetadataTest.php b/tests/codeception/wpunit/functions/MetadataTest.php new file mode 100644 index 0000000000..4973749ee4 --- /dev/null +++ b/tests/codeception/wpunit/functions/MetadataTest.php @@ -0,0 +1,504 @@ + 'test_metadata_post', + 'taxonomy' => 'test_metadata_term', + // Name should be equal as WP object name. + 'media' => 'media', + 'comment' => 'comment', + 'user' => 'user', + ]; + + protected static $pod_ids = []; + + protected static $field_ids = []; + + protected static $obj_ids = []; + + protected static $image_ids = []; + + public function setUp() : void { + self::create_pods(); + + // Reload PodsMeta. + $meta = pods_meta(); + $meta->core(); + + // Setup the post types/taxonomies again. + $init = pods_init(); + $init->setup_content_types( true ); + + self::load_pods(); + + parent::setUp(); + } + + public function tearDown() : void { + self::$obj_ids = []; + self::$image_ids = []; + + parent::tearDown(); + } + + public static function create_pods() { + $api = pods_api(); + + foreach ( self::$pod_names as $type => $name ) { + $pod = $api->load_pod( $name ); + + if ( $pod ) { + self::$pod_ids[ $type ] = $pod['id']; + } else { + self::$pod_ids[ $type ] = $api->save_pod( [ + 'storage' => 'meta', + 'type' => $type, + 'name' => $name, + ] ); + } + + $pod_id = self::$pod_ids[ $type ]; + + if ( ! empty( self::$field_ids[ $type ] ) ) { + continue; + } + + self::$field_ids[ $type ] = []; + + $params = [ + 'pod' => $name, + 'pod_id' => $pod_id, + 'name' => 'metadata_test_text', + 'type' => 'text', + ]; + + self::$field_ids[ $type ][] = $api->save_field( $params ); + + $params = [ + 'pod' => $name, + 'pod_id' => $pod_id, + 'name' => 'metadata_test_images', + 'type' => 'file', + 'file_format_type' => 'multi', + ]; + + self::$field_ids[ $type ][] = $api->save_field( $params ); + + $params = [ + 'pod' => $name, + 'pod_id' => $pod_id, + 'name' => 'metadata_test_related_single', + 'type' => 'pick', + 'pick_object' => $type, + 'pick_val' => $name, + 'pick_format_type' => 'single', + ]; + + self::$field_ids[ $type ][] = $api->save_field( $params ); + + $params = [ + 'pod' => $name, + 'pod_id' => $pod_id, + 'name' => 'metadata_test_related_multi', + 'type' => 'pick', + 'pick_object' => $type, + 'pick_val' => $name, + 'pick_format_type' => 'multi', + ]; + + self::$field_ids[ $type ][] = $api->save_field( $params ); + + // PR #5665 + $params = [ + 'pod' => $name, + 'pod_id' => $pod_id, + 'name' => 'metadata_test_slash', + 'type' => 'text', + ]; + + self::$field_ids[ $type ][] = $api->save_field( $params ); + + $params = [ + 'pod' => $name, + 'pod_id' => $pod_id, + 'name' => 'metadata_test_quotes', + 'type' => 'text', + ]; + + self::$field_ids[ $type ][] = $api->save_field( $params ); + } + } + + public static function load_pods() { + pods_no_conflict_on( 'all' ); + + self::$image_ids = [ + self::factory()->attachment->create(), + self::factory()->attachment->create(), + ]; + + foreach ( self::$pod_names as $type => $name ) { + $objects = [ + 'test 1', + 'test 2', + 'test 3', + ]; + + foreach ( $objects as $key => $object ) { + $title = $object; + $object = []; + $id_key = 'ID'; + $id = 0; + switch ( $type ) { + case 'post_type': + $object['post_title'] = $title; + $object['post_content'] = 'Test content'; + $object['post_status'] = 'publish'; + $object['post_type'] = $name; + + $id = self::factory()->post->create( $object ); + break; + case 'taxonomy': + $object['taxonomy'] = $name; + $object['name'] = $title; + + $id = self::factory()->term->create( $object ); + break; + case 'user': + $login = str_replace( '-', '', sanitize_title_with_dashes( $title ) ); + $object['user_login'] = $login; + $object['user_pass'] = $login; + $object['user_email'] = $login . '@test.local'; + + $id = self::factory()->user->create( $object ); + break; + case 'comment': + $object['comment_content'] = $title; + $object['comment_approved'] = 1; + + $id = self::factory()->comment->create( $object ); + break; + } + + if ( ! is_numeric( $id ) ) { + $id = pods_v( self::get_id_key( $type ), $id, $id ); + } + $objects[ $key ] = $id; + } + + self::$obj_ids[ $type ] = $objects; + + $update_meta = self::get_meta_function( 'update', $type ); + + foreach ( $objects as $key => $id ) { + $data = []; + + switch ( $key ) { + case 0: + $data = [ + 'metadata_test_text' => 'text', + 'metadata_test_images' => self::$image_ids, + // No relationship fields. + // No relationship fields. + + // PR #5665 + 'metadata_test_slash' => 'Test \backslash', + 'metadata_test_quotes' => 'Test \'quotes\' "doublequotes"', + ]; + break; + case 1: + $data = [ + 'metadata_test_related_single' => $objects[2], + // Single multi relationship. + 'metadata_test_related_multi' => $objects[2], + ]; + break; + case 2: + $data = [ + 'metadata_test_related_single' => $objects[1], + 'metadata_test_related_multi' => [ $objects[0], $objects[1] ], + ]; + break; + } + + // Handle update of the values. + foreach ( $data as $meta_key => $meta_value ) { + call_user_func( $update_meta, $id, $meta_key, $meta_value ); + } + } + } + + pods_no_conflict_off( 'all' ); + } + + public function test_created_pods() { + + foreach( self::$pod_names as $type => $name ) { + $pod = pods( $name ); + $this->assertInstanceOf( \Pods::class, $pod ); + $this->assertNotFalse( $pod->valid() ); + $this->assertNotEmpty( self::$obj_ids[ $type ] ); + } + } + + public function test_get_metadata() { + $this->markTestSkipped( 'This test class needs to be revamped, the pod get/create/update is messed up between tests' ); + + foreach ( self::$obj_ids as $type => $ids ) { + $id_key = self::get_id_key( $type ); + $name = self::$pod_names[ $type ]; + $get_meta = self::get_meta_function( 'get', $type ); + + foreach ( $ids as $key => $id ) { + $single = call_user_func( $get_meta, $id, 'metadata_test_related_single', false ); + $single_single = call_user_func( $get_meta, $id, 'metadata_test_related_single', true ); + $multi = call_user_func( $get_meta, $id, 'metadata_test_related_multi', false ); + $multi_single = call_user_func( $get_meta, $id, 'metadata_test_related_multi', true ); + + // Pods returns object arrays by default. Fetch the ID's of these objects. + $single = self::convert_output_type_ids( $single, $id_key ); + $multi = self::convert_output_type_ids( $multi, $id_key ); + $single_single = isset( $single_single[ $id_key ] ) ? $single_single[ $id_key ] : $single_single; + $multi_single = isset( $multi_single[ $id_key ] ) ? $multi_single[ $id_key ] : $multi_single; + + // Add a bit of context when an assertion has failed. + $message = "Method: `{$get_meta}()`:"; + + switch ( $key ) { + case 0: + + $images = self::$image_ids; + + codecept_debug( var_export( compact( 'type', 'name', 'id' ), true ) ); + codecept_debug( var_export( call_user_func( $get_meta, $id ), true ) ); + + // Single param false + $value = call_user_func( $get_meta, $id, 'metadata_test_text', false ); + $this->assertEquals( [ 'text' ], $value, $message ); + + $value = call_user_func( $get_meta, $id, 'metadata_test_images', false ); + codecept_debug( var_export( compact( 'value', 'id', 'images' ), true ) ); + $value = self::convert_output_type_ids( $value, 'ID' ); + codecept_debug( var_export( compact( 'value' ), true ) ); + $this->assertEquals( $images, $value, $message ); + + $this->assertEquals( [], $single, $message ); + $this->assertEquals( [], $multi, $message ); + + // Single param true + $value = call_user_func( $get_meta, $id, 'metadata_test_text', true ); + $this->assertEquals( 'text', $value, $message ); + + $value = call_user_func( $get_meta, $id, 'metadata_test_images', true ); + $value = isset( $value['ID'] ) ? $value['ID'] : $value; + $this->assertEquals( $images[0], $value, $message ); + + $this->assertEquals( '', $single_single, $message ); + $this->assertEquals( '', $multi_single, $message ); + + // PR #5665 + $value = call_user_func( $get_meta, $id, 'metadata_test_slash', true ); + $this->assertEquals( 'Test backslash', $value, $message ); + $value = call_user_func( $get_meta, $id, 'metadata_test_quotes', true ); + $this->assertEquals( 'Test \'quotes\' "doublequotes"', $value, $message ); + + break; + case 1: + // Single related to: 2 + // Multi related to: 2 + + $single_rel = $ids[2]; + $multi_rel = $ids[2]; + + // Single param false + $this->assertEquals( [ $single_rel ], $single, $message ); + $this->assertEquals( [ $multi_rel ], $multi, $message ); + + // Single param true + $this->assertEquals( $single_rel, $single_single, $message ); + $this->assertEquals( $multi_rel, $multi_single, $message ); + + break; + case 2: + // Single related to: 1 + // Multi related to: 0 and 1 + + $single_rel = $ids[1]; + $multi_rel = [ + $ids[0], + $ids[1], + ]; + + codecept_debug( var_export( compact( 'single_rel', 'multi_rel', 'ids', 'single', 'multi' ), true ) ); + + // Single param false + $this->assertEquals( [ $single_rel ], $single, $message ); + $this->assertEquals( $multi_rel, $multi, $message ); + + // Single param true + $this->assertEquals( $single_rel, $single_single, $message ); + // Even when having multiple values, if single is true then it should return the first value. + $this->assertEquals( $multi_rel[0], $multi_single, $message ); + + break; + } + } + } + } + + public function test_get_metadata_ids() { + $this->markTestSkipped( 'This test class needs to be revamped, the pod get/create/update is messed up between tests' ); + + // Make sure we return ID's. + add_filter( 'pods_pods_field_related_output_type', [ $this, 'filter_output_type_ids' ] ); + //remove_filter( 'get_post_metadata', array( pods_meta(), 'get_post_meta' ), 10 ); + + foreach ( self::$obj_ids as $type => $ids ) { + $name = self::$pod_names[ $type ]; + $get_meta = self::get_meta_function( 'get', $type ); + + foreach ( $ids as $key => $id ) { + $single = call_user_func( $get_meta, $id, 'metadata_test_related_single', false ); + $single_single = call_user_func( $get_meta, $id, 'metadata_test_related_single', true ); + $multi = call_user_func( $get_meta, $id, 'metadata_test_related_multi', false ); + $multi_single = call_user_func( $get_meta, $id, 'metadata_test_related_multi', true ); + + // Add a bit of context when a assertion has failed. + $message = "Method: `{$get_meta}()`:"; + + switch ( $key ) { + case 0: + + $images = self::$image_ids; + + // Single param false + $value = call_user_func( $get_meta, $id, 'metadata_test_text', false ); + $this->assertEquals( [ 'text' ], $value, $message ); + + $value = call_user_func( $get_meta, $id, 'metadata_test_images', false ); + $this->assertEquals( $images, $value, $message ); + + $this->assertEquals( [], $single, $message ); + $this->assertEquals( [], $multi, $message ); + + // Single param true + $value = call_user_func( $get_meta, $id, 'metadata_test_text', true ); + $this->assertEquals( 'text', $value, $message ); + + $value = call_user_func( $get_meta, $id, 'metadata_test_images', true ); + $this->assertEquals( $images[0], $value, $message ); + + $this->assertEquals( '', $single_single, $message ); + $this->assertEquals( '', $multi_single, $message ); + + break; + case 1: + // Single related to: 2 + // Multi related to: 2 + + $single_rel = $ids[2]; + $multi_rel = $ids[2]; + + // Single param false + $this->assertEquals( [ $single_rel ], $single, $message ); + $this->assertEquals( [ $multi_rel ], $multi, $message ); + + // Single param true + $this->assertEquals( $single_rel, $single_single, $message ); + $this->assertEquals( $multi_rel, $multi_single, $message ); + + break; + case 2: + // Single related to: 1 + // Multi related to: 0 and 1 + + $single_rel = $ids[1]; + $multi_rel = [ + $ids[0], + $ids[1], + ]; + + // Single param false + $this->assertEquals( [ $single_rel ], $single, $message ); + $this->assertEquals( $multi_rel, $multi, $message ); + + // Single param true + $this->assertEquals( $single_rel, $single_single, $message ); + // Even when having multiple values, if single is true then it should return the first value. + $this->assertEquals( $multi_rel[0], $multi_single, $message ); + + break; + } + } + } + + remove_filter( 'pods_pods_field_related_output_type', [ $this, 'filter_output_type_ids' ] ); + } + + public static function get_meta_function( $action, $type ) { + switch ( $type ) { + case 'post_type': + case 'media': + $type = 'post'; + break; + case 'taxonomy': + $type = 'term'; + break; + } + return $action . '_' . $type . '_meta'; + } + + public static function get_id_key( $type ) { + $id_key = 'ID'; + switch ( $type ) { + case 'comment': + $id_key = 'comment_ID'; + break; + case 'term': + case 'taxonomy': + $id_key = 'term_id'; + break; + } + + return $id_key; + } + + public static function convert_output_type_ids( $list, $id_key ) { + if ( empty( $list ) ) { + return []; + } + + $return = []; + + foreach ( $list as $key => $value ) { + if ( ! is_array( $value ) ) { + $return[] = $value; + } elseif ( isset( $value[ $id_key ] ) ) { + $return[] = $value[ $id_key ]; + } + } + + return $return; + } + + public function filter_output_type_ids() { + return 'ids'; + } +} diff --git a/tests/js/pods-dfv/_setup.js b/tests/js/pods-dfv/_setup.js deleted file mode 100644 index 20954ed091..0000000000 --- a/tests/js/pods-dfv/_setup.js +++ /dev/null @@ -1,83 +0,0 @@ -require( 'jsdom-global' )( '', { beforeParse ( window ) { window.alert = function () {}; } } ); -global.jQuery = require( 'jquery' ); -global._ = require( 'underscore' ); -global.Backbone = require( 'backbone' ); -global.PodsMn = require( 'backbone.marionette' ); -global.sprintf = require( 'sprintf-js' ).sprintf; -global.assert = require( 'assert' ); -global.wp = { - media: { - view: { - Frame: { - extend: function(){} - }, - Modal: { - extend: function(){} - } - } - } -}; // Stubs - -//--!! We need to build the PodsI18n object as a module so it's importable -/*global podsLocalizedStrings */ -global.PodsI18n = ( function () { - - /** - * Only visible to the closure, not exposed externally. - * @param {string} str - * @returns {string} - */ - var translateString = function ( str ) { - var translated = str; - var ref; - - if ( 'undefined' !== typeof podsLocalizedStrings ) { - - /** - * Converts string into reference object variable - * Uses the same logic as PHP to create the same references - */ - ref = '__' + str; - - if ( 'undefined' !== typeof podsLocalizedStrings[ ref ] ) { - translated = podsLocalizedStrings[ ref ]; - } else if ( podsLocalizedStrings.debug ) { - console.log( 'PodsI18n: String not found "' + str + '" (reference used: "' + ref + '")' ); - } - } - - return translated; - }; - - /** - * The returned object, this is what we'll expose to the outside world - */ - return { - /** - * @param {string} str - * @returns {string} - */ - __: function ( str ) { - return translateString( str ); - }, - - /** - * @param {string} single - * @param {string} plural - * @param {number} number - * - * @returns {string} - */ - _n: function ( single, plural, number ) { - - // Unary + will implicitly cast to numeric - if ( +number === 1 ) { - return translateString( single ); - } - else { - return translateString( plural ); - } - }, - }; - -}()); diff --git a/tests/js/pods-dfv/file-upload/models/file-upload-model.js b/tests/js/pods-dfv/file-upload/models/file-upload-model.js deleted file mode 100644 index e59ce61299..0000000000 --- a/tests/js/pods-dfv/file-upload/models/file-upload-model.js +++ /dev/null @@ -1,42 +0,0 @@ -/*global jQuery, _, Backbone, Mn, assert */ -import {FileUploadCollection, FileUploadModel} from 'pods-dfv/_src/file-upload/file-upload-model'; - -const default_model = new FileUploadModel(); - -const test_data = { - id : 1, - icon : 'abc', - name : 'def', - edit_link: 'http://www.example.com/edit', - link : 'http://www.example.com/link', - download : 'http://www.example.com/download' -}; - -const test_model = new FileUploadModel( test_data ); -const collection = new FileUploadCollection( test_model ); - -describe( 'FileUploadModel', function () { - it( 'should have proper defaults', function () { - assert.equal( default_model.get( 'id' ), 0, 'id' ); - assert.equal( default_model.get( 'icon' ), '', 'icon' ); - assert.equal( default_model.get( 'name' ), '', 'name' ); - assert.equal( default_model.get( 'edit_link' ), '', 'edit_link' ); - assert.equal( default_model.get( 'link' ), '', 'link' ); - assert.equal( default_model.get( 'download' ), '', 'download' ); - } ); - - it( 'should have proper test values', function () { - assert.equal( test_model.get( 'id' ), test_data.id, 'id' ); - assert.equal( test_model.get( 'icon' ), test_data.icon, 'icon' ); - assert.equal( test_model.get( 'name' ), test_data.name, 'name' ); - assert.equal( test_model.get( 'edit_link' ), test_data.edit_link, 'edit_link' ); - assert.equal( test_model.get( 'link' ), test_data.link, 'link' ); - assert.equal( test_model.get( 'download' ), test_data.download, 'download' ); - } ); -} ); - -describe( 'FileUploadCollection', function () { - it( 'should have one model', function () { - assert.equal( collection.length, 1 ); - } ); -} ); diff --git a/tests/js/pods-dfv/file-upload/models/relationship-model.js b/tests/js/pods-dfv/file-upload/models/relationship-model.js deleted file mode 100644 index d5fa98c0cb..0000000000 --- a/tests/js/pods-dfv/file-upload/models/relationship-model.js +++ /dev/null @@ -1,42 +0,0 @@ -/*global jQuery, _, Backbone, Mn, assert */ -import {RelationshipCollection, RelationshipModel} from 'pods-dfv/_src/pick/relationship-model'; - -const default_model = new RelationshipModel(); - -const test_data = { - id : 1, - name : 'def', - icon : 'abc', - link : 'http://www.example.com/link', - edit_link : 'http://www.example.com/edit', - selected : true -}; - -const test_model = new RelationshipModel( test_data ); -const collection = new RelationshipCollection( test_model ); - -describe( 'RelationshipModel', function () { - it( 'should have proper defaults', function () { - assert.equal( default_model.get( 'id' ), 0, 'id' ); - assert.equal( default_model.get( 'name' ), '', 'name' ); - assert.equal( default_model.get( 'icon' ), '', 'icon' ); - assert.equal( default_model.get( 'link' ), '', 'link' ); - assert.equal( default_model.get( 'edit_link' ), '', 'edit_link' ); - assert.equal( default_model.get( 'selected' ), false, 'selected' ); - } ); - - it( 'should have proper test values', function () { - assert.equal( test_model.get( 'id' ), test_data.id, 'id' ); - assert.equal( test_model.get( 'name' ), test_data.name, 'name' ); - assert.equal( test_model.get( 'icon' ), test_data.icon, 'icon' ); - assert.equal( test_model.get( 'link' ), test_data.link, 'link' ); - assert.equal( test_model.get( 'edit_link' ), test_data.edit_link, 'edit_link' ); - assert.equal( test_model.get( 'selected' ), test_data.selected, 'selected' ); - } ); -} ); - -describe( 'RelationshipCollection', function () { - it( 'should have one model', function () { - assert.equal( collection.length, 1 ); - } ); -} ); diff --git a/tests/js/pods-dfv/pick/pick-spec.js b/tests/js/pods-dfv/pick/pick-spec.js deleted file mode 100644 index f7cea1b75d..0000000000 --- a/tests/js/pods-dfv/pick/pick-spec.js +++ /dev/null @@ -1,158 +0,0 @@ -/*global assert */ -import {PodsDFVFieldModel} from 'pods-dfv/_src/core/pods-field-model'; -import {Pick} from 'pods-dfv/_src/pick/pick'; - -/** - * Pick field tests - */ -describe( 'Pick field', function () { - let field, $el; - let fieldModel = new PodsDFVFieldModel(); - - /** - * Pre-test setup, before every it() - */ - beforeEach( function () { - jQuery( document.body ).append( '
            ' ); - $el = jQuery( '#target' ); - } ); - - /** - * Post-test clean-up, after every it() - */ - afterEach( function () { - jQuery( document.body ).empty(); - } ); - - /** - * - */ - it( 'Does not throw an exception with defaults', function () { - field = new Pick( { - el : $el, - model: fieldModel - } ); - - assert.doesNotThrow( field.render ); - } ); - - /** - * - */ - it( 'Throws an exception on invalid view name', function () { - fieldModel.set( 'fieldConfig', { view_name: 'not a view' } ); - - field = new Pick( { - el : $el, - model: fieldModel - } ); - assert.throws( field.render, Error ); - } ); - - /** - * Test pick_allow_add_new option - */ - it( "Does not show add new when it shouldn't", function () { - const add_new_not_allowed = [ - { - description: 'Default values (empty)', - options : {} - }, - { - description: 'Add new option as a string', - options : { - iframe_src : 'xxx', - pick_allow_add_new: '0' - } - }, - { - description: 'Add new option as a non 1/0 string', - options : { - iframe_src : 'xxx', - pick_allow_add_new: 'bob' - } - }, - { - description: 'Add new option as a number', - options : { - iframe_src : 'xxx', - pick_allow_add_new: 0 - } - }, - { - description: 'Add new option as a Boolean', - options : { - iframe_src : 'xxx', - pick_allow_add_new: false - } - }, - { - description: 'Add new allowed but no iframe source specified', - options : { - pick_allow_add_new: '1' - } - }, - ]; - - add_new_not_allowed.forEach( function ( thisOption ) { - const description = thisOption.description; - const options = thisOption.options; - - fieldModel.set( 'fieldConfig', options ); - - field = new Pick( { - el : $el, - model: fieldModel - } ); - - field.render(); - - assert.equal( $el.find( '.pods-related-add-new' ).length, 0, description ); - } ); - - } ); - - it( "Shows add new when it should", function () { - const add_new_allowed = [ - { - description: 'Add new option as a string', - options : { - iframe_src : 'xxx', - pick_allow_add_new: '1' - } - }, - { - description: 'Add new option as a number', - options : { - iframe_src : 'xxx', - pick_allow_add_new: 1 - } - }, - { - description: 'Add new option as a Boolean', - options : { - iframe_src : 'xxx', - pick_allow_add_new: true - } - }, - ]; - - add_new_allowed.forEach( function ( thisOption ) { - const description = thisOption.description; - const options = thisOption.options; - - fieldModel.set( 'fieldConfig', options ); - - field = new Pick( { - el : $el, - model: fieldModel - } ); - - field.render(); - - assert.equal( $el.find( '.pods-related-add-new' ).length, 1, description ); - } ); - - } ); - -} ); diff --git a/tests/js/pods-dfv/pick/views/checkbox-selection.limits.js b/tests/js/pods-dfv/pick/views/checkbox-selection.limits.js deleted file mode 100644 index 8a82fa37b1..0000000000 --- a/tests/js/pods-dfv/pick/views/checkbox-selection.limits.js +++ /dev/null @@ -1,212 +0,0 @@ -/*global assert */ -const inspect = require( 'util' ).inspect; - -import {CheckboxView} from 'pods-dfv/_src/pick/views/checkbox-view'; -import {PodsDFVFieldModel} from 'pods-dfv/_src/core/pods-field-model'; -import {RelationshipCollection} from 'pods-dfv/_src/pick/relationship-model'; - -const collection = new RelationshipCollection( [ - { id: 0, name: 'zero' }, - { id: 1, name: 'one' }, - { id: 2, name: 'two' }, - { id: 3, name: 'three' }, - { id: 4, name: 'four' }, - { id: 5, name: 'five' }, - { id: 6, name: 'six' }, - { id: 7, name: 'seven' }, - { id: 8, name: 'eight' }, - { id: 9, name: 'nine' }, -] ); - -const cases = [ - { - name: "Unlimited selections", - - fieldConfig: { - view_name : 'checkbox', - pick_format_type: 'multi', - pick_limit : 0 - }, - - steps: [ - { - desc : "Select the first checkbox", - targetItem : 0, - expectedValue : [ '0' ], - expectedDisabled: [] - }, - { - desc : "Select the second checkbox", - targetItem : 1, - expectedValue : [ '0', '1' ], - expectedDisabled: [] - }, - { - desc : "Select the third checkbox", - targetItem : 2, - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [] - }, - { - desc : "Select the fourth checkbox", - targetItem : 3, - expectedValue : [ '0', '1', '2', '3' ], - expectedDisabled: [] - }, - { - desc : "Deselect the first checkbox", - targetItem : 0, - expectedValue : [ '1', '2', '3' ], - expectedDisabled: [] - }, - { - desc : "Deselect the second checkbox", - targetItem : 1, - expectedValue : [ '2', '3' ], - expectedDisabled: [] - }, - { - desc : "Deselect the third checkbox", - targetItem : 2, - expectedValue : [ '3' ], - expectedDisabled: [] - }, - { - desc : "Deselect the fourth checkbox", - targetItem : 3, - expectedValue : [], - expectedDisabled: [] - } - ] - }, - { - name: "Limit 3", - - fieldConfig: { - view_name : 'checkbox', - pick_format_type: 'multi', - pick_limit : 3 - }, - - steps: [ - { - desc : "Select the first checkbox", - targetItem : 0, - expectedValue : [ '0' ], - expectedDisabled: [] - }, - { - desc : "Select the second checkbox", - targetItem : 1, - expectedValue : [ '0', '1' ], - expectedDisabled: [] - }, - { - desc : "Select the third checkbox, hit selection limit, disable other checkboxes", - targetItem : 2, - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [ '3', '4', '5', '6', '7', '8', '9' ] - }, - { - desc : "Limit 3, selecting the fourth checkbox should refuse", - targetItem : 3, - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [ '3', '4', '5', '6', '7', '8', '9' ] - }, - { - desc : "Deselect the third checkbox, disabled checkboxes should re-enable", - targetItem : 2, - expectedValue : [ '0', '1' ], - expectedDisabled: [] - }, - ] - } -]; - -// Main test entry point -describe( 'Checkbox Selection Limits', function () { - cases.forEach( function ( thisCase, index ) { - // Note: do not refactor the testCase function inline here, we need the closure of the function due to Mocha's - // asynch execution of it() blocks. - testCase( thisCase, collection, index ); - } ); -} ); - -/** - * - * @param {Object} thisCase - * @param {RelationshipCollection} collection - * @param {number} index - */ -function testCase( thisCase, collection, index ) { - // Note: this needs to be here, between the function and the it() block. Move it and you'll probably be sorry - const view = createView( thisCase.fieldConfig, collection, index ); - - // Test this case - it( thisCase.name, function () { - const containerID = `target-${index}`; - let $container; - - // Note: This setup cannout be placed outside the it() block. Mocha runs all it() blocks asynch - jQuery( document.body ).append( `` ); - $container = jQuery( `#${containerID}` ); - $container.append( view.$el ); - - // Loop through the steps for this case - thisCase.steps.forEach( function ( thisStep, stepIndex ) { - let $checkbox, value, disabled; - - // Perform the step and grab the state - view.$el.find( `input[type=checkbox][value=${thisStep.targetItem}]` ).trigger( 'click' ); - - value = view.$el.find( 'input[type=checkbox]:checked' ).map( function ( _, el ) { - return jQuery( el ).val(); - } ).get(); - disabled = view.$el.find( 'input[type=checkbox]:disabled' ).map( function () { - return this.value; - } ).toArray(); - - // Test value - assert.deepEqual( value, thisStep.expectedValue, - `\nStep: ${thisStep.desc}` + - `\nExpected value: ${inspect( thisStep.expectedValue )} ` + - `Actual value: ${inspect( value )}\n` - ); - - // Test checkboxes we expect to be disabled - assert.deepEqual( disabled, thisStep.expectedDisabled, - `\nStep: ${thisStep.desc}` + - `\nExpected disabled checkboxes: ${inspect( thisStep.expectedDisabled )} ` + - `Actual disabled checkboxes: ${inspect( disabled )}\n` - ); - } ); - - // Note: Tear-down for unique references must be inside the it() block. Mocha runs all it() blocks asynch - view.destroy(); - } ); -} - -/** - * - * @param {Object} fieldConfig - * @param {RelationshipCollection} collection - * @param {number} index - */ -function createView( fieldConfig, collection, index ) { - let fieldModel, view; - - fieldModel = new PodsDFVFieldModel( { - htmlAttr : { - id : `test-view-id-${index}`, - name: `test-view-name-${index}` - }, - fieldConfig: fieldConfig - } ); - - view = new CheckboxView( { - fieldModel: fieldModel, - collection: collection - } ).render(); - - return view; -} \ No newline at end of file diff --git a/tests/js/pods-dfv/pick/views/multiselect-selection-limits.js b/tests/js/pods-dfv/pick/views/multiselect-selection-limits.js deleted file mode 100644 index c2cd03cca0..0000000000 --- a/tests/js/pods-dfv/pick/views/multiselect-selection-limits.js +++ /dev/null @@ -1,253 +0,0 @@ -/*global assert */ -const inspect = require( 'util' ).inspect; - -import {SelectView} from 'pods-dfv/_src/pick/views/select-view'; -import {PodsDFVFieldModel} from 'pods-dfv/_src/core/pods-field-model'; -import {RelationshipCollection} from 'pods-dfv/_src/pick/relationship-model'; - -const collection = new RelationshipCollection( [ - { id: 0, name: 'zero' }, - { id: 1, name: 'one' }, - { id: 2, name: 'two' }, - { id: 3, name: 'three' }, - { id: 4, name: 'four' }, - { id: 5, name: 'five' }, - { id: 6, name: 'six' }, - { id: 7, name: 'seven' }, - { id: 8, name: 'eight' }, - { id: 9, name: 'nine' }, -] ); - -const cases = [ - { - name: "Unlimited, individual selection", - - fieldConfig: { - view_name : 'select', - pick_format_type: 'multi', - pick_limit : 0 - }, - - steps: [ - { - desc : "Select the first option", - optionIndexes : [ '0' ], - expectedValue : [ '0' ], - expectedDisabled: [] - }, - { - desc : "Select the second option", - optionIndexes : [ '1' ], - expectedValue : [ '0', '1' ], - expectedDisabled: [] - }, - { - desc : "Select the third option", - optionIndexes : [ '2' ], - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [] - }, - { - desc : "Select the fourth option", - optionIndexes : [ '3' ], - expectedValue : [ '0', '1', '2', '3' ], - expectedDisabled: [] - }, - { - desc : "Deselect the fourth option", - optionIndexes : [ '3' ], - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [] - } - ] - }, - { - name: "Limit 3, individual selection", - - fieldConfig: { - view_name : 'select', - pick_format_type: 'multi', - pick_limit : 3 - }, - - steps: [ - { - desc : "Select the first option", - optionIndexes : [ '0' ], - expectedValue : [ '0' ], - expectedDisabled: [] - }, - { - desc : "Select the second option", - optionIndexes : [ '1' ], - expectedValue : [ '0', '1' ], - expectedDisabled: [] - }, - { - desc : "Select the third option, reach limit, disable other options", - optionIndexes : [ '2' ], - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [ '3', '4', '5', '6', '7', '8', '9' ] - }, - { - desc : "Limit 3, the fourth option should be refused", - optionIndexes : [ '3' ], - expectedValue : [ '0', '1', '2' ], - expectedDisabled: [ '3', '4', '5', '6', '7', '8', '9' ] - }, - { - desc : "Deselect first option, should clear diabled options", - optionIndexes : [ '0' ], - expectedValue : [ '1', '2' ], - expectedDisabled: [] - }, - { - desc : "Deselect second option", - optionIndexes : [ '1' ], - expectedValue : [ '2' ], - expectedDisabled: [] - }, - { - desc : "Deselect third option, selection should be empty again", - optionIndexes : [ '2' ], - expectedValue : null, // Note: behavior for val() changes to an empty array in jQuery 3.0 - expectedDisabled: [] - } - ] - }, - { - name: "Limit 3, multiple selection", - - fieldConfig: { - view_name : 'select', - pick_format_type: 'multi', - pick_limit : 3 - }, - - steps: [ - { - desc : "Select five items, should be refused", - optionIndexes : [ '0', '1', '2', '3', '4' ], - expectedValue : null, // Note: behavior for val() changes to an empty array in jQuery 3.0 - expectedDisabled: [] - }, - { - desc : "Select two staggered items", - optionIndexes : [ '0', '2' ], - expectedValue : [ '0', '2' ], - expectedDisabled: [] - }, - { - desc : "Attempt to select three more options, should refuse and revert to last good value", - optionIndexes : [ '7', '8', '9' ], - expectedValue : [ '0', '2' ], - expectedDisabled: [] - } - ] - } -]; - -// Main test entry point -describe( 'Multiselect Selection Limits', function () { - cases.forEach( function ( thisCase, index ) { - // Note: do not refactor the testCase function inline here, we need the closure of the function due to Mocha's - // asynch execution of it() blocks. - testCase( thisCase, collection, index ); - } ); -} ); - -/** - * - * @param {Object} thisCase - * @param {RelationshipCollection} collection - * @param {number} index - */ -function testCase( thisCase, collection, index ) { - // Note: this needs to be here, between the function and the it() block. Move it and you'll probably be sorry - const view = createView( thisCase.fieldConfig, collection, index ); - - // Test this case - it( thisCase.name, function () { - const containerID = `target-${index}`; - let $container; - - // Note: This setup cannout be placed outside the it() block. Mocha runs all it() blocks asynch - jQuery( document.body ).append( `
            ` ); - $container = jQuery( `#${containerID}` ); - $container.append( view.$el ); - - // Loop through the steps for this case - thisCase.steps.forEach( function ( thisStep, stepIndex ) { - let value, disabled; - - // Perform the step and grab the state - doStep( thisStep, view ); - - value = view.$el.val(); - disabled = view.$el.find( 'option:disabled' ).map( function () { - return this.value; - } ).toArray(); - - // Check value - assert.deepEqual( value, thisStep.expectedValue, - `\nStep: ${thisStep.desc}` + - `\nExpected value: ${inspect( thisStep.expectedValue )} ` + - `Actual value: ${inspect( value )}\n` - ); - - // Check options we expect to be disabled - assert.deepEqual( disabled, thisStep.expectedDisabled, - `\nStep: ${thisStep.desc}` + - `\nExpected disabled options: ${inspect( thisStep.expectedDisabled )} ` + - `Actual disabled options: ${inspect( disabled )}\n` - ); - } ); - - // Note: Tear-down for unique references must be inside the it() block. Mocha runs all it() blocks asynch - view.destroy(); - } ); -} - -/** - * - * @param {Object} thisStep - * @param {Object} view - */ -function doStep( thisStep, view ) { - - // Attempt to "click" (toggle) the specified options, one at a time - thisStep.optionIndexes.forEach( function ( thisIndex ) { - const $option = view.$el.find( `option:eq( ${thisIndex} )` ); - - // Respect disabled options, cannot be clicked in the UI and we're vaguely simulating mouse clicks - if ( !$option.prop( 'disabled' ) ) { - $option.prop( 'selected', !$option.prop( 'selected' ) ); - } - } ); - view.$el.focus().change(); -} - -/** - * - * @param {Object} fieldConfig - * @param {RelationshipCollection} collection - * @param {number} index - */ -function createView( fieldConfig, collection, index ) { - let fieldModel, view; - - fieldModel = new PodsDFVFieldModel( { - htmlAttr : { - id : `test-view-id-${index}`, - name: `test-view-name-${index}` - }, - fieldConfig: fieldConfig - } ); - - view = new SelectView( { - fieldModel: fieldModel, - collection: collection - } ).render(); - - return view; -} \ No newline at end of file diff --git a/tests/js/pods-dfv/pick/views/select-view.js b/tests/js/pods-dfv/pick/views/select-view.js deleted file mode 100644 index ca47291dc2..0000000000 --- a/tests/js/pods-dfv/pick/views/select-view.js +++ /dev/null @@ -1,51 +0,0 @@ -/*global assert */ -import {SelectView} from 'pods-dfv/_src/pick/views/select-view'; -import {PodsDFVFieldModel} from 'pods-dfv/_src/core/pods-field-model'; -import {RelationshipCollection} from 'pods-dfv/_src/pick/relationship-model'; - -let pickFormatTypes = [ - { type: 'single', isMultiple: false }, - { type: 'multi', isMultiple: true } -]; - -/** - * SelectView tests - */ -describe( 'SelectView', function () { - let view; - let fieldModel = new PodsDFVFieldModel(); - let collection = new RelationshipCollection(); - - /** - * Post-test clean-up, after every it() - */ - afterEach( function () { - jQuery( document.body ).empty(); - - if ( view instanceof Backbone.View ) { - view.destroy(); - } - } ); - - /** - * Test single/multi select - */ - pickFormatTypes.forEach( function ( thisFormatType ) { - let multiple; - - it( 'respects ' + thisFormatType.type + ' select', function () { - fieldModel.set( 'fieldConfig', { pick_format_type: thisFormatType.type } ); - - view = new SelectView( { - fieldModel: fieldModel - } ); - view.render(); - jQuery( document.body ).append( view.$el ); - - multiple = jQuery( 'select' ).prop( 'multiple' ); - assert.equal( multiple, thisFormatType.isMultiple ); - } ); - } ); - -} ); - diff --git a/tests/phpunit/README.md b/tests/phpunit/README.md deleted file mode 100755 index 4d2d10b8f1..0000000000 --- a/tests/phpunit/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Pods Framework Unit Tests [![Build Status](https://secure.travis-ci.org/pods-framework/pods.png?branch=master)](http://travis-ci.org/pods-framework/pods) [![Coverage Status](https://coveralls.io/repos/pods-framework/pods/badge.png)](https://coveralls.io/r/pods-framework/pods) # - -This folder contains all the tests for Pods Framework. - -For more information on how to write PHPUnit Tests, see [PHPUnit's Website](http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html). - -## Local environment variables to set - -* `export WP_DEVELOP_DIR=/srv/www/wordpress-develop` -* `export WP_TESTS_DIR=/srv/www/wordpress-develop/tests/phpunit` - -## Running locally via VVV - -1. `cd /path/to/vvv/folder` -1. `vagrant ssh` -1. `cd /srv/www/path/to/pods/folder` -1. `composer install` -1. `./bin/vagrant-wp-tests.sh; ./vendor/bin/phpunit` (run this each time you want to test) - -## Running locally (other servers) - -1. `cd /path/to/pods/folder` -1. `composer install` -1. `./bin/install-wp-tests.sh wordpress_test root '' localhost latest; ./vendor/bin/phpunit` (run this each time you want to test) \ No newline at end of file diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php deleted file mode 100755 index d8d29e48bc..0000000000 --- a/tests/phpunit/bootstrap.php +++ /dev/null @@ -1,64 +0,0 @@ -set_role( 'administrator' ); - -$classLoader = require PODS_TEST_PLUGIN_DIR . '/vendor/autoload.php'; -$classLoader->addPsr4( 'Pods_Unit_Tests\\', dirname( __FILE__ ) . '/includes', true ); - diff --git a/tests/phpunit/clover.xml b/tests/phpunit/clover.xml deleted file mode 100644 index ab368d8bb7..0000000000 --- a/tests/phpunit/clover.xml +++ /dev/null @@ -1,2171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/phpunit/includes/Bugs/Test_4097.php b/tests/phpunit/includes/Bugs/Test_4097.php deleted file mode 100644 index 7d422f9776..0000000000 --- a/tests/phpunit/includes/Bugs/Test_4097.php +++ /dev/null @@ -1,112 +0,0 @@ -pod_name . '_' . substr( $storage, 2 ) . '_' . substr( $type, 2 ); - $this->pod_id = pods_api()->save_pod( - array( - 'storage' => $storage, - 'type' => $type, - 'name' => $pod_name, - ) - ); - - $params = array( - 'pod' => $pod_name, - 'pod_id' => $this->pod_id, - 'name' => 'color', - 'type' => 'pick', - 'pick_object' => 'custom-simple', - 'pick_custom' => "yellow|Kollane\ngreen|Roheline\nbrown|Pruun\nred|Punane\n", - 'pick_format_type' => 'multi', - 'pick_format_multi' => 'checkbox', - ); - pods_api()->save_field( $params ); - - return $pod_name; - } - - public function tearDown() { - - if ( isset( $this->pod_id ) ) { - pods_api()->delete_pod( array( 'id' => $this->pod_id ) ); - $this->pod_id = null; - } - } - - /** - * @param $type - * @param $storage - */ - public function run_test( $type, $storage ) { - - $pod_name = $this->setup_pod( $type, $storage ); - $pod = pods( $pod_name ); - $id = $pod->add( - array( - 'color' => array( - 0 => 'green', - 1 => 'brown', - 2 => 'red', - ), - ) - ); - $pod->fetch( $id ); - $value = $pod->display( 'color' ); - $this->assertEquals( 'Roheline, Pruun, and Punane', $value ); - - $id = $pod->add( - array( - 'color' => array( - 2 => 'green', - 3 => 'brown', - 4 => 'red', - ), - ) - ); - $pod->fetch( $id ); - $value = $pod->display( 'color' ); - $this->assertEquals( 'Roheline, Pruun, and Punane', $value ); - - $id = $pod->add( array( 'color' => array( 'yellow', 'green', 'brown', 'red' ) ) ); - $pod->fetch( $id ); - $value = $pod->display( 'color' ); - - $this->assertEquals( 'Kollane, Roheline, Pruun, and Punane', $value ); - } - - public function test_cpt() { - - $this->run_test( 'meta', 'post_type' ); - } - - public function test_cpt_table() { - - $this->run_test( 'table', 'post_type' ); - } - - public function test_act() { - - $this->run_test( 'table', 'pod' ); - } - -} diff --git a/tests/phpunit/includes/Bugs/Test_5254.php b/tests/phpunit/includes/Bugs/Test_5254.php deleted file mode 100644 index 4d41a7990f..0000000000 --- a/tests/phpunit/includes/Bugs/Test_5254.php +++ /dev/null @@ -1,30 +0,0 @@ -assertFalse( $result ); - - $params = array( 'bypass_helpers' => false ); - $result = pods_str_replace( '@wp_', '{prefix}', $params ); - $this->assertFalse( $result['bypass_helpers'] ); - - $params = array( 'nested' => array( 'bypass_helpers' => false ) ); - $result = pods_str_replace( '@wp_', '{prefix}', $params ); - $this->assertFalse( $result['nested']['bypass_helpers'] ); - - } -} diff --git a/tests/phpunit/includes/Bugs/Test_5476.php b/tests/phpunit/includes/Bugs/Test_5476.php deleted file mode 100644 index bde97e5429..0000000000 --- a/tests/phpunit/includes/Bugs/Test_5476.php +++ /dev/null @@ -1,34 +0,0 @@ -load(); - $active = $components->activate_component('migrate-packages'); - $this->assertTrue( $active ); - - // The WordPress test framework rolls back during tearDown, so we can safely delete the data without affecting other tests - pods_api()->delete_pod( 'page' ); - - $migrate = $components->components['migrate-packages']['object']; - $result = $migrate->import( $import ); - $this->assertNotFalse( $result ); - - $pod = pods( 'page' ); - $id = $pod->add( array( 'banana' => 'This failure is brought to you by migrate-packages' ) ); - $pod->fetch( $id ); - $value = $pod->display('banana'); - $this->assertEquals( 'This failure is brought to you by migrate-packages', $value ); - - } -} diff --git a/tests/phpunit/includes/Bugs/Test_5909.php b/tests/phpunit/includes/Bugs/Test_5909.php deleted file mode 100644 index d6ab595ef6..0000000000 --- a/tests/phpunit/includes/Bugs/Test_5909.php +++ /dev/null @@ -1,39 +0,0 @@ -save_pod( $params ); - - // Fetch the stored data. - $pod = pods( 'sanitize5909' ); - - $this->assertEquals( $where, $pod->fields['rel']['options']['pick_where'] ); - } -} diff --git a/tests/phpunit/includes/Meta/Test_Metadata.php b/tests/phpunit/includes/Meta/Test_Metadata.php deleted file mode 100644 index ac5986f3af..0000000000 --- a/tests/phpunit/includes/Meta/Test_Metadata.php +++ /dev/null @@ -1,465 +0,0 @@ - 'post_meta', - 'taxonomy' => 'term_meta', - // Name should be equal as WP object name. - 'comment' => 'comment', - 'user' => 'user', - ); - - protected static $obj_ids = array(); - - public static function wpSetUpBeforeClass() { - - self::create_pods(); - // Reload PodsMeta. - pods_meta()->core(); - - self::load_pods(); - } - - /*public function setUp() { - parent::setUp(); - - self::create_pods(); - self::load_pods(); - }*/ - - public static function wpTearDownAfterClass() { - foreach ( self::$pod_names as $type => $name ) { - if ( in_array( $name, array( 'comment', 'user' ), true ) ){ - continue; - } - // Delete all pod objects as well. - $delete_all = true; - pods_api()->delete_pod( $name, false, $delete_all ); - } - } - - public static function create_pods() { - - foreach ( self::$pod_names as $type => $name ) { - - $pod_id = pods_api()->save_pod( - array( - 'storage' => 'meta', - 'type' => $type, - 'name' => $name, - ) - ); - - $params = array( - 'pod' => $name, - 'pod_id' => $pod_id, - 'name' => 'text', - 'type' => 'text', - ); - pods_api()->save_field( $params ); - - $params = array( - 'pod' => $name, - 'pod_id' => $pod_id, - 'name' => 'images', - 'type' => 'file', - 'file_format_type' => 'multi', - ); - pods_api()->save_field( $params ); - - $params = array( - 'pod' => $name, - 'pod_id' => $pod_id, - 'name' => 'related_single', - 'type' => 'pick', - 'pick_object' => $type, - 'pick_val' => $name, - 'pick_format_type' => 'single', - ); - pods_api()->save_field( $params ); - - $params = array( - 'pod' => $name, - 'pod_id' => $pod_id, - 'name' => 'related_multi', - 'type' => 'pick', - 'pick_object' => $type, - 'pick_val' => $name, - 'pick_format_type' => 'multi', - ); - pods_api()->save_field( $params ); - - // PR #5665 - $params = array( - 'pod' => $name, - 'pod_id' => $pod_id, - 'name' => 'slash', - 'type' => 'text', - ); - pods_api()->save_field( $params ); - $params = array( - 'pod' => $name, - 'pod_id' => $pod_id, - 'name' => 'quotes', - 'type' => 'text', - ); - pods_api()->save_field( $params ); - } - } - - public static function load_pods() { - - foreach ( self::$pod_names as $type => $name ) { - - $objects = array( - 'test 1', - 'test 2', - 'test 3', - ); - - foreach ( $objects as $key => $object ) { - $title = $object; - $object = array(); - $id_key = 'ID'; - $id = 0; - switch ( $type ) { - case 'post_type': - $object['post_title'] = $title; - $object['post_status'] = 'publish'; - $object['post_type'] = $name; - - $id = self::factory()->post->create( $object ); - break; - case 'taxonomy': - $object['taxonomy'] = $name; - $object['name'] = $title; - - $id = self::factory()->term->create( $object ); - break; - case 'user': - $login = str_replace( '-', '', sanitize_title_with_dashes( $title ) ); - $object['user_login'] = $login; - $object['user_pass'] = $login; - $object['user_email'] = $login . '@test.local'; - - $id = self::factory()->user->create( $object ); - break; - case 'comment': - $object['comment_content'] = $title; - $object['comment_approved'] = 1; - - $id = self::factory()->comment->create( $object ); - break; - } - - if ( ! is_numeric( $id ) ) { - $id = pods_v( self::get_id_key( $type ), $id, $id ); - } - $objects[ $key ] = $id; - } - - self::$obj_ids[ $type ] = $objects; - - foreach ( $objects as $key => $id ) { - $data = array(); - - switch ( $key ) { - case 0: - $data = array( - 'text' => 'text', - 'images' => self::get_images(), - // No relationship fields. - - // PR #5665 - 'slash' => 'Test \backslash', - 'quotes' => 'Test \'quotes\' "doublequotes"', - ); - break; - case 1: - $data = array( - 'related_single' => $objects[ 2 ], - // Single multi relationship. - 'related_multi' => $objects[ 2 ], - ); - break; - case 2: - $data = array( - 'related_single' => $objects[ 1 ], - 'related_multi' => array( $objects[ 0 ], $objects[ 1 ] ), - ); - break; - } - - $pod = pods( $name, $id ); - $pod->save( $data ); - } - } - } - - public static function get_images() { - static $images = null; - if ( ! $images ) { - $images = array( - self::factory()->attachment->create(), - self::factory()->attachment->create(), - ); - } - return $images; - } - - public function test_created_pods() { - - foreach( self::$pod_names as $type => $name ) { - $pod = pods( $name ); - $this->assertNotFalse( $pod->valid() ); - $this->assertNotEmpty( self::$obj_ids[ $type ] ); - } - } - - public function test_get_metadata() { - - foreach ( self::$obj_ids as $type => $ids ) { - - $id_key = self::get_id_key( $type ); - $name = self::$pod_names[ $type ]; - $get_meta = self::get_meta_function( 'get', $type ); - - foreach ( $ids as $key => $id ) { - - $single = call_user_func( $get_meta, $id, 'related_single', false ); - $single_single = call_user_func( $get_meta, $id, 'related_single', true ); - $multi = call_user_func( $get_meta, $id, 'related_multi', false ); - $multi_single = call_user_func( $get_meta, $id, 'related_multi', true ); - - // Pods returns object arrays by default. Fetch the ID's of these objects. - $single = self::convert_output_type_ids( $single, $id_key ); - $multi = self::convert_output_type_ids( $multi, $id_key ); - $single_single = isset( $single_single[ $id_key ] ) ? $single_single[ $id_key ] : $single_single; - $multi_single = isset( $multi_single[ $id_key ] ) ? $multi_single[ $id_key ] : $multi_single; - - // Add a bit of context when an assertion has failed. - $message = "Method: `{$get_meta}()`:"; - - switch ( $key ) { - case 0: - - $images = self::get_images(); - - // Single param false - $value = call_user_func( $get_meta, $id, 'text', false ); - $this->assertEquals( array( 'text' ), $value, $message ); - - $value = call_user_func( $get_meta, $id, 'images', false ); - $value = self::convert_output_type_ids( $value, 'ID' ); - $this->assertEquals( $images, $value, $message ); - - $this->assertEquals( array(), $single, $message ); - $this->assertEquals( array(), $multi, $message ); - - // Single param true - $value = call_user_func( $get_meta, $id, 'text', true ); - $this->assertEquals( 'text', $value, $message ); - - $value = call_user_func( $get_meta, $id, 'images', true ); - $value = isset( $value[ 'ID' ] ) ? $value[ 'ID' ] : $value; - $this->assertEquals( $images[0], $value, $message ); - - $this->assertEquals( '', $single_single, $message ); - $this->assertEquals( '', $multi_single, $message ); - - // PR #5665 - $value = call_user_func( $get_meta, $id, 'slash', true ); - $this->assertEquals( 'Test \backslash', $value, $message ); - $value = call_user_func( $get_meta, $id, 'quotes', true ); - $this->assertEquals( 'Test \'quotes\' "doublequotes"', $value, $message ); - - break; - case 1: - // Single related to: 2 - // Multi related to: 2 - - $single_rel = $ids[ 2 ]; - $multi_rel = $ids[ 2 ]; - - // Single param false - $this->assertEquals( array( $single_rel ), $single, $message ); - $this->assertEquals( array( $multi_rel ), $multi, $message ); - - // Single param true - $this->assertEquals( $single_rel, $single_single, $message ); - $this->assertEquals( $multi_rel, $multi_single, $message ); - - break; - case 2: - // Single related to: 1 - // Multi related to: 0 and 1 - - $single_rel = $ids[ 1 ]; - $multi_rel = array( - $ids[ 0 ], - $ids[ 1 ] - ); - - // Single param false - $this->assertEquals( array( $single_rel ), $single, $message ); - $this->assertEquals( $multi_rel, $multi, $message ); - - // Single param true - $this->assertEquals( $single_rel, $single_single, $message ); - // Even when having multiple values, if single is true then it should return the first value. - $this->assertEquals( $multi_rel[0], $multi_single, $message ); - - break; - } - - } - - } - } - - public function test_get_metadata_ids() { - - // Make sure we return ID's. - add_filter( 'pods_pods_field_related_output_type', array( $this, 'filter_output_type_ids' ) ); - //remove_filter( 'get_post_metadata', array( pods_meta(), 'get_post_meta' ), 10 ); - - foreach ( self::$obj_ids as $type => $ids ) { - - $name = self::$pod_names[ $type ]; - $get_meta = self::get_meta_function( 'get', $type ); - - foreach ( $ids as $key => $id ) { - - $single = call_user_func( $get_meta, $id, 'related_single', false ); - $single_single = call_user_func( $get_meta, $id, 'related_single', true ); - $multi = call_user_func( $get_meta, $id, 'related_multi', false ); - $multi_single = call_user_func( $get_meta, $id, 'related_multi', true ); - - // Add a bit of context when a assertion has failed. - $message = "Method: `{$get_meta}()`:"; - - switch ( $key ) { - case 0: - - $images = self::get_images(); - - // Single param false - $value = call_user_func( $get_meta, $id, 'text', false ); - $this->assertEquals( array( 'text' ), $value, $message ); - - $value = call_user_func( $get_meta, $id, 'images', false ); - $this->assertEquals( $images, $value, $message ); - - $this->assertEquals( array(), $single, $message ); - $this->assertEquals( array(), $multi, $message ); - - // Single param true - $value = call_user_func( $get_meta, $id, 'text', true ); - $this->assertEquals( 'text', $value, $message ); - - $value = call_user_func( $get_meta, $id, 'images', true ); - $this->assertEquals( $images[0], $value, $message ); - - $this->assertEquals( '', $single_single, $message ); - $this->assertEquals( '', $multi_single, $message ); - - break; - case 1: - // Single related to: 2 - // Multi related to: 2 - - $single_rel = $ids[ 2 ]; - $multi_rel = $ids[ 2 ]; - - // Single param false - $this->assertEquals( array( $single_rel ), $single, $message ); - $this->assertEquals( array( $multi_rel ), $multi, $message ); - - // Single param true - $this->assertEquals( $single_rel, $single_single, $message ); - $this->assertEquals( $multi_rel, $multi_single, $message ); - - break; - case 2: - // Single related to: 1 - // Multi related to: 0 and 1 - - $single_rel = $ids[ 1 ]; - $multi_rel = array( - $ids[ 0 ], - $ids[ 1 ] - ); - - // Single param false - $this->assertEquals( array( $single_rel ), $single, $message ); - $this->assertEquals( $multi_rel, $multi, $message ); - - // Single param true - $this->assertEquals( $single_rel, $single_single, $message ); - // Even when having multiple values, if single is true then it should return the first value. - $this->assertEquals( $multi_rel[0], $multi_single, $message ); - - break; - } - - } - - } - - remove_filter( 'pods_pods_field_related_output_type', array( $this, 'filter_output_type_ids' ) ); - } - - public static function get_meta_function( $action, $type ) { - switch ( $type ) { - case 'post_type': - $type = 'post'; - break; - case 'taxonomy': - $type = 'term'; - break; - } - return $action . '_' . $type . '_meta'; - } - - public static function get_id_key( $type ) { - $id_key = 'ID'; - switch ( $type ) { - case 'comment': - $id_key = 'comment_ID'; - break; - case 'term': - case 'taxonomy': - $id_key = 'term_id'; - break; - } - return $id_key; - } - - public static function convert_output_type_ids( $list, $id_key ) { - foreach ( $list as $key => $value ) { - if ( isset( $value[ $id_key ] ) ) { - $list[ $key ] = $value[ $id_key ]; - } - } - return $list; - } - - public function filter_output_type_ids() { - return 'ids'; - } -} diff --git a/tests/phpunit/includes/Shortcodes/Test_Each.php b/tests/phpunit/includes/Shortcodes/Test_Each.php deleted file mode 100644 index e94359f9e1..0000000000 --- a/tests/phpunit/includes/Shortcodes/Test_Each.php +++ /dev/null @@ -1,238 +0,0 @@ -save_pod( - array( - 'storage' => 'meta', - 'type' => 'post_type', - 'name' => self::$pod_name, - ) - ); - - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'number1', - 'type' => 'number', - ); - - pods_api()->save_field( $params ); - - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'number2', - 'type' => 'number', - ); - - pods_api()->save_field( $params ); - - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'images', - 'type' => 'file', - 'file_format_type' => 'multi', - 'file_type' => 'images', - ); - - pods_api()->save_field( $params ); - - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'related_field', - 'type' => 'pick', - 'pick_object' => 'post_type', - 'pick_val' => self::$pod_name, - 'pick_format_type' => 'multi', - ); - - pods_api()->save_field( $params ); - - } - - public static function wpTearDownAfterClass() { - - if ( shortcode_exists( 'test_each_recurse' ) ) { - remove_shortcode( 'test_each_recurse' ); - } - pods_api()->delete_pod( array( 'id' => self::$pod_id ) ); - - } - - public function test_psuedo_shortcodes() { - - // Make sure our pseudo shortcodes are working properly - $this->assertEquals( 'abc123', do_shortcode( '[test_each_recurse]abc123[/test_each_recurse]' ) ); - } - - public function test_each_simple() { - - $pod_name = self::$pod_name; - $sub_ids = array(); - $pod = pods( $pod_name ); - for ( $x = 1; $x <= 5; $x ++ ) { - $sub_ids[] = $pod->add( - array( - 'post_status' => 'publish', - 'name' => $x, - 'number1' => $x, - 'number2' => $x * $x, - ) - ); - } - $main_id = $pod->add( - array( - 'post_status' => 'publish', - 'name' => 'main post', - 'number1' => 123, - 'number2' => 456, - 'related_field' => $sub_ids, - ) - ); - $content = base64_encode( '{@number1}_{@number2}' ); - $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_sub_template]" ) ); - - /** - * Image tests. - */ - - $image_ids = array(); - $image_ids[] = $this->factory()->attachment->create(); - $image_ids[] = $this->factory()->attachment->create(); - $image_ids[] = $this->factory()->attachment->create(); - - $main_id = $pod->save( - array( - 'ID' => $main_id, - 'images' => $image_ids, - ) - ); - - $content = base64_encode( '{@_src}' ); - $compare = ''; - foreach ( $image_ids as $img ) { - $compare .= pods_image_url( $img, 'medium' ); - } - - // Make sure the media Pod exists. - // @todo Validate when there is not media Pod active. Requires refactor of caching. - $this->assertTrue( pods( 'media' )->valid() ); - - // Should return all image links. - $this->assertEquals( $compare, do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='images']{$content}[/pod_sub_template]" ) ); - - // Use media object for Pod related fields. - $content = base64_encode( '{@title}' ); - $compare = ''; - foreach ( $image_ids as $img ) { - $compare .= get_the_title( $img ); - } - - // Should still return all image links. - $this->assertEquals( $compare, do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='images']{$content}[/pod_sub_template]" ) ); - } - - public function test_each_with_nested_if() { - - $pod_name = self::$pod_name; - $sub_ids = array(); - $pod = pods( $pod_name ); - for ( $x = 1; $x <= 5; $x ++ ) { - $sub_ids[] = $pod->add( - array( - 'post_status' => 'publish', - 'name' => $x, - 'number1' => $x, - 'number2' => $x * $x, - ) - ); - } - $main_id = $pod->add( - array( - 'post_status' => 'publish', - 'name' => 'main post', - 'number1' => 123, - 'number2' => 456, - 'related_field' => $sub_ids, - ) - ); - $content = base64_encode( '[if number1]{@number1}_{@number2}[/if]' ); - $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_sub_template]" ) ); - // Testing [each] inside [if] - $inner_content = base64_encode( '[if number1]{@number1}_{@number2}[/if]' ); - $content = base64_encode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$inner_content}[/pod_sub_template]" ); - $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_if_field]" ) ); - - // Testing [each] inside [if] with [else] - $inner_content = base64_encode( '[if number1]{@number1}_{@number2}[/if]' ); - $content = base64_encode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$inner_content}[/pod_sub_template][else]No related field" ); - $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_if_field]" ) ); - - // Testing [each] inside [if] with [else] and no relationships - $main_id = $pod->add( - array( - 'post_status' => 'publish', - 'name' => 'post with no related fields', - 'number1' => 123, - 'number2' => 456, - ) - ); - $inner_content = base64_encode( '[if number1]{@number1}_{@number2}[/if]' ); - $content = base64_encode( "[pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$inner_content}[/pod_sub_template][else]No related field" ); - $this->assertEquals( 'No related field', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_if_field]" ) ); - } - - public function test_each_nested_in_external() { - - $pod_name = self::$pod_name; - $sub_ids = array(); - $pod = pods( $pod_name ); - for ( $x = 1; $x <= 5; $x ++ ) { - $sub_ids[] = $pod->add( - array( - 'post_status' => 'publish', - 'name' => $x, - 'number1' => $x, - 'number2' => $x * $x, - ) - ); - } - $main_id = $pod->add( - array( - 'post_status' => 'publish', - 'name' => 'main post', - 'number1' => 123, - 'number2' => 456, - 'related_field' => $sub_ids, - ) - ); - $content = base64_encode( '{@number1}_{@number2}' ); - $this->assertEquals( '1_12_43_94_165_25', do_shortcode( "[test_each_recurse][pod_sub_template pod='{$pod_name}' id='{$main_id}' field='related_field']{$content}[/pod_sub_template][/test_each_recurse]" ) ); - } -} diff --git a/tests/phpunit/includes/Shortcodes/Test_If.php b/tests/phpunit/includes/Shortcodes/Test_If.php deleted file mode 100644 index 8eb5926dbb..0000000000 --- a/tests/phpunit/includes/Shortcodes/Test_If.php +++ /dev/null @@ -1,238 +0,0 @@ -save_pod( - array( - 'storage' => 'meta', - 'type' => 'post_type', - 'name' => self::$pod_name, - ) - ); - - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'number1', - 'type' => 'number', - ); - pods_api()->save_field( $params ); - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'number2', - 'type' => 'number', - ); - pods_api()->save_field( $params ); - $params = array( - 'pod' => self::$pod_name, - 'pod_id' => self::$pod_id, - 'name' => 'related_field', - 'type' => 'pick', - 'pick_object' => 'post_type', - 'pick_val' => self::$pod_name, - 'pick_format_type' => 'single', - ); - pods_api()->save_field( $params ); - - } - - public static function wpTearDownAfterClass() { - - if ( shortcode_exists( 'test_if_text' ) ) { - remove_shortcode( 'test_if_text' ); - } - if ( shortcode_exists( 'test_if_recurse' ) ) { - remove_shortcode( 'test_if_recurse' ); - } - pods_api()->delete_pod( array( 'id' => self::$pod_id ) ); - - } - - public function test_psuedo_shortcodes() { - - // Make sure our pseudo shortcodes are working properly - $this->assertEquals( 'abc123', do_shortcode( '[test_if_text]' ) ); - $this->assertEquals( 'abc123', do_shortcode( '[test_if_recurse][test_if_text][/test_if_recurse]' ) ); - } - - public function test_if_simple() { - - $pod_name = self::$pod_name; - $id = pods( $pod_name )->add( - array( - 'name' => __FUNCTION__ . '1', - 'number1' => 123, - 'number2' => 456, - ) - ); - $content = base64_encode( 'ABC' ); - $this->assertEquals( 'ABC', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - $content = base64_encode( 'ABC[else]DEF' ); - $this->assertEquals( 'ABC', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - $this->assertNotEquals( 'DEF', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - - $id = pods( $pod_name )->add( - array( - 'name' => __FUNCTION__ . '2', - 'number1' => 456, - 'number2' => 0, - ) - ); - $content = base64_encode( 'ABC' ); - $this->assertNotEquals( 'ABC', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$content}[/pod_if_field]" ) ); - $this->assertNotEquals( 'ABC', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='invalidfield']{$content}[/pod_if_field]" ) ); - $content = base64_encode( 'ABC[else]DEF' ); - $this->assertEquals( 'DEF', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$content}[/pod_if_field]" ) ); - $this->assertEquals( 'DEF', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='invalidfield']{$content}[/pod_if_field]" ) ); - $this->assertNotEquals( 'ABC', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$content}[/pod_if_field]" ) ); - } - - public function test_if_nested() { - - $pod_name = self::$pod_name; - $id = pods( $pod_name )->add( - array( - 'name' => __FUNCTION__ . '1', - 'number1' => 123, - 'number2' => 456, - ) - ); - $inner_content = base64_encode( 'XYZ' ); - $content = base64_encode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$inner_content}[/pod_if_field]" ); - $this->assertEquals( 'XYZ', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - - $inner_content = base64_encode( 'XYZ' ); - $content = base64_encode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$inner_content}[/pod_if_field]" ); - $this->assertEquals( 'XYZ', do_shortcode( "[test_if_recurse][pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field][/test_if_recurse]" ) ); - - $this->markTestIncomplete( 'Nested shortcodes currently broken, test disabled until issue resolved' ); - $inner_content = base64_encode( '[test_if_recurse]XYZ[/test_if_recurse]' ); - $content = base64_encode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$inner_content}[/pod_if_field]" ); - $this->assertEquals( 'XYZ', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - - } - - public function test_if_nested_external_shortcodes() { - - $this->markTestIncomplete( 'Nested shortcodes currently broken, test disabled until issue resolved' ); - - $pod_name = self::$pod_name; - $id = pods( $pod_name )->add( - array( - 'name' => __FUNCTION__ . '1', - 'number1' => 123, - 'number2' => 456, - ) - ); - $content = base64_encode( '[test_if_text][else]INVALID' ); - $this->assertEquals( 'abc123', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - } - - public function test_if_with_magic_tags() { - - $pod_name = self::$pod_name; - $id = pods( $pod_name )->add( - array( - 'name' => 'my post title', - 'number1' => 123, - 'number2' => 456, - ) - ); - $content = base64_encode( '{@post_title}' ); - $this->assertEquals( 'my post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - $content = base64_encode( '{@number1}' ); - $this->assertEquals( '123', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number1']{$content}[/pod_if_field]" ) ); - - $id = pods( $pod_name )->add( - array( - 'name' => 'my post title', - 'number1' => 456, - 'number2' => 0, - ) - ); - $content = base64_encode( '{@number2}[else]{@number1}' ); - $this->assertEquals( '456', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id}' field='number2']{$content}[/pod_if_field]" ) ); - } - - public function test_if_in_html() { - - $pod_name = self::$pod_name; - $id = pods( $pod_name )->add( - array( - 'name' => 'my post title', - 'number1' => 123, - 'number2' => 456, - ) - ); - $content = base64_encode( '{@number1}[else]{@number2}' ); - // This isn't supposed to be perfect HTML, just good enough for the test - $this->assertEquals( '', do_shortcode( "" ) ); - } - - /** - * @group bug-4403 - */ - public function test_if_related_field() { - - $pod_name = self::$pod_name; - $id1 = pods( $pod_name )->add( - array( - 'post_status' => 'publish', - 'name' => 'first post title', - 'number1' => 123, - 'number2' => 456, - ) - ); - $id2 = pods( $pod_name )->add( - array( - 'post_status' => 'publish', - 'name' => 'second post title', - 'number1' => 987, - 'number2' => 654, - 'related_field' => $id1, - ) - ); - - // Not exactly related to the shortcode test but lets make sure we can at least retrieve the proper data - $this->assertEquals( '123', pods( $pod_name, $id2 )->field( 'related_field.number1' ) ); - - $content = base64_encode( '{@related_field.post_title}' ); - $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id2}' field='related_field']{$content}[/pod_if_field]" ) ); - - $content = base64_encode( '{@related_field.post_title}' ); - $this->assertEquals( 'first post title', do_shortcode( "[pod_if_field pod='{$pod_name}' id='{$id2}' field='related_field']{$content}[/pod_if_field]" ) ); - - $this->assertEquals( 'first post title', do_shortcode( "[pods name='{$pod_name}' id='{$id2}'][if related_field]{@related_field.post_title}[/if][/pods]" ) ); - - } -} diff --git a/tests/phpunit/includes/Templates/Test_Frontier.php b/tests/phpunit/includes/Templates/Test_Frontier.php deleted file mode 100644 index 0b9d38fd0c..0000000000 --- a/tests/phpunit/includes/Templates/Test_Frontier.php +++ /dev/null @@ -1,47 +0,0 @@ - '_pods_template', - 'post_status' => 'publish', - 'post_content' => 'All of the true things I am about to tell you are shameless lies.', - ); - $id = wp_insert_post( $post ); - $this->assertGreaterThan( 0, $id ); - } - - /** - * This test isn't specifically about the templates, but it's connected with the issue. - * Create an arbitrary post type and insert a post to check to make sure save_meta isn't failing - * - * @group pods-issue-4500 - */ - public function test_create_post_type() { - - $post_type = 'new_post_type'; - $args = array(); - register_post_type( $post_type, $args ); - - $post = array( - 'post_type' => $post_type, - 'post_status' => 'publish', - 'post_content' => 'All of the true things I am about to tell you are shameless lies.', - ); - $id = wp_insert_post( $post ); - $this->assertGreaterThan( 0, $id ); - } - -} diff --git a/tests/phpunit/includes/_tests-integration-pods.php b/tests/phpunit/includes/_tests-integration-pods.php deleted file mode 100644 index ae6e0e3f3a..0000000000 --- a/tests/phpunit/includes/_tests-integration-pods.php +++ /dev/null @@ -1,144 +0,0 @@ -pod_id = pods_api()->save_pod( - array( - 'storage' => 'table', - 'type' => 'pod', - 'name' => 'foo', - ) - ); - $this->pod = pods( 'foo' ); - - // register the fields - $params = array( - 'pod' => 'foo', - 'pod_id' => $this->pod_id, - 'name' => 'description', - 'type' => 'text', - ); - $this->fields['description']['id'] = pods_api()->save_field( $params ); - - $params = array( - 'pod' => 'foo', - 'pod_id' => $this->pod_id, - 'name' => 'start_date', - 'type' => 'datetime', - ); - $this->fields['start_date']['id'] = pods_api()->save_field( $params ); - - // add item - $this->item = $this->pod->save( - array( - 'name' => 'Sample Event', - 'description' => 'My first event', - 'start_date' => 'May 5, 2014 11:00 PM', - ) - ); - } - - public function tearDown() { - - pods_api()->delete_pod( array( 'id' => $this->pod_id ) ); - unset( $this->pod ); - } - - /** - * @covers Pods::valid - * @since 3.0.0 - */ - public function test_method_valid() { - - $this->assertTrue( $this->pod->valid() ); - } - - /** - * @covers Pods::exists - * @uses ::pods - * @since 3.0.0 - */ - public function test_method_exists() { - - $pod = pods( 'foo', $this->item ); - $this->assertTrue( $pod->exists(), __( 'Item %s does not exist', 'pods' ) ); - } - - /** - * @covers Pods::row - * uses ::pods - * @since 3.0.0 - */ - public function test_method_row() { - - $pod = pods( 'foo', $this->item ); - $row = $pod->row(); - $this->assertInternalType( 'array', $row, __( 'Pods::row did not return an array' ) ); - } - - /** - * @covers Pods::find - * @since 3.0.0 - */ - public function test_method_find() { - - $pod = $this->pod->find(); - $this->assertInstanceOf( 'pods', $pod ); - } - - /** - * @covers Pods::fetch - * @since 3.0.0 - */ - public function test_method_fetch() { - - $this->assertInternalType( 'array', $this->pod->fetch() ); - } - - /** - * @covers Pods::display - * @uses Pods::fetch - * @since 3.0.0 - */ - public function test_method_display() { - - $this->pod->fetch(); - $this->assertEquals( 'Sample Event', $this->pod->display( 'name' ) ); - $this->assertEquals( 'My first event', $this->pod->display( 'description' ) ); - $this->assertEquals( 'May 5, 2014 11:00 PM', $this->pod->display( 'start_date' ) ); - } - - /** - * @covers Pods::save - * since 3.0 - */ - public function test_method_save() { - - $foo = $this->pod->save( 'bar', 'baz' ); - $this->assertInternalType( 'int', $foo ); - } -} diff --git a/tests/phpunit/includes/factory.php b/tests/phpunit/includes/factory.php deleted file mode 100755 index ab47f4dfc9..0000000000 --- a/tests/phpunit/includes/factory.php +++ /dev/null @@ -1,126 +0,0 @@ -pod = new Pods_UnitTest_Factory_For_Pod( $this ); - } -} - -/** - * Class Pods_UnitTest_Factory_For_Pod - * - * @package Pods_Unit_Tests - */ -class Pods_UnitTest_Factory_For_Pod extends WP_UnitTest_Factory_For_Thing { - - /** - * Pods_UnitTest_Factory_For_Pod constructor. - * - * @param null $factory - */ - public function __construct( $factory = null ) { - - parent::__construct( $factory ); - $this->default_generation_definitions = array( - 'id' => new \WP_UnitTest_Generator_Sequence( '%s' ), - 'name' => new \WP_UnitTest_Generator_Sequence( 'test-pod-%s' ), - 'label' => new \WP_UnitTest_Generator_Sequence( 'Test Pod %s' ), - ); - } - - /** - * @param $args - * - * @return int - */ - public function create_object( $args ) { - - return pods_api()->save_pod( $args ); - } - - /** - * @param $post_id - * @param $fields - */ - public function update_object( $post_id, $fields ) { - // not yet implemented - } - - /** - * @param $post_id - */ - public function get_object_by_id( $post_id ) { - // not yet implemented - } -} - -/** - * Class Pods_UnitTest_Factory_For_Field - * - * @package Pods_Unit_Tests - */ -class Pods_UnitTest_Factory_For_Field extends WP_UnitTest_Factory_For_Thing { - - /** - * Pods_UnitTest_Factory_For_Field constructor. - * - * @param null $factory - */ - public function __construct( $factory = null ) { - - parent::__construct( $factory ); - $this->default_generation_definitions = array( - 'id' => new \WP_UnitTest_Generator_Sequence( '%s' ), - 'name' => new \WP_UnitTest_Generator_Sequence( 'test-field-%s' ), - 'label' => new \WP_UnitTest_Generator_Sequence( 'Test Field %s' ), - ); - } - - /** - * @param $args - */ - public function create_object( $args ) { - // not yet implemented - } - - /** - * @param $post_id - * @param $fields - */ - public function update_object( $post_id, $fields ) { - // not yet implemented - } - - /** - * @param $post_id - */ - public function get_object_by_id( $post_id ) { - // not yet implemented - } -} diff --git a/tests/phpunit/includes/test-pods-field-text.php b/tests/phpunit/includes/test-pods-field-text.php deleted file mode 100644 index 34de487586..0000000000 --- a/tests/phpunit/includes/test-pods-field-text.php +++ /dev/null @@ -1,354 +0,0 @@ -field = new PodsField_Text(); - } - - public function tearDown() { - - if ( shortcode_exists( 'fooshortcode' ) ) { - remove_shortcode( 'fooshortcode' ); - } - - unset( $this->field ); - } - - /** - * @covers PodsField_Text::options - */ - public function test_method_exists_options() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'options' ) ); - } - - /** - * @covers PodsField_Text::options - * @depends test_method_exists_options - */ - public function test_method_options_returns_array() { - - $this->assertInternalType( 'array', $this->field->options() ); - } - - /** - * @covers PodsField_Text::options - * @depends test_method_exists_options - */ - public function test_method_options_key_exists_text_repeatable() { - - $this->assertArrayHasKey( 'text_repeatable', $this->field->options() ); - } - - /** - * @covers PodsField_Text::options - * @depends test_method_exists_options - */ - public function test_method_options_key_exists_output_options() { - - $this->assertArrayHasKey( 'output_options', $this->field->options() ); - } - - /** - * @covers PodsField_Text::options - * @depends test_method_exists_options - */ - public function test_method_options_key_exists_text_allowed_html_tags() { - - $this->assertArrayHasKey( 'text_allowed_html_tags', $this->field->options() ); - } - - /** - * @covers PodsField_Text::options - * @depends test_method_exists_options - */ - public function test_method_options_key_exists_text_max_length() { - - $this->assertArrayHasKey( 'text_max_length', $this->field->options() ); - } - - /** - * @covers PodsField_Text::schema - */ - public function test_method_exists_schema() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'schema' ) ); - } - - /** - * @covers PodsField_Text::schema - * @depends test_method_exists_schema - */ - public function test_method_schema_returns_string() { - - $this->assertInternalType( 'string', $this->field->schema() ); - } - - /** - * @covers PodsField_Text::schema - * @depends test_method_exists_schema - * @uses ::pods_v - */ - public function test_method_schema_returns_varchar_default() { - - $this->assertEquals( 'VARCHAR(255)', $this->field->schema() ); - } - - /** - * @covers PodsField_Text::schema - * @depends test_method_exists_schema - * @uses ::pods_v - */ - public function test_method_schema_returns_longtext() { - - $this->assertEquals( 'LONGTEXT', $this->field->schema( array( 'text_max_length' => 16777216 ) ) ); - } - - /** - * @covers PodsField_Text::display - */ - public function test_method_exists_display() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'display' ) ); - } - - /** - * @covers PodsField_Text::display - * @depends test_method_exists_display - * @uses PodsField_Text::strip_html - * @uses ::pods_v - */ - public function test_method_display_defaults() { - - $this->assertEquals( '', $this->field->display() ); - } - - /** - * @covers PodsField_Text::display - * @depends test_method_exists_display - * @uses PodsField_Text::strip_html - * @uses ::pods_v - */ - public function test_method_display_value() { - - $this->assertEquals( 'foo', $this->field->display( 'foo' ) ); - } - - /** - * @covers PodsField_Text::display - * @depends test_method_exists_display - * @uses PodsField_Text::strip_html - * @uses ::pods_v - */ - public function test_method_display_value_allow_shortcode() { - - add_shortcode( - 'fooshortcode', function () { - - return 'foobar'; - } - ); - - $this->assertEquals( 'foobar', $this->field->display( '[fooshortcode]foo[/fooshortcode]', 'bar', array( 'text_allow_shortcode' => 1 ) ) ); - } - - /** - * @covers PodsField_Text::pre_save - */ - public function test_method_exists_pre_save() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'pre_save' ), 'PodsField_Text::pre_save does not exist.' ); - } - - /** - * @covers PodsField_Text::pre_save - * @depends test_method_exists_pre_save - * @uses PodsField_Text::strip_html - * @uses ::pods_v - * @uses ::pods_mb_strlen - * @uses ::pods_mb_substr - */ - public function test_method_pre_save_defaults() { - - $this->assertEquals( 'foo', $this->field->pre_save( 'foo' ) ); - } - - /** - * @covers PodsField_Text::pre_save - * @depends test_method_exists_pre_save - * @uses PodsField_Text::strip_html - * @uses ::pods_v - * @uses ::pods_mb_strlen - * @uses ::pods_mb_substr - */ - public function test_method_pre_save_truncate() { - - $this->assertEquals( 'foo', $this->field->pre_save( 'foobar', null, null, array( 'text_max_length' => 3 ) ) ); - } - - /** - * @covers PodsField_Text::validate - */ - public function test_method_exists_validate() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'validate' ), 'PodsField_Text::validate does not exist.' ); - } - - /** - * @covers PodsField_Text::validate - * @depends test_method_exists_validate - * @uses PodsField_Text::strip_html - * @uses ::pods_v - * @uses ::pods_mb_strlen - * @uses ::pods_mb_substr - */ - public function test_method_validate() { - - $this->assertTrue( $this->field->validate( 'foobar' ) ); - } - - /** - * @covers PodsField_Text::validate - * @depends test_method_exists_validate - * @uses PodsField_Text::strip_html - * @uses ::pods_v - * @uses ::pods_mb_strlen - * @uses ::pods_mb_substr - */ - public function test_method_validate_empty_value() { - - $this->assertTrue( $this->field->validate( '' ) ); - } - - /** - * @covers PodsField_Text::ui - */ - public function test_method_exists_ui() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'ui' ), 'PodsField_Text::ui does not exist.' ); - } - - /** - * @covers PodsField_Text::ui - * @depends test_method_exists_ui - */ - public function test_method_ui() { - - $this->assertEquals( 'foo', $this->field->ui( 1, 'foo' ) ); - } - - /** - * @covers PodsField_Text::strip_html - */ - public function test_method_exists_strip_html() { - - $this->assertTrue( method_exists( 'PodsField_Text', 'strip_html' ), 'PodsField_Text::strip_html does not exist.' ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_array_value() { - - $this->assertEquals( 'foo bar baz', $this->field->strip_html( array( 'foo', 'bar', 'baz' ) ) ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - */ - public function test_method_strip_html_empty_array_value() { - - $this->assertEmpty( $this->field->strip_html( array() ) ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_defaults() { - - $this->assertEquals( 'foo', $this->field->strip_html( 'foo' ) ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_default_options() { - - $this->assertEquals( 'foo', $this->field->strip_html( '
              1. foo
            ' ), $this->field->options() ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_default_tags_allowed() { - - $options['text_allow_html'] = 1; - $options['text_allowed_html_tags'] = 'strong em a ul ol li b i'; - - $this->assertEquals( '
              1. foo
            ', $this->field->strip_html( '
              1. foo
            ', $options ) ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_br_tags_allowed() { - - $options['text_allow_html'] = 1; - $options['text_allowed_html_tags'] = 'br'; - - $this->assertEquals( 'foo
            ', $this->field->strip_html( 'foo
            ', $options ) ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_hr_tags_allowed() { - - $options['text_allow_html'] = 1; - $options['text_allowed_html_tags'] = 'hr'; - - $this->assertEquals( 'foo
            ', $this->field->strip_html( 'foo
            ', $options ) ); - } - - /** - * @covers PodsField_Text::strip_html - * @depends test_method_exists_strip_html - * @uses ::pods_v - */ - public function test_method_strip_html_tags_allowed() { - - $options['text_allow_html'] = 1; - $options['text_allowed_html_tags'] = 'strong em'; - - $this->assertEquals( 'foo', $this->field->strip_html( '
            foo
            ', $options ) ); - } -} diff --git a/tests/phpunit/includes/testcase.php b/tests/phpunit/includes/testcase.php deleted file mode 100644 index a59f63e1ac..0000000000 --- a/tests/phpunit/includes/testcase.php +++ /dev/null @@ -1,969 +0,0 @@ - array( - 'object' => array( - '%d', - 'post', - 'page', - 'nav_menu_item', - ), - // @todo Figure out how to split test meta/table for existing objects - 'storage' => array( - 'meta', - 'table', - ), - 'data' => array( - 'post_status' => 'publish', - ), - 'options' => array( - 'built_in_taxonomies_category' => 1, - 'built_in_taxonomies_post_tag' => 1, - 'built_in_taxonomies_nav_menu' => 1, - 'built_in_taxonomies_test_non_pod_ct' => 1, - ), - ), - 'taxonomy' => array( - 'object' => array( - '%d', - 'category', - 'post_tag', - 'nav_menu', - ), - // @todo Figure out how to split test meta/table for existing objects - 'storage' => array( - 'table', - 'none', - ), - 'options' => array( - 'built_in_post_types_post' => 1, - 'built_in_post_types_page' => 1, - 'built_in_post_types_nav_menu_item' => 1, - ), - ), - 'user' => array( - // @todo Figure out how to split test meta/table for existing objects - 'storage' => array( - 'meta', - 'table', - ), - 'fields' => array( - array( - 'name' => 'avatar', - 'type' => 'avatar', - ), - ), - 'data' => array( - 'display_name' => 'User %s', - 'user_login' => 'User-%s', - 'user_email' => '%s@user.com', - 'user_pass' => '%s', - ), - ), - 'media' => array( - // @todo Figure out how to split test meta/table for existing objects - 'storage' => array( - 'meta', - 'table', - ), - 'data' => array( - 'post_status' => 'inherit', - 'post_type' => 'attachment', - ), - ), - 'comment' => array( - // @todo Figure out how to split test meta/table for existing objects - 'storage' => array( - 'meta', - 'table', - ), - 'data' => array( - 'comment_author' => 'Comment %s', - 'comment_author_email' => '%s@comment.com', - 'comment_author_url' => 'http://comment.com', - 'comment_content' => '%s', - 'comment_post_ID' => 1, - 'comment_type' => 'comment', - 'comment_approved' => 1, - 'comment_date' => '2014-11-11', - ), - ), - 'pod' => array( - 'object' => array( - '%d', - 'test_act', - ), - 'storage' => array( - 'table', - ), - 'fields' => array( - array( - 'name' => 'name', - 'type' => 'text', - ), - array( - 'name' => 'permalink', - 'type' => 'slug', - ), - array( - 'name' => 'test_text_field', - 'type' => 'test', - ), - array( - 'name' => 'author', - 'type' => 'pick', - 'pick_object' => 'user', - 'pick_val' => '', - 'pick_format_type' => 'single', - ), - ), - 'data' => array( - 'permalink' => 'test-slug-%s', - ), - ), - ); - - /** - * A collection of supported field definitions - * - * @var array - * @static - */ - public static $supported_fields = array( - array( - 'name' => 'test_rel_user', - 'type' => 'pick', - 'pick_object' => 'user', - 'pick_val' => 'user', - 'pick_format_type' => 'single', - ), - array( - 'name' => 'test_rel_post', - 'type' => 'pick', - 'pick_object' => 'post_type', - 'pick_val' => 'post', - 'pick_format_type' => 'single', - ), - array( - 'name' => 'test_rel_pages', - 'type' => 'pick', - 'pick_object' => 'post_type', - 'pick_val' => 'page', - 'pick_format_type' => 'multi', - ), - array( - 'name' => 'test_rel_tag', - 'type' => 'pick', - 'pick_object' => 'taxonomy', - 'pick_val' => 'post_tag', - 'pick_format_type' => 'single', - ), - array( - 'name' => 'test_rel_media', - 'type' => 'pick', - 'pick_object' => 'media', - 'pick_val' => '', - 'pick_format_type' => 'single', - ), - array( - 'name' => 'test_rel_comment', - 'type' => 'pick', - 'pick_object' => 'comment', - 'pick_val' => '', - 'pick_format_type' => 'single', - ), - array( - 'name' => 'test_rel_act', - 'type' => 'pick', - 'pick_object' => 'pod', - 'pick_val' => 'test_act', - 'pick_format_type' => 'single', - ), - array( - 'name' => 'test_text_field', - 'type' => 'text', - ), - ); - - /** - * A collection of preset related field configurations - * - * @var array - * @static - */ - public static $related_items = array( - 'test_rel_user' => array( - 'pod' => 'user', - 'id' => 0, - 'field_index' => 'display_name', - 'field_id' => 'ID', - 'data' => array( - 'display_name' => 'Related user', - 'user_login' => 'related-user', - 'user_email' => 'related@user.com', - 'user_pass' => 'changeme', - 'test_text_field' => 'Test related user text field', - ), - ), - 'test_rel_post' => array( - 'pod' => 'post', - 'id' => 0, - 'field_index' => 'post_title', - 'field_id' => 'ID', - 'field_author' => 'post_author', - 'data' => array( - 'post_title' => 'Related post', - 'post_content' => '%s', - 'post_status' => 'publish', - 'test_text_field' => 'Test related post text field', - ), - ), - 'test_rel_pages' => array( - 'pod' => 'page', - 'id' => 0, - 'field_index' => 'post_title', - 'field_id' => 'ID', - 'field_author' => 'post_author', - 'limit' => 2, - 'data' => array( - 'post_title' => 'Related page', - 'post_content' => '%s', - 'post_status' => 'publish', - 'test_text_field' => 'Test related page text field', - ), - 'sub_data' => array(), - 'sub_rel_data' => array(), - ), - 'test_rel_tag' => array( - 'pod' => 'post_tag', - 'id' => 0, - 'field_index' => 'name', - 'field_id' => 'term_id', - 'field_author' => false, - 'data' => array( - 'name' => 'Related post tag', - 'description' => '%s', - 'test_text_field' => 'Test related tag text field', - ), - ), - 'test_rel_media' => array( - 'pod' => 'media', - 'id' => 0, - 'field_index' => 'post_title', - 'field_id' => 'ID', - 'field_author' => 'post_author', - 'data' => array( - 'post_title' => 'Related media', - 'post_content' => '%s', - 'post_status' => 'publish', - 'test_text_field' => 'Test related media text field', - ), - ), - 'test_rel_comment' => array( - 'pod' => 'comment', - 'id' => 0, - 'field_index' => 'comment_date', - 'field_id' => 'comment_ID', - 'field_author' => 'user_id', - 'data' => array( - 'comment_author' => 'Related comment', - 'comment_author_email' => 'related@comment.com', - 'comment_author_url' => 'http://comment.com', - 'comment_content' => '%s', - 'comment_post_ID' => 1, - 'comment_type' => 'comment', - 'comment_approved' => 1, - 'comment_date' => '2014-11-11 00:00:00', - 'test_text_field' => 'Test related comment text field', - ), - ), - 'test_rel_act' => array( - 'pod' => 'test_act', - 'id' => 0, - 'field_index' => 'name', - 'field_id' => 'id', - 'field_author' => 'author', - 'data' => array( - 'name' => 'Related pod item', - 'permalink' => 'related-pod-item', - 'test_text_field' => 'Test related pod text field', - ), - ), - 'avatar' => array( - 'pod' => 'media', - 'id' => 0, - 'field_index' => 'post_title', - 'field_id' => 'ID', - 'field_author' => 'post_author', - 'data' => array( - 'post_title' => 'Related media', - 'post_content' => '%s', - 'post_status' => 'publish', - 'test_text_field' => 'Test avatar text field', - ), - ), - '%s' => array( - 'pod' => '%s', - 'id' => 0, - 'field_index' => '', - 'field_id' => '', - 'field_author' => false, - 'data' => array( - 'index' => 'Testing %s', - 'test_text_field' => 'Testing %s', - ), - ), - ); - - /** - * A collection of pre-built pod objects - * - * @var array - * @static - */ - public static $builds = array(/* - * 'pod_type' => array( - * 'object_name' => array( - * 'meta' => array( - * // pod array of info - * ), - * 'table' => array( - * // pod array of info - * ), - * 'none' => array( - * // pod array of info - * ) - * ) - * ) - */ - ); - - /** - * Fetches the factory object for generating WordPress & Pods fixtures. - * - * @return Pods_UnitTest_Factory The fixture factory. - */ - protected static function factory() { - static $factory = null; - if ( ! $factory ) { - $factory = new Pods_UnitTest_Factory(); - } - return $factory; - } - - /** - * @inheritDoc - */ - public function setUp() { - - parent::setUp(); - - pods_require_component( 'table-storage' ); - pods_require_component( 'advanced-relationships' ); - pods_require_component( 'migrate-packages' ); - pods_require_component( 'advanced-content-types' ); - } - - public function clean_up_global_scope() { - - parent::clean_up_global_scope(); - } - - public function assertPreConditions() { - - parent::assertPreConditions(); - } - - /** - * @param $url - */ - public function go_to( $url ) { - - $url = str_replace( network_home_url(), '', $url ); - - $GLOBALS['_SERVER']['REQUEST_URI'] = $url; - - $_GET = array(); - $_POST = array(); - - foreach ( - array( - 'query_string', - 'id', - 'postdata', - 'authordata', - 'day', - 'currentmonth', - 'page', - 'pages', - 'multipage', - 'more', - 'numpages', - 'pagenow', - ) as $v - ) { - if ( isset( $GLOBALS[ $v ] ) ) { - unset( $GLOBALS[ $v ] ); - } - } - - $parts = parse_url( $url ); - - if ( isset( $parts['scheme'] ) ) { - $req = $parts['path']; - if ( isset( $parts['query'] ) ) { - $req .= '?' . $parts['query']; - parse_str( $parts['query'], $_GET ); - } - } else { - $req = $url; - } - - if ( ! isset( $parts['query'] ) ) { - $parts['query'] = ''; - } - - // Scheme - if ( 0 === strpos( $req, '/wp-admin' ) && force_ssl_admin() ) { - $_SERVER['HTTPS'] = 'on'; - } else { - unset( $_SERVER['HTTPS'] ); - } - - $_SERVER['REQUEST_URI'] = $req; - unset( $_SERVER['PATH_INFO'] ); - - $this->flush_cache(); - - unset( $GLOBALS['wp_query'], $GLOBALS['wp_the_query'] ); - - $GLOBALS['wp_the_query'] = new WP_Query(); - $GLOBALS['wp_query'] = $GLOBALS['wp_the_query']; - $GLOBALS['wp'] = new WP(); - - foreach ( $GLOBALS['wp']->public_query_vars as $v ) { - unset( $GLOBALS[ $v ] ); - } - foreach ( $GLOBALS['wp']->private_query_vars as $v ) { - unset( $GLOBALS[ $v ] ); - } - - $GLOBALS['wp']->main( $parts['query'] ); - } - - /** - * @param $user_id - */ - public function set_current_user( $user_id ) { - - wp_set_current_user( $user_id ); - } - - /** - * @param $class - * @param $property - * - * @return mixed - */ - public function getReflectionPropertyValue( $class, $property ) { - - $reflection = new \ReflectionProperty( $class, $property ); - $reflection->setAccessible( true ); - - return $reflection->getValue( $class ); - } - - /** - * @param $class - * @param $property - * @param $value - */ - public function setReflectionPropertyValue( $class, $property, $value ) { - - $reflection = new \ReflectionProperty( $class, $property ); - $reflection->setAccessible( true ); - - return $reflection->setValue( $class, $value ); - } - - /** - * @param $class - * @param $method - * - * @return mixed - */ - public function reflectionMethodInvoke( $class, $method ) { - - $reflection = new \ReflectionMethod( $class, $method ); - $reflection->setAccessible( true ); - - return $reflection->invoke( $class ); - } - - /** - * @param $class - * @param $method - * @param $args - * - * @return mixed - */ - public function reflectionMethodInvokeArgs( $class, $method, $args ) { - - $reflection = new \ReflectionMethod( $class, $method ); - $reflection->setAccessible( true ); - - return $reflection->invokeArgs( $class, $args ); - } - - /** - * Create a full working set of pods - */ - public static function _initialize_config() { - - // Setup non-Pod taxonomy - $args = array( - 'hierarchical' => true, - 'show_ui' => true, - 'query_var' => true, - 'labels' => array( - 'name' => 'Non-Pod Taxonomy', - 'singular_name' => 'Non-Pod Taxonomy', - ), - ); - - register_taxonomy( 'test_non_pod_ct', array( 'post', 'page', 'nav_menu_item' ), $args ); - - // Setup Pods API - $api = pods_api(); - - $test_pod = 1; - - // Loop through supported types and fields and setup test builds - foreach ( self::$supported_types as $pod_type => $options ) { - $main_pod = array( - 'name' => '', - 'type' => $pod_type, - 'storage' => '', - 'fields' => array(), - // Hack for 2.x - // @todo Remove for 3.x - 'options' => array(), - ); - - if ( 'pod' === $pod_type ) { - $main_pod['options']['pod_index'] = 'name'; - } - - $objects = array(); - - if ( ! isset( $options['object'] ) ) { - $objects[] = $pod_type; - } else { - $objects = (array) $options['object']; - } - - foreach ( $objects as $object ) { - $object_pod = $main_pod; - - // @todo Fix for 3.x to be merge instead - if ( ! empty( $options['options'] ) ) { - $object_pod['options'] = $options['options']; - } - - $pod_object = $object; - - if ( '%d' === $pod_object ) { - $pod_object = 'test_' . substr( $pod_type, 0, 4 ); - - $object_pod['object'] = ''; - } else { - $object_pod['object'] = $pod_object; - } - - $object_pod['name'] = $pod_object; - - foreach ( $options['storage'] as $storage_type ) { - $pod = $object_pod; - - if ( empty( $pod['object'] ) ) { - $pod['name'] = $pod_object . '_' . substr( $storage_type, 0, 3 ) . '_' . $test_pod; - } - - if ( 'taxonomy' === $pod_type && 'none' === $storage_type && function_exists( 'get_term_meta' ) ) { - $storage_type = 'meta'; - } - - $pod['storage'] = $storage_type; - - if ( 'none' !== $storage_type ) { - $pod['fields'] = self::$supported_fields; - - if ( isset( $options['fields'] ) ) { - foreach ( $options['fields'] as $field ) { - if ( isset( $field['id'] ) ) { - unset( $field['id'] ); - } - - // Hack for 2.x - // @todo Remove for 3.x - $field['options'] = $field; - - $pod['fields'][] = $field; - } - } - } - - if ( ! isset( self::$builds[ $pod_type ] ) ) { - self::$builds[ $pod_type ] = array(); - } - - if ( ! isset( self::$builds[ $pod_type ][ $object ] ) ) { - self::$builds[ $pod_type ][ $object ] = array(); - } - - if ( isset( self::$builds[ $pod_type ][ $object ][ $storage_type ] ) ) { - continue; - } - - self::$builds[ $pod_type ][ $object ][ $storage_type ] = $pod; - self::$builds[ $pod_type ][ $object ][ $storage_type ]['fields'] = array(); - - foreach ( $pod['fields'] as $field ) { - self::$builds[ $pod_type ][ $object ][ $storage_type ]['fields'][ $field['name'] ] = $field; - } - - if ( in_array( $pod['name'], pods_reserved_keywords(), true ) ) { - // Extending objects when using reserved keywords. - // This will then accept `post`, `page` etc. as Pods object names. - $pod['create_extend'] = 'extend'; - } - - $id = $api->save_pod( $pod ); - - $load_pod = $api->load_pod( array( 'id' => $id ) ); - - if ( ! empty( $load_pod ) ) { - foreach ( $load_pod['fields'] as $field ) { - if ( isset( self::$builds[ $pod_type ][ $object ][ $storage_type ]['fields'][ $field['name'] ] ) ) { - self::$builds[ $pod_type ][ $object ][ $storage_type ]['fields'][ $field['name'] ]['id'] = $field['id']; - } - } - } - - // $this->assertGreaterThan( 0, $id, 'Pod not added' ); - self::$builds[ $pod_type ][ $object ][ $storage_type ]['id'] = $id; - - $test_pod ++; - - // @todo Figure out how to split test meta/table for existing objects - // If object set, we can't create multiple Pods to test, use first storage provided - if ( ! empty( $pod['object'] ) ) { - break; - } - }//end foreach - }//end foreach - }//end foreach - - global $pods_init; - - $pods_init->setup_content_types( true ); - $pods_init->load_meta(); - - } - - /** - * Add items to the pods - */ - public static function _initialize_data() { - - // Insert test data for Non-Pod Taxonomy - $term = wp_insert_term( 'Non-Pod Term', 'test_non_pod_ct' ); - - self::$related_items['test_non_pod_ct'] = array( - 'pod' => 'test_non_pod_ct', - 'id' => (int) $term['term_id'], - 'field_index' => 'name', - 'field_id' => 'term_id', - 'data' => array( - 'name' => 'Non-Pod Term', - ), - ); - - // @todo In 3.x, we should be able to use pods() on any taxonomy outside of Pods - $related_author = 0; - $related_media = 0; - $related_avatar = 0; - - // Get and store sample image for use later - $sample_image = pods_attachment_import( self::$sample_image ); - - if ( empty( $sample_image ) ) { - throw new \Exception( sprintf( 'The sample image must have been deleted! Sample image: %s', self::$sample_image ) ); - } - - $sample_image = get_attached_file( $sample_image ); - - $new_related_items = array(); - - foreach ( self::$related_items as $item => $item_data ) { - // Get latest, as we're updating as we go - $item_data = self::$related_items[ $item ]; - - if ( ! empty( $item_data['is_build'] ) || 'test_non_pod_ct' === $item ) { - continue; - } elseif ( '%s' !== $item ) { - foreach ( $item_data['data'] as $k => $v ) { - if ( is_array( $v ) ) { - foreach ( $v as $kv => $vv ) { - $v[ $kv ] = sprintf( $vv, wp_generate_password( 4, false ) ); - } - } else { - $v = sprintf( $v, wp_generate_password( 4, false ) ); - if ( 'permalink' === $k ) { - $v = strtolower( $v ); - } - } - - $item_data['data'][ $k ] = $v; - } - - $p = pods( $item_data['pod'] ); - - $item_data['field_id'] = $p->pod_data['field_id']; - $item_data['field_index'] = $p->pod_data['field_index']; - - // Add term id for the Non-Pod Taxonomy field - if ( 'post_type' === $p->pod_data['type'] ) { - $item_data['data']['test_non_pod_ct'] = (int) self::$related_items['test_non_pod_ct']['id']; - } elseif ( 'pod' === $p->pod_data['type'] ) { - $item_data['data']['author'] = $related_author; - } - - if ( 'media' === $item_data['pod'] ) { - // Create new attachment from sample image - $id = pods_attachment_import( $sample_image ); - - $p->save( $item_data['data'], null, $id ); - } else { - $id = $p->add( $item_data['data'] ); - } - - if ( ! empty( $item_data['limit'] ) ) { - $ids = array(); - - $item_data['sub_data'][ $id ] = $item_data['data']; - - $ids[] = $id; - - for ( $x = 1; $x < $item_data['limit']; $x ++ ) { - $sub_item_data = $item_data['data']; - $sub_item_data[ $item_data['field_index'] ] .= ' (' . $x . ')'; - - if ( 'media' === $item_data['pod'] ) { - // Create new attachment from sample image - $id = pods_attachment_import( $sample_image ); - - $p->save( $sub_item_data, null, $id ); - } else { - $id = $p->add( $sub_item_data ); - - $item_data['sub_data'][ $id ] = $sub_item_data; - } - - $ids[] = $id; - } - - $id = $ids; - } elseif ( 'test_rel_user' === $item ) { - $related_author = $id; - } elseif ( 'test_rel_media' === $item ) { - $related_media = $id; - } elseif ( 'avatar' === $item ) { - $related_avatar = $id; - }//end if - - $item_data['id'] = $id; - - self::$related_items[ $item ] = $item_data; - - // Init user data to other items for saving - foreach ( self::$related_items as $r_item => $r_item_data ) { - if ( is_array( $r_item_data['id'] ) ) { - foreach ( $r_item_data['sub_data'] as $sub_id => $sub_data ) { - self::$related_items[ $r_item ]['sub_data'][ $sub_id ][ $item ] = $id; - } - } elseif ( isset( $r_item_data['sub_data'] ) ) { - self::$related_items[ $r_item ]['sub_rel_data'][ $item ] = $id; - } - - self::$related_items[ $r_item ]['data'][ $item ] = $id; - } - } else { - foreach ( self::$builds as $pod_type => $objects ) { - foreach ( $objects as $object => $storage_types ) { - foreach ( $storage_types as $storage_type => $pod ) { - $pod_item_data = $item_data; - - if ( ! empty( self::$supported_types[ $pod_type ]['data'] ) ) { - foreach ( self::$supported_types[ $pod_type ]['data'] as $k => $v ) { - $pod_item_data['data'][ $k ] = $v; - } - } - - foreach ( $pod_item_data['data'] as $k => $v ) { - if ( is_array( $v ) ) { - foreach ( $v as $kv => $vv ) { - $v[ $kv ] = sprintf( $vv, wp_generate_password( 4, false ) ); - } - } else { - $v = sprintf( $v, wp_generate_password( 4, false ) ); - if ( 'permalink' === $k ) { - $v = strtolower( $v ); - } - } - - $pod_item_data['data'][ $k ] = $v; - } - - foreach ( self::$supported_fields as $field ) { - if ( isset( self::$related_items[ $field['name'] ] ) ) { - $pod_item_data['data'][ $field['name'] ] = self::$related_items[ $field['name'] ]['id']; - } - } - - $pod_item_data['pod'] = $pod['name']; - - $p = pods( $pod_item_data['pod'] ); - - $pod_item_data['field_index'] = $p->pod_data['field_index']; - $pod_item_data['field_id'] = $p->pod_data['field_id']; - - $index = $pod_item_data['data']['index']; - - unset( $pod_item_data['data']['index'] ); - - if ( empty( $pod_item_data['data'][ $pod_item_data['field_index'] ] ) ) { - $pod_item_data['data'][ $pod_item_data['field_index'] ] = $index; - } - - if ( in_array( $pod_type, array( 'post_type', 'media' ) ) ) { - $pod_item_data['data']['post_author'] = $related_author; - } elseif ( 'comment' === $pod_type ) { - $pod_item_data['data']['user_id'] = $related_author; - } elseif ( 'user' === $pod_type ) { - $pod_item_data['data']['avatar'] = $related_avatar; - } elseif ( 'pod' === $pod_type ) { - $pod_item_data['data']['author'] = $related_author; - } - - // Add term id for the Non-Pod Taxonomy field - if ( 'post_type' === $pod_type ) { - $pod_item_data['data']['test_non_pod_ct'] = (int) self::$related_items['test_non_pod_ct']['id']; - } - - $id = $p->add( $pod_item_data['data'] ); - - if ( 'post_type' === $pod_type ) { - set_post_thumbnail( $id, $related_media ); - } - - $new_related_items[ $pod_item_data['pod'] ] = $pod_item_data; - $new_related_items[ $pod_item_data['pod'] ]['id'] = $id; - $new_related_items[ $pod_item_data['pod'] ]['is_build'] = true; - }//end foreach - }//end foreach - }//end foreach - }//end if - }//end foreach - - // Go over related field items and save relations to them too - foreach ( self::$related_items as $r_item => $r_item_data ) { - if ( in_array( $r_item, array( '%s', 'test_non_pod_ct' ) ) ) { - continue; - } - - $r_item_data['id'] = (array) $r_item_data['id']; - - $p = pods( $r_item_data['pod'] ); - - foreach ( $r_item_data['id'] as $item_id ) { - $item_id = (int) $item_id; - - $sub = false; - - if ( ! empty( $r_item_data['sub_data'][ $item_id ] ) ) { - $sub = true; - - $save_data = array_merge( $r_item_data['sub_data'][ $item_id ], $r_item_data['sub_rel_data'] ); - } else { - $save_data = $r_item_data['data']; - } - - if ( 'post_type' === $p->pod_data['type'] ) { - // Add term id for the Non-Pod Taxonomy field - // @todo This should be working on it's own - $save_data['test_non_pod_ct'] = (int) self::$related_items['test_non_pod_ct']['id']; - } elseif ( 'user' === $p->pod_data['type'] ) { - // Avatar gets added after user is added, have to add it back - $save_data['avatar'] = (int) self::$related_items['avatar']['id']; - } - - if ( ! $sub ) { - self::$related_items[ $r_item ]['data'] = array_merge( self::$related_items[ $r_item ]['data'], $save_data ); - } - - $p->save( $save_data, null, $item_id ); - }//end foreach - }//end foreach - - foreach ( $new_related_items as $item => $item_data ) { - self::$related_items[ $item ] = $item_data; - } - - // Setup copies - self::$related_items['author'] = self::$related_items['test_rel_user']; - - } - - /** - * {@inheritdoc} - */ - public static function tearDownAfterClass() { - // Force WP_UnitTestCase to not delete all data - } -} - -Pods_UnitTestCase::_initialize_config(); -Pods_UnitTestCase::_initialize_data(); diff --git a/tests/phpunit/includes/tests-pods-api.php b/tests/phpunit/includes/tests-pods-api.php deleted file mode 100644 index 04b51acdb3..0000000000 --- a/tests/phpunit/includes/tests-pods-api.php +++ /dev/null @@ -1,51 +0,0 @@ -assertTrue( method_exists( 'PodsAPI', 'init' ), 'Method init does not exist' ); - } - - /** - * Test the init method with no pod defined - * - * @covers PodsAPI::init - * @depends test_method_exists_init - * @since 3.0.0 - */ - public function test_method_init_no_pod() { - - $this->assertInstanceOf( 'PodsAPI', \PodsAPI::init(), 'Object returned is not of type Pods_API' ); - } - - /** - * @covers PodsAPI::__construct - * @since 3.0.0 - */ - public function test_method_construct_no_pod() { - - $pods_api = pods_api(); - - $this->assertTrue( $pods_api->display_errors, 'Property display_errors not true' ); - $this->assertNull( $pods_api->pod_data, 'Property pod_data not null' ); - $this->assertNull( $pods_api->pod, 'Property pod not null' ); - $this->assertNull( $pods_api->pod_id, 'Property pod_id not null' ); - $this->assertEmpty( $pods_api->fields, 'Property fields not empty' ); - $this->assertNull( $pods_api->format, 'Property format not null' ); - } -} diff --git a/tests/phpunit/includes/tests-pods-data.php b/tests/phpunit/includes/tests-pods-data.php deleted file mode 100644 index edd6d6336d..0000000000 --- a/tests/phpunit/includes/tests-pods-data.php +++ /dev/null @@ -1,626 +0,0 @@ -assertEquals( '', pods_sanitize( '' ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_returns_int() { - - $this->assertEquals( 1, pods_sanitize( 1 ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_returns_float() { - - $this->assertEquals( 12.348329, pods_sanitize( 12.348329 ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_null() { - - $this->assertEquals( null, pods_sanitize( null ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_returns_object() { - - $object = new stdClass(); - $object->foo = 1; - $object->bar = 'a test string'; - - $this->assertEquals( $object, pods_sanitize( $object ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_returns_array() { - - $array = array( - 'foo' => 1, - 'bar' => 'a test string', - ); - $this->assertEquals( $array, pods_sanitize( $array ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_string() { - - $original = "'\\`"; - - $this->assertEquals( "\'\\\`", pods_sanitize( $original ) ); - } - - /** - * @covers ::pods_sanitize - */ - public function test_pods_sanitize_sql() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_sanitize_like() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_slash() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_unsanitize() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_unslash() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_trim() { - - $string = ' test '; - - $this->assertEquals( 'test', pods_trim( $string ) ); - - $this->assertEquals( ' test', pods_trim( $string, null, 'r' ) ); - - $this->assertEquals( 'test ', pods_trim( $string, null, 'l' ) ); - - $string = ' test & '; - - $this->assertEquals( 'test', pods_trim( $string, ' &' ) ); - - $this->assertEquals( ' test', pods_trim( $string, ' &', 'r' ) ); - - // Arrays. - - $array = array( - ' test ', - ' test2 ', - ); - - $result = array( - 'test', - 'test2' - ); - - $this->assertEquals( $result, pods_trim( $array ) ); - - $result = array( - ' test', - ' test2' - ); - - $this->assertEquals( $result, pods_trim( $array, null, 'r' ) ); - - $array = array( - ' test & ', - ' test2 ', - ); - - $result = array( - ' test', - ' test2' - ); - - $this->assertEquals( $result, pods_trim( $array, ' &', 'r' ) ); - - // Objects. - - $object = new stdClass(); - $object->test = ' test '; - $object->test2 = ' test2 '; - - $result = new stdClass(); - $result->test = 'test'; - $result->test2 = 'test2'; - - $this->assertEquals( $result, pods_trim( $object ) ); - - $result->test = ' test'; - $result->test2 = ' test2'; - - $this->assertEquals( $result, pods_trim( $object, null, 'r' ) ); - - $object->test = ' test & '; - $object->test2 = ' test2 '; - - $result->test = ' test'; - $result->test2 = ' test2'; - - $this->assertEquals( $result, pods_trim( $object, ' &', 'r' ) ); - - //$this->markTestIncomplete( 'not yet implemented' ); - } - - /** - * @covers pods_traverse - */ - public function test_pods_traverse() { - - /** - * Array values. - */ - $value = array( - 'foobar', - 'one' => 1, - 'two' => '2', - 'decimals' => array( - 'no_key', - 'second_no_key', - 'third_no_key', - 'half' => 0.5, - 'onehalf' => 1.5, - ), - ); - - // No traversal. - $this->assertEquals( $value, pods_traverse( null, $value ) ); - - // String traversal. - $this->assertEquals( 1, pods_traverse( 'one', $value ) ); - $this->assertEquals( '2', pods_traverse( 'two', $value ) ); - $this->assertEquals( 1.5, pods_traverse( 'decimals.onehalf', $value ) ); - $this->assertEquals( null, pods_traverse( 'invalid', $value ) ); - $this->assertEquals( null, pods_traverse( 'decimals.invalid', $value ) ); - - // Array traversal. - $this->assertEquals( 1, pods_traverse( array( 'one' ), $value ) ); - $this->assertEquals( '2', pods_traverse( array( 'two' ), $value ) ); - $this->assertEquals( 1.5, pods_traverse( array( 'decimals', 'onehalf' ), $value ) ); - $this->assertEquals( null, pods_traverse( array( 'invalid' ), $value ) ); - $this->assertEquals( null, pods_traverse( array( 'decimals', 'invalid' ), $value ) ); - - // Numeric array keys. - $this->assertEquals( 'foobar', pods_traverse( 0, $value ) ); - $this->assertEquals( 'third_no_key', pods_traverse( 'decimals.2', $value ) ); - $this->assertEquals( 'foobar', pods_traverse( array( 0 ), $value ) ); - $this->assertEquals( 'third_no_key', pods_traverse( array( 'decimals', 2 ), $value ) ); - - /** - * Object values. - * Numeric keys not available in objects. - */ - $value = new stdClass(); - $value->one = 1; - $value->two = '2'; - $value->decimals = new stdClass(); - $value->decimals->half = 0.5; - $value->decimals->onehalf = 1.5; - - // No traversal. - $this->assertEquals( $value, pods_traverse( null, $value ) ); - - // String traversal. - $this->assertEquals( 1, pods_traverse( 'one', $value ) ); - $this->assertEquals( '2', pods_traverse( 'two', $value ) ); - $this->assertEquals( 1.5, pods_traverse( 'decimals.onehalf', $value ) ); - $this->assertEquals( null, pods_traverse( 'invalid', $value ) ); - $this->assertEquals( null, pods_traverse( 'decimals.invalid', $value ) ); - - // Array traversal. - $this->assertEquals( 1, pods_traverse( array( 'one' ), $value ) ); - $this->assertEquals( '2', pods_traverse( array( 'two' ), $value ) ); - $this->assertEquals( 1.5, pods_traverse( array( 'decimals', 'onehalf' ), $value ) ); - $this->assertEquals( null, pods_traverse( array( 'invalid' ), $value ) ); - $this->assertEquals( null, pods_traverse( array( 'decimals', 'invalid' ), $value ) ); - - } - - public function test_pods_v() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_v_sanitized() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_v_set() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_var() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_var_raw() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_var_set() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_query_arg() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_var_update() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_cast() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_create_slug() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_unique_slug() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_clean_name() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - /** - * @covers ::pods_absint - */ - public function test_pods_absint() { - - $this->assertEquals( 1, pods_absint( 1.234 ) ); - } - - /** - * @covers ::pods_absint - */ - public function test_pods_absint_no_negative() { - - $this->assertEquals( 1, pods_absint( - 1.234 ) ); - } - - /** - * @covers ::pods_absint - */ - public function test_pods_absint_allows_negative() { - - $this->assertEquals( - 1, pods_absint( - 1.234, true, true ) ); - } - - /** - * @covers ::pods_absint - */ - public function test_pods_absint_returns_zero_for_string() { - - $this->assertEquals( 0, pods_absint( 'asdf' ) ); - } - - public function test_pods_str_replace() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - /** - * @covers ::pods_mb_strlen - */ - public function test_pods_mb_strlen() { - - $this->assertEquals( 4, pods_mb_strlen( 'asdf' ) ); - } - - /** - * @covers ::pods_mb_substr - */ - public function test_pods_mb_substr() { - - $this->assertEquals( 'sd', pods_mb_substr( 'asdf', 1, 2 ) ); - } - - /** - * @covers ::pods_evaluate_tags - * @covers ::pods_evaluate_tag - */ - public function test_pods_evaluate_tags() { - global $wpdb; - - /** - * Special magic tags. - * @link https://docs.pods.io/displaying-pods/magic-tags/special-magic-tags/ - */ - $this->assertEquals( - $wpdb->prefix, - pods_evaluate_tag( '{@prefix}' ) - ); - $this->assertEquals( - get_template_directory_uri(), - pods_evaluate_tag( '{@template-url}' ) - ); - $this->assertEquals( - get_stylesheet_directory_uri(), - pods_evaluate_tag( '{@stylesheet-url}' ) - ); - $this->assertEquals( - site_url(), - pods_evaluate_tag( '{@site-url}' ) - ); - $this->assertEquals( - home_url(), - pods_evaluate_tag( '{@home-url}' ) - ); - $this->assertEquals( - admin_url(), - pods_evaluate_tag( '{@admin-url}' ) - ); - $this->assertEquals( - includes_url(), - pods_evaluate_tag( '{@includes-url}' ) - ); - $this->assertEquals( - plugins_url(), - pods_evaluate_tag( '{@plugins-url}' ) - ); - $this->assertEquals( - network_site_url(), - pods_evaluate_tag( '{@network-site-url}' ) - ); - $this->assertEquals( - network_home_url(), - pods_evaluate_tag( '{@network-home-url}' ) - ); - $this->assertEquals( - network_admin_url(), - pods_evaluate_tag( '{@network-admin-url}' ) - ); - $this->assertEquals( - user_admin_url(), - pods_evaluate_tag( '{@user-admin-url}' ) - ); - $this->assertEquals( - date_i18n( 'Y-m-d' ), - pods_evaluate_tag( '{@date.Y-m-d}' ) - ); - $this->assertEquals( - date_i18n( 'Y-m-d', - strtotime( 'tomorrow' ) ), pods_evaluate_tag( '{@date.Y-m-d|tomorrow}' ) - ); - - // First log in the user. - $user_id = $this->factory()->user->create(); - wp_set_current_user( $user_id ); - $this->assertEquals( - get_current_user_id(), - pods_evaluate_tag( '{@user.id}' ) // Should be `ID` but added lowercase for backwards compatibility. - ); - - //$this->markTestIncomplete( 'not yet implemented' ); - } - - /** - * @covers ::pods_evaluate_tag_sql - */ - public function test_pods_evaluate_tag_sql() { - - $params = array( - 'sanitize' => true, - 'fallback' => '""', - ); - - // EQUALS - - $sql = "value = {@get.test_sql_tag}"; - $compare = 'value = ""'; - - $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); - - $_GET['test_sql_tag'] = '5797'; - $compare = 'value = 5797'; - - $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); - - // LIKE - - $sql = "value LIKE '{@get.test_sql_tag_like}%'"; - $compare = "value LIKE '%'"; - - $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); - - $_GET['test_sql_tag_like'] = '5797'; - $compare = "value LIKE '5797%'"; - - $this->assertEquals( pods_evaluate_tags_sql( $sql, $params ), $compare ); - } - - public function test_pods_evaluate_tag_sanitized() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_evaluate_tag() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_serial_comma() { - - $values = array( - 'test1', - 'test2', - 'test3', - ); - - $result = 'test1, test2, and test3'; - - $this->assertEquals( $result, pods_serial_comma( $values ) ); - - $args = array( - 'serial' => false, - ); - - $result = 'test1, test2 and test3'; - - $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); - - $args = array( - 'separator' => ' | ', - 'serial' => false, - ); - - $result = 'test1 | test2 and test3'; - - $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); - - $args = array( - 'and' => ' & ', - 'serial' => false, - ); - - $result = 'test1, test2 & test3'; - - $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); - - $args = array( - 'separator' => ' | ', - 'and' => ' | ', - 'serial' => false, - ); - - $result = 'test1 | test2 | test3'; - - $this->assertEquals( $result, pods_serial_comma( $values, $args ) ); - - //$this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_var_user() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_hierarchical_list() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_hierarchical_list_recurse() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_hierarchical_select() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - public function test_pods_hierarchical_select_recurse() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - - /** - * @covers ::pods_list_filter - */ - public function test_pods_list_filter() { - - // Test objects since that is not supported by wp_list_filter. - - $obj = new stdClass(); - $obj->obj1 = new stdClass(); - $obj->obj2 = new stdClass(); - $obj->obj3 = new stdClass(); - $obj->obj4 = new stdClass(); - - $obj->obj1->status = 'published'; - $obj->obj2->status = 'published'; - $obj->obj3->status = 'draft'; - $obj->obj4->status = 'published'; - - $obj->obj1->param = 'valid'; - $obj->obj2->param = 'invalid'; - $obj->obj3->param = 'valid'; - $obj->obj4->param = 'valid'; - - $args = array( - 'status' => 'published', - 'param' => 'valid', - ); - - $result = $obj; - unset( $result->obj2 ); - unset( $result->obj3 ); - - $this->assertEquals( $result, pods_list_filter( $obj, $args ) ); - - // NOT operator. - - $args = array( - 'status' => 'published', - ); - - $result = $obj; - unset( $result->obj1 ); - unset( $result->obj2 ); - unset( $result->obj4 ); - - $this->assertEquals( $result, pods_list_filter( $obj, $args, 'NOT' ) ); - - $this->markTestIncomplete( 'not yet implemented' ); - } - -} diff --git a/tests/phpunit/includes/tests-pods-field-boolean.php b/tests/phpunit/includes/tests-pods-field-boolean.php deleted file mode 100644 index 89ca37a127..0000000000 --- a/tests/phpunit/includes/tests-pods-field-boolean.php +++ /dev/null @@ -1,608 +0,0 @@ -field = new PodsField_Boolean(); - } - - public function tearDown() { - - unset( $this->field ); - } - - /** - * @covers ::options - */ - public function test_method_options_exists() { - - $this->assertTrue( method_exists( $this->field, 'options' ), 'Method ::options does not exist.' ); - } - - /** - * @covers ::options - * @depends test_method_options_exists - */ - public function test_method_options_returns_array() { - - $this->assertInternalType( 'array', $this->field->options() ); - } - - /** - * @covers ::options - * @depends test_method_options_exists - * @depends test_method_options_returns_array - */ - public function test_method_options_key_boolean_format_type_present() { - - $this->assertArrayHasKey( 'boolean_format_type', $this->field->options() ); - } - - /** - * @covers ::options - * @depends test_method_options_exists - * @depends test_method_options_returns_array - */ - public function test_method_options_key_boolean_yes_label_present() { - - $this->assertArrayHasKey( 'boolean_yes_label', $this->field->options() ); - } - - /** - * @covers ::options - * @depends test_method_options_exists - * @depends test_method_options_returns_array - */ - public function test_method_options_key_boolean_no_label_present() { - - $this->assertArrayHasKey( 'boolean_no_label', $this->field->options() ); - } - - /** - * @covers ::schema - */ - public function test_method_schema_exists() { - - $this->assertTrue( method_exists( $this->field, 'schema' ), 'Method ::schema does not exist.' ); - } - - /** - * @covers ::schema - * @depends test_method_schema_exists - */ - public function test_method_schema() { - - $this->assertEquals( 'BOOL DEFAULT 0', $this->field->schema() ); - } - - /** - * @covers ::display - */ - public function test_method_display_exists() { - - $this->assertTrue( method_exists( $this->field, 'display' ), 'Method ::display does not exist.' ); - } - - /** - * @covers ::display - * @depends test_method_display_exists - * @uses ::pods_v - */ - public function test_method_display_defaults() { - - $this->assertNUll( $this->field->display() ); - } - - /** - * @covers ::display - * @depends test_method_display_exists - * @uses ::pods_v - */ - public function test_method_display_true() { - - $this->assertEquals( 1, $this->field->display( 1 ) ); - } - - /** - * @covers ::display - * @depends test_method_display_exists - * @uses ::pods_v - */ - public function test_method_display_false() { - - $this->assertEquals( 0, $this->field->display( 0 ) ); - } - - /** - * @covers ::input - */ - public function test_method_input_exists() { - - $this->assertTrue( method_exists( $this->field, 'input' ), 'Method ::input does not exist.' ); - } - - /** - * @covers ::input - * @depends test_method_input_exists - * @uses Pods_Form::permission - * @uses ::pods_v - * @uses ::pods_has_permissions - */ - public function test_method_input_defaults() { - - $this->markTestIncomplete(); - } - - /** - * @covers ::data - */ - public function test_method_data_exists() { - - $this->assertTrue( method_exists( $this->field, 'data' ), 'Method ::data does not exist.' ); - } - - /** - * @covers ::data - * @depends test_method_data_exists - * @uses ::pods_v - */ - public function test_method_data_defaults() { - - $this->assertEquals( - array( - 1 => null, - 0 => null, - ), $this->field->data( 'foo' ) - ); - } - - /** - * @covers ::data - * @depends test_method_data_exists - * @uses ::pods_v - */ - public function test_method_data_format_type_radio() { - - $this->assertEquals( - array( - 1 => 'bar', - 0 => 'baz', - ), $this->field->data( - 'foo', null, array( - 'boolean_format_type' => 'radio', - 'boolean_yes_label' => 'bar', - 'boolean_no_label' => 'baz', - ) - ) - ); - } - - /** - * @covers ::data - * @depends test_method_data_exists - * @uses ::pods_v - */ - public function test_method_data_format_type_checkbox() { - - $this->assertEquals( - array( 1 => 'bar' ), $this->field->data( - 'foo', null, array( - 'boolean_format_type' => 'checkbox', - 'boolean_yes_label' => 'bar', - ) - ) - ); - } - - /** - * @covers ::regex - */ - public function test_method_regex_exists() { - - $this->assertTrue( method_exists( $this->field, 'regex' ), 'Method ::regex does not exist.' ); - } - - /** - * @covers ::regex - * @depends test_method_regex_exists - */ - public function test_method_regex() { - - $this->assertFalse( $this->field->regex() ); - } - - /** - * @covers ::validate - */ - public function test_method_validate_exists() { - - $this->assertTrue( method_exists( $this->field, 'validate' ), 'Method ::validate does not exist.' ); - } - - /** - * @covers ::validate - * @depends test_method_validate_exists - */ - public function test_method_validate() { - - // All values are valid as they are parsed to integers (1 or 0). - - $options = array( - 'boolean_format_type' => 'radio', - 'required' => false, - ); - - // Empty values. - $this->assertTrue( $this->field->validate( true, null, $options ) ); - $this->assertTrue( $this->field->validate( 1, null, $options ) ); - $this->assertTrue( $this->field->validate( '1', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); - $this->assertTrue( $this->field->validate( 'On', null, $options ) ); - $this->assertTrue( $this->field->validate( 'True', null, $options ) ); - - // Non empty values. - $this->assertTrue( $this->field->validate( false, null, $options ) ); - $this->assertTrue( $this->field->validate( 0, null, $options ) ); - $this->assertTrue( $this->field->validate( '0', null, $options ) ); - $this->assertTrue( $this->field->validate( 'No', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Off', null, $options ) ); - $this->assertTrue( $this->field->validate( 'False', null, $options ) ); - - // Other - $this->assertTrue( $this->field->validate( '', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Foobar', null, $options ) ); - - $options = array( - 'boolean_format_type' => 'radio', - 'required' => true, - ); - - // Empty values. - $this->assertTrue( $this->field->validate( true, null, $options ) ); - $this->assertTrue( $this->field->validate( 1, null, $options ) ); - $this->assertTrue( $this->field->validate( '1', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); - $this->assertTrue( $this->field->validate( 'On', null, $options ) ); - $this->assertTrue( $this->field->validate( 'True', null, $options ) ); - - // Non empty values. - $this->assertTrue( $this->field->validate( false, null, $options ) ); - $this->assertTrue( $this->field->validate( 0, null, $options ) ); - $this->assertTrue( $this->field->validate( '0', null, $options ) ); - $this->assertTrue( $this->field->validate( 'No', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Off', null, $options ) ); - $this->assertTrue( $this->field->validate( 'False', null, $options ) ); - - // Other - $this->assertTrue( $this->field->validate( '', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Foobar', null, $options ) ); - - $options = array( - 'boolean_format_type' => 'checkbox', - 'required' => false, - ); - - // Empty values. - $this->assertTrue( $this->field->validate( true, null, $options ) ); - $this->assertTrue( $this->field->validate( 1, null, $options ) ); - $this->assertTrue( $this->field->validate( '1', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); - $this->assertTrue( $this->field->validate( 'On', null, $options ) ); - $this->assertTrue( $this->field->validate( 'True', null, $options ) ); - - // Non empty values. - $this->assertTrue( $this->field->validate( false, null, $options ) ); - $this->assertTrue( $this->field->validate( 0, null, $options ) ); - $this->assertTrue( $this->field->validate( '0', null, $options ) ); - $this->assertTrue( $this->field->validate( 'No', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Off', null, $options ) ); - $this->assertTrue( $this->field->validate( 'False', null, $options ) ); - - // Other - $this->assertTrue( $this->field->validate( '', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Foobar', null, $options ) ); - - - /** - * Required checkbox. - * Only non_empty values are valid since a required checkbox only has one value. - */ - - $options = array( - 'boolean_format_type' => 'checkbox', - 'required' => true, - ); - - // Empty values. - $this->assertTrue( $this->field->validate( true, null, $options ) ); - $this->assertTrue( $this->field->validate( 1, null, $options ) ); - $this->assertTrue( $this->field->validate( '1', null, $options ) ); - $this->assertTrue( $this->field->validate( 'Yes', null, $options ) ); - $this->assertTrue( $this->field->validate( 'On', null, $options ) ); - $this->assertTrue( $this->field->validate( 'True', null, $options ) ); - - // Non empty values. - $this->assertNotTrue( $this->field->validate( false, null, $options ) ); - $this->assertNotTrue( $this->field->validate( 0, null, $options ) ); - $this->assertNotTrue( $this->field->validate( '0', null, $options ) ); - $this->assertNotTrue( $this->field->validate( 'No', null, $options ) ); - $this->assertNotTrue( $this->field->validate( 'Off', null, $options ) ); - $this->assertNotTrue( $this->field->validate( 'False', null, $options ) ); - - // Other - $this->assertNotTrue( $this->field->validate( '', null, $options ) ); // Parses to 0. - $this->assertNotTrue( $this->field->validate( 'Foobar', null, $options ) ); // Parses to 0. - } - - /** - * @covers ::is_empty - */ - public function test_method_is_empty() { - - // Empty values. - $this->assertTrue( $this->field->is_empty( false ) ); - $this->assertTrue( $this->field->is_empty( 0 ) ); - $this->assertTrue( $this->field->is_empty( '0' ) ); - $this->assertTrue( $this->field->is_empty( 'No' ) ); - $this->assertTrue( $this->field->is_empty( 'Off' ) ); - $this->assertTrue( $this->field->is_empty( 'False' ) ); - - // Non empty values. - $this->assertFalse( $this->field->is_empty( true ) ); - $this->assertFalse( $this->field->is_empty( 1 ) ); - $this->assertFalse( $this->field->is_empty( '1' ) ); - $this->assertFalse( $this->field->is_empty( 'Yes' ) ); - $this->assertFalse( $this->field->is_empty( 'On' ) ); - $this->assertFalse( $this->field->is_empty( 'True' ) ); - - // Other - $this->assertTrue( $this->field->is_empty( '' ) ); // Parses to 0. - $this->assertTrue( $this->field->is_empty( 'Foobar' ) ); // Parses to 0. - } - - /** - * @covers ::is_required - */ - public function test_method_is_required() { - - // Default - $options = array(); - $this->assertFalse( $this->field->is_required( $options ) ); - - // Int value. - $options['required'] = 1; - $this->assertTrue( $this->field->is_required( $options ) ); - $options['required'] = 0; - $this->assertFalse( $this->field->is_required( $options ) ); - - // Bool value. - $options['required'] = true; - $this->assertTrue( $this->field->is_required( $options ) ); - $options['required'] = false; - $this->assertFalse( $this->field->is_required( $options ) ); - - // String values. - $options['required'] = '1'; - $this->assertTrue( $this->field->is_required( $options ) ); - $options['required'] = '0'; - $this->assertFalse( $this->field->is_required( $options ) ); - $options['required'] = 'true'; - $this->assertTrue( $this->field->is_required( $options ) ); - $options['required'] = 'false'; - $this->assertFalse( $this->field->is_required( $options ) ); - $options['required'] = 'yes'; - $this->assertTrue( $this->field->is_required( $options ) ); - $options['required'] = 'no'; - $this->assertFalse( $this->field->is_required( $options ) ); - } - - /** - * @covers ::pre_save - */ - public function test_method_pre_save_exists() { - - $this->assertTrue( method_exists( $this->field, 'pre_save' ), 'Method ::pre_save does not exist.' ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_1() { - - $this->assertEquals( 1, $this->field->pre_save( 1 ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_yes() { - - $this->assertEquals( 1, $this->field->pre_save( 'yes' ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_capitalized_yes() { - - $this->assertEquals( 1, $this->field->pre_save( 'Yes' ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_0() { - - $this->assertEquals( 0, $this->field->pre_save( 0 ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_no() { - - $this->assertEquals( 0, $this->field->pre_save( 'no' ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_captialized_no() { - - $this->assertEquals( 0, $this->field->pre_save( 'No' ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_foo_no_label_match() { - - $this->assertEquals( 0, $this->field->pre_save( 'foo' ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_foo_matches_yes_label() { - - $this->assertEquals( 1, $this->field->pre_save( 'foo', null, null, array( 'boolean_yes_label' => 'foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_capitalized_foo_matches_yes_label() { - - $this->assertEquals( 1, $this->field->pre_save( 'Foo', null, null, array( 'boolean_yes_label' => 'foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_foo_matches_capitalized_yes_label() { - - $this->assertEquals( 1, $this->field->pre_save( 'foo', null, null, array( 'boolean_yes_label' => 'Foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_capitalized_foo_matches_capitalized_yes_label() { - - $this->assertEquals( 1, $this->field->pre_save( 'Foo', null, null, array( 'boolean_yes_label' => 'Foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_foo_matches_no_label() { - - $this->assertEquals( 0, $this->field->pre_save( 'foo', null, null, array( 'boolean_no_label' => 'foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_capitalized_foo_matches_no_label() { - - $this->assertEquals( 0, $this->field->pre_save( 'Foo', null, null, array( 'boolean_no_label' => 'foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_foo_matches_capitalized_no_label() { - - $this->assertEquals( 0, $this->field->pre_save( 'foo', null, null, array( 'boolean_no_label' => 'Foo' ) ) ); - } - - /** - * @covers ::pre_save - * @depends test_method_pre_save_exists - */ - public function test_method_pre_save_value_capitalized_foo_matches_capitalized_no_label() { - - $this->assertEquals( 0, $this->field->pre_save( 'Foo', null, null, array( 'boolean_no_label' => 'Foo' ) ) ); - } - - /** - * @covers ::ui - */ - public function test_method_ui_exists() { - - $this->assertTrue( method_exists( $this->field, 'ui' ), 'Method ::ui does not exist.' ); - } - - /** - * @covers ::ui - * @depends test_method_ui_exists - */ - public function test_method_ui_defaults_to_no() { - - $this->assertEquals( 'No', $this->field->ui( 'foo', 'bar' ) ); - } - - /** - * @covers ::ui - * @depends test_method_ui_exists - */ - public function test_method_ui_default_no_label() { - - $this->assertEquals( 'No', $this->field->ui( 'foo', 0 ) ); - } - - /** - * @covers ::ui - * @depends test_method_ui_exists - */ - public function test_method_ui_default_yes_label() { - - $this->assertEquals( 'Yes', $this->field->ui( 'foo', 1 ) ); - } - - /** - * @covers ::ui - * @depends test_method_ui_exists - */ - public function test_method_ui_custom_yes_label() { - - $this->assertEquals( 'Bar', $this->field->ui( 'foo', 1, null, array( 'boolean_yes_label' => 'Bar' ) ) ); - } - - /** - * @covers ::ui - * @depends test_method_ui_exists - */ - public function test_method_ui_custom_no_label() { - - $this->assertEquals( 'Bar', $this->field->ui( 'foo', 0, null, array( 'boolean_no_label' => 'Bar' ) ) ); - } -} diff --git a/tests/phpunit/includes/tests-pods-field-currency.php b/tests/phpunit/includes/tests-pods-field-currency.php deleted file mode 100644 index 5b27b2ae17..0000000000 --- a/tests/phpunit/includes/tests-pods-field-currency.php +++ /dev/null @@ -1,443 +0,0 @@ - "number", - "currency_format_sign" => "usd", - "currency_format_placement" => "before", - "currency_format" => "9,999.99", - "currency_decimals" => 2, - "currency_decimal_handling" => "default" - ); - - public function setUp() { - - $this->field = new PodsField_Currency(); - } - - public function tearDown() { - - unset( $this->field ); - } - - /** - * @dataProvider formatDefaultsProvider - */ - public function test_format_defaults( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); - } - - public function formatDefaultsProvider() { - - return array( - array( "-1", "-1.00" ), - array( "0", "0.00" ), - array( "1", "1.00" ), - array( "1.", "1.00" ), - array( "1.5", "1.50" ), - array( "10", "10.00" ), - array( "10.01", "10.01" ), - array( "100", "100.00" ), - array( "1000", "1,000.00" ), - array( "10000", "10,000.00" ), - array( "1000000", "1,000,000.00" ), - ); - } - - /** - * @dataProvider formatDecimalCommaProvider - */ - public function test_format_decimal_comma( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format' ] = '9.999,99'; - - $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); - } - - public function formatDecimalCommaProvider() { - - return array( - array( "-1", "-1,00" ), - array( "0", "0,00" ), - array( "1", "1,00" ), - array( "1.", "1,00" ), - array( "1.5", "1,50" ), - array( "10", "10,00" ), - array( "10.01", "10,01" ), - array( "100", "100,00" ), - array( "1000", "1.000,00" ), - array( "10000", "10.000,00" ), - array( "1000000", "1.000.000,00" ), - ); - } - - /** - * @dataProvider formatThousandsQuoteProvider - */ - public function test_format_thousands_quote( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format' ] = '9\'999.99'; - - $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); - } - - public function formatThousandsQuoteProvider() { - return array( - array( "1000", "1'000.00" ), - array( "10000", "10'000.00" ), - array( "1000000", "1'000'000.00" ), - ); - } - - /** - * @dataProvider formatSpaceCommaProvider - */ - public function test_format_space_comma( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format' ] = '9 999,99'; - - $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); - } - - public function formatSpaceCommaProvider() { - - return array( - array( "1000", "1 000,00" ), - array( "10000", "10 000,00" ), - array( "1000000", "1 000 000,00" ), - ); - } - - /** - * @dataProvider formatDecimalDashProvider - * @covers ::trim_decimals - */ - public function test_format_decimal_dash( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_decimal_handling' ] = 'dash'; - - $this->assertEquals( $expected, $this->field->format( $value, null, $options ) ); - } - - public function formatDecimalDashProvider() { - - return array( - array( "-1", "-1.-" ), - array( "0", "0.-" ), - array( "1", "1.-" ), - array( "1.", "1.-" ), - array( "1.5", "1.50" ), - array( "10", "10.-" ), - array( "10.01", "10.01" ), - array( "100", "100.-" ), - array( "1000", "1,000.-" ), - array( "10000", "10,000.-" ), - array( "1000000", "1,000,000.-" ), - ); - } - - /** - * @dataProvider displayDefaultProvider - */ - public function test_display_default( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - public function displayDefaultProvider() { - - return array( - array( "-1", "$-1.00" ), - array( "0", "$0.00" ), - array( "1", "$1.00" ), - array( "1.", "$1.00" ), - array( "1.5", "$1.50" ), - array( "10", "$10.00" ), - array( "10.01", "$10.01" ), - array( "100", "$100.00" ), - array( "1000", "$1,000.00" ), - array( "10000", "$10,000.00" ), - array( "1000000", "$1,000,000.00" ), - ); - } - - /** - * @dataProvider displayFormatCurrencyAfterProvider - */ - public function test_display_format_currency_after( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format_placement' ] = 'after'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - public function displayFormatCurrencyAfterProvider() { - - return array( - array( "-1", "-1.00$" ), - array( "0", "0.00$" ), - array( "1", "1.00$" ), - array( "1.", "1.00$" ), - array( "1.5", "1.50$" ), - array( "10", "10.00$" ), - array( "10.01", "10.01$" ), - array( "100", "100.00$" ), - array( "1000", "1,000.00$" ), - array( "10000", "10,000.00$" ), - array( "1000000", "1,000,000.00$" ), - ); - } - - /** - * @dataProvider displayFormatCurrencyAfterSpaceProvider - */ - public function test_display_format_currency_after_space( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format_placement' ] = 'after_space'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - public function displayFormatCurrencyAfterSpaceProvider() { - - return array( - array( "-1", "-1.00 $" ), - array( "0", "0.00 $" ), - array( "1", "1.00 $" ), - array( "1.", "1.00 $" ), - array( "1.5", "1.50 $" ), - array( "10", "10.00 $" ), - array( "10.01", "10.01 $" ), - array( "100", "100.00 $" ), - array( "1000", "1,000.00 $" ), - array( "10000", "10,000.00 $" ), - array( "1000000", "1,000,000.00 $" ), - ); - } - - /** - * @dataProvider saveDefaultsProvider - */ - public function test_save_defaults( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveDefaultsProvider() { - - return array( - array( "-1.00", "-1.00" ), - array( "0.00", "0.00" ), - array( "1", "1.00" ), - array( "1.00", "1.00" ), - array( "1.0000", "1.00" ), - array( "1.50", "1.50" ), - array( "10.00", "10.00" ), - array( "10.01", "10.01" ), - array( "100.00", "100.00" ), - array( "1,000.00", "1000.00" ), - array( "10,000.00", "10000.00" ), - array( "1,000,000.00", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatDecimalCommaProvider - */ - public function test_save_format_decimal_comma( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format' ] = '9.999,99'; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatDecimalCommaProvider() { - - return array( - array( "-1,00", "-1.00" ), - array( "0,00", "0.00" ), - array( "1", "1.00" ), - array( "1,", "1.00" ), - array( "1,00", "1.00" ), - array( "1,0000", "1.00" ), - array( "1,50", "1.50" ), - array( "10,00", "10.00" ), - array( "10,01", "10.01" ), - array( "100,00", "100.00" ), - array( "1.000,00", "1000.00" ), - array( "10.000,00", "10000.00" ), - array( "1.000.000,00", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatThousandsQuoteProvider - */ - public function test_save_format_thousands_quote( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format' ] = '9\'999.99'; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatThousandsQuoteProvider() { - - return array( - array( "1'000.00", "1000.00" ), - array( "10'000.00", "10000.00" ), - array( "1'000'000.00", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatSpaceCommaProvider - */ - public function test_save_format_space_comma_formats( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format' ] = '9 999,99'; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatSpaceCommaProvider() { - - return array( - array( "1 000,00", "1000.00" ), - array( "10 000,00", "10000.00" ), - array( "1 000 000,00", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatDecimalDashProvider - */ - public function test_save_format_decimal_dash( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_decimal_handling' ] = 'dash'; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatDecimalDashProvider() { - - return array( - array( "-1.-", "-1.00" ), - array( "0.-", "0.00" ), - array( "1", "1.00" ), - array( "1.-", "1.00" ), - array( "1.--", "1.00" ), - array( "1.00", "1.00" ), - array( "1.0000", "1.00" ), - array( "1.50", "1.50" ), - array( "10.-", "10.00" ), - array( "10.01", "10.01" ), - array( "100.-", "100.00" ), - array( "1,000.-", "1000.00" ), - array( "10,000.-", "10000.00" ), - array( "1,000,000.-", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatCurrencyDefaultProvider - */ - public function test_save_format_defaults_currency( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatCurrencyDefaultProvider() { - - return array( - array( "$-1.00", "-1.00" ), - array( "$0.00", "0.00" ), - array( "$1", "1.00" ), - array( "$1.00", "1.00" ), - array( "$1.0000", "1.00" ), - array( "$1.50", "1.50" ), - array( "$10.00", "10.00" ), - array( "$10.01", "10.01" ), - array( "$100.00", "100.00" ), - array( "$1,000.00", "1000.00" ), - array( "$10,000.00", "10000.00" ), - array( "$1,000,000.00", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatCurrencyAfterProvider - */ - public function test_save_format_currency_after( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format_placement' ] = 'after'; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatCurrencyAfterProvider() { - - return array( - array( "-1.00$", "-1.00" ), - array( "0.00$", "0.00" ), - array( "1$", "1.00" ), - array( "1.00$", "1.00" ), - array( "1.0000$", "1.00" ), - array( "1.50$", "1.50" ), - array( "10.00$", "10.00" ), - array( "10.01$", "10.01" ), - array( "100.00$", "100.00" ), - array( "1,000.00$", "1000.00" ), - array( "10,000.00$", "10000.00" ), - array( "1,000,000.00$", "1000000.00" ), - ); - } - - /** - * @dataProvider saveFormatCurrencyAfterSpaceProvider - */ - public function test_save_format_currency_after_space( $value, $expected ) { - $options = $this->defaultOptions; - $options[ 'currency_format_placement' ] = 'after_space'; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveFormatCurrencyAfterSpaceProvider() { - - return array( - array( "-1.00 $", "-1.00" ), - array( "0.00 $", "0.00" ), - array( "1 $", "1.00" ), - array( "1.00 $", "1.00" ), - array( "1.0000 $", "1.00" ), - array( "1.50 $", "1.50" ), - array( "10.00 $", "10.00" ), - array( "10.01 $", "10.01" ), - array( "100.00 $", "100.00" ), - array( "1,000.00 $", "1000.00" ), - array( "10,000.00 $", "10000.00" ), - array( "1,000,000.00 $", "1000000.00" ), - ); - } - -} diff --git a/tests/phpunit/includes/tests-pods-field-datetime.php b/tests/phpunit/includes/tests-pods-field-datetime.php deleted file mode 100644 index 4d0fe16e15..0000000000 --- a/tests/phpunit/includes/tests-pods-field-datetime.php +++ /dev/null @@ -1,186 +0,0 @@ - 'format', - 'datetime_format_custom' => '', - 'datetime_format_custom_js' => '', - 'datetime_format' => 'mdy', - 'datetime_time_type' => '12', - 'datetime_time_format_custom' => '', - 'datetime_time_format_custom_js' => '', - 'datetime_time_format' => 'h_mma', - 'datetime_time_format_24' => 'hh_mm', - 'datetime_allow_empty' => 1, - ); - - public function setUp() { - - $this->field = new PodsField_DateTime(); - } - - public function tearDown() { - - unset( $this->field ); - } - - /** - * @dataProvider displayDefaultProvider - */ - public function test_display_default( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - public function displayDefaultProvider() { - - return array( - array( '2017-12-06' , '12/06/2017 12:00am' ), - array( '2017-12-06 15:04' , '12/06/2017 3:04pm' ), - array( '2017-12-06 15:04:50', '12/06/2017 3:04pm' ), - array( '2017-06-12 15:04:50', '06/12/2017 3:04pm' ), - ); - } - - /** - * @dataProvider displayCustomFormatDMYProvider - */ - public function test_display_custom_format_dmy( $value, $expected ) { - $options = $this->defaultOptions; - - $options['datetime_type'] = 'custom'; - $options['datetime_format_custom'] = 'd/m/Y'; // Days and months switched. - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - public function displayCustomFormatDMYProvider() { - - return array( - array( '2017-12-06' , '06/12/2017 12:00am' ), - array( '2017-12-06 15:04' , '06/12/2017 3:04pm' ), - array( '2017-12-06 15:04:50', '06/12/2017 3:04pm' ), - array( '2017-06-12 15:04:50', '12/06/2017 3:04pm' ), - ); - } - - /** - * @dataProvider saveDefaultsProvider - */ - public function test_save_defaults( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveDefaultsProvider() { - - return array( - array( '2017-12-06' , '2017-12-06 00:00:00' ), - array( '2017-12-06 15:04' , '2017-12-06 15:04:00' ), - array( '2017-12-06 15:04:50', '2017-12-06 15:04:50' ), - array( '2017-06-12 15:04:50', '2017-06-12 15:04:50' ), - // Display format. - array( '12/06/2017 12:00am' , '2017-12-06 00:00:00' ), - array( '12/06/2017 3:04pm' , '2017-12-06 15:04:00' ), - array( '06/12/2017 3:04pm' , '2017-06-12 15:04:00' ), - ); - } - - /** - * @dataProvider saveCustomFormatDMYProvider - */ - public function test_save_custom_format_dmy( $value, $expected ) { - $options = $this->defaultOptions; - - $options['datetime_type'] = 'custom'; - $options['datetime_format_custom'] = 'd/m/Y'; // Days and months switched. - - $this->assertEquals( $expected, $this->field->pre_save( $value, null, null, $options ) ); - } - - public function saveCustomFormatDMYProvider() { - - return array( - array( '2017-12-06' , '2017-12-06 00:00:00' ), - array( '2017-12-06 15:04' , '2017-12-06 15:04:00' ), - array( '2017-12-06 15:04:50', '2017-12-06 15:04:50' ), - array( '2017-06-12 15:04:50', '2017-06-12 15:04:50' ), - // Display format d/m/Y. - array( '12/06/2017 12:00am' , '2017-06-12 00:00:00' ), - array( '12/06/2017 3:04pm' , '2017-06-12 15:04:00' ), - array( '06/12/2017 3:04pm' , '2017-12-06 15:04:00' ), - ); - } - - /** - * @dataProvider validateDefaultsProvider - */ - public function test_validate_defaults( $value, $expected ) { - $options = $this->defaultOptions; - - $this->assertEquals( $expected, $this->field->validate( $value, null, null, $options ) ); - } - - public function validateDefaultsProvider() { - - return array( - array( '2017-12-06' , true ), - array( '2017-12-06 15:04' , true ), - array( '2017-12-06 15:04:50', true ), - array( '2017-06-12 15:04:50', true ), - // Display format. - array( '12/06/2017 12:00am' , true ), - array( '12/06/2017 3:04pm' , true ), - array( '06/12/2017 3:04pm' , true ), - ); - } - - /** - * @dataProvider validateCustomFormatDMYProvider - */ - public function test_validate_custom_format_dmy( $value, $expected ) { - $options = $this->defaultOptions; - - $options['datetime_type'] = 'custom'; - $options['datetime_format_custom'] = 'd/m/Y'; // Days and months switched. - - $this->assertEquals( $expected, $this->field->validate( $value, null, null, $options ) ); - } - - public function validateCustomFormatDMYProvider() { - - return array( - array( '2017-12-06' , true ), - array( '2017-12-06 15:04' , true ), - array( '2017-12-06 15:04:50', true ), - array( '2017-06-12 15:04:50', true ), - // Display format. - array( '12/06/2017 12:00am' , true ), - array( '12/06/2017 3:04pm' , true ), - array( '06/12/2017 3:04pm' , true ), - ); - } - -} diff --git a/tests/phpunit/includes/tests-pods-field-pick.php b/tests/phpunit/includes/tests-pods-field-pick.php deleted file mode 100644 index ed6c2927a9..0000000000 --- a/tests/phpunit/includes/tests-pods-field-pick.php +++ /dev/null @@ -1,103 +0,0 @@ - "single", - "pick_format_single" => "dropdown", - "pick_format_multi" => "checkbox", - "pick_display_format_multi" => "default", - "pick_display_format_separator" => ", ", - ); - - public function setUp() { - - $this->field = new PodsField_Pick(); - } - - public function tearDown() { - - unset( $this->field ); - } - - /** - * Single values. - */ - public function test_format_defaults() { - $options = $this->defaultOptions; - - $value = array( - 'item1', - ); - - $expected = 'item1'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - /** - * Multiple values and display formats. - */ - public function test_display_format_multi_simple() { - $options = $this->defaultOptions; - $options[ 'pick_format_type' ] = 'multi'; - - $value = array( - 'item1', - 'item2', - 'item3', - ); - - $expected = 'item1, item2, and item3'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - - // no_serial display format. - $options[ 'pick_display_format_multi' ] = 'non_serial'; - - $expected = 'item1, item2 and item3'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - - // custom display format. - $options[ 'pick_display_format_multi' ] = 'custom'; - - $expected = 'item1, item2, item3'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - - // custom display format separator. - $options[ 'pick_display_format_multi' ] = 'custom'; - $options[ 'pick_display_format_separator' ] = ' | '; - - $expected = 'item1 | item2 | item3'; - - $this->assertEquals( $expected, $this->field->display( $value, null, $options ) ); - } - - /** - * @todo Cover display tests with actual relationship values. - */ - public function test_display_format_multi_relationship() { - - $this->markTestIncomplete( 'not yet implemented' ); - } - -} diff --git a/tests/phpunit/includes/tests-pods-meta.php b/tests/phpunit/includes/tests-pods-meta.php deleted file mode 100644 index 96049a5ace..0000000000 --- a/tests/phpunit/includes/tests-pods-meta.php +++ /dev/null @@ -1,294 +0,0 @@ -core(); - - } - - /** - * @covers PodsMeta::save_post_detect_new - * @since 2.6.8 - */ - public function test_save_post_detect_new() { - - pods_no_conflict_on( 'post' ); - - $post_id = wp_insert_post( - array( - 'post_title' => 'Testing', - 'post_type' => 'post', - 'post_status' => 'draft', - ) - ); - - pods_no_conflict_off( 'post' ); - - $this->assertArrayNotHasKey( 'post', \PodsMeta::$old_post_status ); - - wp_update_post( - array( - 'ID' => $post_id, - 'post_status' => 'publish', - ) - ); - - $this->assertArrayHasKey( 'post', \PodsMeta::$old_post_status ); - $this->assertEquals( 'draft', \PodsMeta::$old_post_status['post'] ); - - } - - /** - * @covers PodsMeta::save_post - * @since 2.6.8 - */ - public function test_save_post_create() { - - $this->_add_save_actions(); - - $_POST['pods_meta'] = wp_create_nonce( 'pods_meta_post' ); - - pods_no_conflict_on( 'post' ); - - wp_insert_post( - array( - 'post_title' => 'Testing 1', - 'post_type' => 'post', - 'post_status' => 'draft', - ) - ); - - pods_no_conflict_off( 'post' ); - - $this->assertArrayNotHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - - wp_insert_post( - array( - 'post_title' => 'Testing 2', - 'post_type' => 'post', - 'post_status' => 'draft', - ) - ); - - $this->assertArrayHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - $this->_remove_save_actions(); - - } - - /** - * @covers PodsMeta::save_post - * @since 2.6.8 - */ - public function test_save_post_edit() { - - $this->_add_save_actions(); - - $_POST['pods_meta'] = wp_create_nonce( 'pods_meta_post' ); - - pods_no_conflict_on( 'post' ); - - $post_id = wp_insert_post( - array( - 'post_title' => 'Testing 1', - 'post_type' => 'post', - 'post_status' => 'draft', - ) - ); - - pods_no_conflict_off( 'post' ); - - $this->assertArrayNotHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - - wp_update_post( - array( - 'ID' => $post_id, - 'post_status' => 'publish', - ) - ); - - $this->assertArrayHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - $this->_remove_save_actions(); - - } - - /** - * @covers PodsMeta::save_user - * @since 2.6.8 - */ - public function test_save_user_create() { - - $this->_add_save_actions(); - - $_POST['pods_meta'] = wp_create_nonce( 'pods_meta_user' ); - - pods_no_conflict_on( 'user' ); - - wp_insert_user( - array( - 'user_login' => '1' . wp_generate_password( 10, false ), - 'user_email' => '1' . wp_generate_password( 10, false ) . '@example.com', - 'user_pass' => wp_generate_password(), - ) - ); - - pods_no_conflict_off( 'user' ); - - $this->assertArrayNotHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - - wp_insert_user( - array( - 'user_login' => '2' . wp_generate_password( 10, false ), - 'user_email' => '2' . wp_generate_password( 10, false ) . '@example.com', - 'user_pass' => wp_generate_password(), - ) - ); - - $this->assertArrayHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - $this->_remove_save_actions(); - - } - - /** - * @covers PodsMeta::save_user - * @since 2.6.8 - */ - public function test_save_user_edit() { - - $this->_add_save_actions(); - - $_POST['pods_meta'] = wp_create_nonce( 'pods_meta_user' ); - - pods_no_conflict_on( 'user' ); - - $user_id = wp_insert_user( - array( - 'user_login' => '3' . wp_generate_password( 10, false ), - 'user_email' => '3' . wp_generate_password( 10, false ) . '@example.com', - 'user_pass' => wp_generate_password(), - ) - ); - - pods_no_conflict_off( 'user' ); - - $this->assertArrayNotHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - - wp_update_user( - array( - 'ID' => $user_id, - 'user_email' => '4' . wp_generate_password( 10, false ) . '@example.com', - ) - ); - - $this->assertArrayHasKey( 'pods_api_post_save_pod_item', self::$hooked ); - $this->assertArrayNotHasKey( 'pods_api_post_create_pod_item', self::$hooked ); - $this->assertArrayHasKey( 'pods_api_post_edit_pod_item', self::$hooked ); - - $this->_reset_hooks(); - $this->_remove_save_actions(); - - } - - /** - * Track current hook info - * - * @since 2.6.8 - */ - public function _track_hook() { - - self::$hooked[ \current_filter() ] = func_get_args(); - - } - - /** - * Reset hook info - * - * @since 2.6.8 - */ - public function _reset_hooks() { - - self::$hooked = array(); - - } - - /** - * Add save hook actions - * - * @since 2.6.8 - */ - public function _add_save_actions() { - - add_action( 'pods_api_post_save_pod_item', array( $this, '_track_hook' ), 10, 3 ); - add_action( 'pods_api_post_create_pod_item', array( $this, '_track_hook' ), 10, 3 ); - add_action( 'pods_api_post_edit_pod_item', array( $this, '_track_hook' ), 10, 3 ); - - } - - /** - * Remove save hook actions - * - * @since 2.6.8 - */ - public function _remove_save_actions() { - - remove_action( 'pods_api_post_save_pod_item', array( $this, '_track_hook' ) ); - remove_action( 'pods_api_post_create_pod_item', array( $this, '_track_hook' ) ); - remove_action( 'pods_api_post_edit_pod_item', array( $this, '_track_hook' ) ); - - } - -} diff --git a/tests/phpunit/includes/tests-pods.php b/tests/phpunit/includes/tests-pods.php deleted file mode 100644 index 73461f0288..0000000000 --- a/tests/phpunit/includes/tests-pods.php +++ /dev/null @@ -1,496 +0,0 @@ -pods = pods(); - } - - public function tearDown() { - - unset( $this->pods ); - } - - /** - * Test the add method when passing empty parameters - * - * @covers Pods::add - * @since 3.0.0 - */ - public function test_method_add_empty() { - - $this->assertTrue( method_exists( $this->pods, 'add' ), 'Method add does not exist' ); - - $return = $this->pods->add( null, null ); - - $this->assertInternalType( 'int', $return ); - $this->assertEquals( 0, $return ); - } - - /** - * @covers Pods::exists - * @since 3.0.0 - */ - public function test_method_exists_exists() { - - $this->assertTrue( method_exists( $this->pods, 'exists' ), 'Method exists does not exist' ); - } - - /** - * Test pod does not exist - * - * @covers Pods::exists - * @since 3.0.0 - */ - public function test_method_exists_false() { - - $this->assertFalse( $this->pods->exists() ); - } - - /** - * @covers Pods::exists - * @since 3.0.0 - */ - public function test_method_exists() { - - $this->setReflectionPropertyValue( $this->pods, 'row', 'foo' ); - $this->assertTrue( $this->pods->exists() ); - } - - /** - * @covers Pods::valid - * @since 3.0.0 - */ - public function test_method_exists_valid() { - - $this->assertTrue( method_exists( $this->pods, 'valid' ), 'Method valid does not exist' ); - } - - /** - * Test for invalid pod - * - * @covers Pods::valid - * @depends test_method_exists_valid - * @since 3.0.0 - */ - public function test_method_valid_invalid() { - - $this->assertFalse( $this->pods->valid() ); - } - - /** - * @covers Pods::valid - * @depends test_method_exists_valid - * @since 3.0.0 - */ - public function test_method_valid_iterator() { - - $this->setReflectionPropertyValue( $this->pods, 'pod_id', 1 ); - $this->setReflectionPropertyValue( $this->pods, 'iterator', true ); - $this->assertFalse( $this->pods->valid() ); - } - - /** - * @covers Pods::valid - * @depends test_method_exists_valid - * @since 3.0.0 - */ - public function test_method_valid() { - - $this->setReflectionPropertyValue( $this->pods, 'pod_id', 1 ); - $this->assertTrue( $this->pods->valid() ); - } - - /** - * @covers Pods::is_iterator - * @since 3.0.0 - */ - public function test_method_is_iterator() { - - $this->assertTrue( method_exists( $this->pods, 'is_iterator' ), 'Method is_iterator does not exist' ); - $this->setReflectionPropertyValue( $this->pods, 'iterator', true ); - $this->assertTrue( $this->pods->is_iterator() ); - } - - /** - * @covers Pods::stop_iterator - * @since 3.0.0 - */ - public function test_method_stop_iterator() { - - $this->assertTrue( method_exists( $this->pods, 'stop_iterator' ), 'Method stop_iterator does not exist' ); - $this->setReflectionPropertyValue( $this->pods, 'iterator', true ); - $this->pods->stop_iterator(); - $this->assertFalse( $this->getReflectionPropertyValue( $this->pods, 'iterator' ) ); - } - - /** - * @covers Pods::rewind - * @since 3.0.0 - */ - public function test_method_rewind_exists() { - - $this->assertTrue( method_exists( $this->pods, 'rewind' ), 'Method rewind does not exist' ); - } - - /** - * @covers Pods::rewind - * @depends test_method_rewind_exists - * @since 3.0.0 - */ - public function test_method_rewind() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', false ); - $this->assertNull( $this->pods->rewind(), 'Pods::rewind did not return null' ); - $this->assertEquals( 0, $this->getReflectionPropertyValue( $this->pods, 'row_number' ) ); - } - - /** - * @covers Pods::current - * @since 3.0.0 - */ - public function test_method_current_exists() { - - $this->assertTrue( method_exists( $this->pods, 'current' ), 'Method current does not exist' ); - } - - /** - * Test current when iterator = false - * - * @covers Pods::current - * @depends test_method_current_exists - * @since 3.0.0 - */ - public function test_method_current_iterator_false() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', false ); - $this->assertFalse( $this->pods->current() ); - } - - /** - * Test current when iterator = true - * - * @covers Pods::current - * @depends test_method_current_exists - * @since 3.0.0 - */ - public function test_method_current_iterator_true() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', true ); - $this->assertFalse( $this->pods->current() ); - } - - /** - * @covers Pods::key - * @since 3.0.0 - */ - public function test_method_key_exists() { - - $this->assertTrue( method_exists( $this->pods, 'key' ) ); - } - - /** - * Test key when iterator = false - * - * @covers Pods::key - * @depends test_method_key_exists - * @since 3.0.0 - */ - public function test_method_key_iterator_false() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', false ); - $this->setReflectionPropertyValue( $this->pods, 'row_number', 22 ); - $this->assertEquals( 22, $this->pods->key() ); - } - - /** - * Test current when iterator = true - * - * @covers Pods::key - * @depends test_method_key_exists - * @since 3.0.0 - */ - public function test_method_key() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', true ); - $this->setReflectionPropertyValue( $this->pods, 'row_number', 22 ); - $this->assertEquals( 22, $this->pods->key() ); - } - - /** - * @covers Pods::next - * @since 3.0.0 - */ - public function test_method_next_exists() { - - $this->assertTrue( method_exists( $this->pods, 'next' ) ); - } - - /** - * Test next when iterator = false - * - * @covers Pods::next - * @depends test_method_next_exists - * @since 3.0.0 - */ - public function test_method_next_iterator_false() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', false ); - $this->setReflectionPropertyValue( $this->pods, 'row_number', 19 ); - $this->assertNull( $this->pods->next() ); - $this->assertEquals( 20, $this->getReflectionPropertyValue( $this->pods, 'row_number' ), 'The row number was not incremented correctly' ); - } - - /** - * Test next when iterator = true - * - * @covers Pods::next - * @depends test_method_next_exists - * @since 3.0.0 - */ - public function test_method_next() { - - $this->setReflectionPropertyValue( $this->pods, 'iterator', true ); - $this->setReflectionPropertyValue( $this->pods, 'row_number', 19 ); - $this->assertNull( $this->pods->next() ); - $this->assertEquals( 20, $this->getReflectionPropertyValue( $this->pods, 'row_number' ), 'The row number was not incremented correctly' ); - } - - /** - * @covers Pods::input - * @since 3.0.0 - */ - public function test_method_exists_input() { - - $this->assertTrue( method_exists( $this->pods, 'input' ), 'Method input does not exist' ); - } - - /** - * Test input when field parameter is string and does not exist - * - * @covers Pods::input - * @depends test_method_exists_input - * @since 3.0.0 - */ - public function test_method_input_field_string_missing_field() { - - $this->expectOutputString( '' ); - $this->pods->input( 'foo' ); - } - - /** - * Test input when field parameter is empty array - * - * @covers Pods::input - * @depends test_method_exists_input - * @since 3.0.0 - */ - public function test_method_input_field_empty_array() { - - $this->expectOutputString( '' ); - $this->pods->input( array() ); - } - - /** - * @covers Pods::row - * @since 3.0.0 - */ - public function test_method_exists_row() { - - $this->assertTrue( method_exists( $this->pods, 'row' ), 'Method row does not exist' ); - } - - /** - * @covers Pods::row - * @depends test_method_exists_row - * @since 3.0.0 - */ - public function test_method_row_false() { - - $this->assertFalse( $this->pods->row() ); - } - - /** - * @covers Pods::row - * @depends test_method_exists_row - * @since 3.0.0 - */ - public function test_method_row() { - - $this->setReflectionPropertyValue( $this->pods, 'row', array() ); - $this->assertInternalType( 'array', $this->pods->row() ); - } - - /** - * @covers Pods::data - * @since 3.0.0 - */ - public function test_method_exists_data() { - - $this->assertTrue( method_exists( $this->pods, 'data' ), 'Method data does not exist' ); - } - - /** - * @covers Pods::data - * @depends test_method_exists_data - * @since 3.0.0 - */ - public function test_method_data_empty_rows() { - - $this->setReflectionPropertyValue( $this->pods, 'rows', array() ); - $this->assertFalse( $this->pods->data() ); - } - - /** - * @covers Pods::data - * @depends test_method_exists_data - * @since 3.0.0 - */ - public function test_method_data() { - - $this->setReflectionPropertyValue( $this->pods, 'rows', array( 'foo' => 'bar' ) ); - $this->assertEquals( array( 'foo' => 'bar' ), $this->pods->data() ); - } - - /** - * @covers Pods::__get - * @since 3.0.0 - */ - public function test_method_exists_get() { - - $this->assertTrue( method_exists( $this->pods, '__get' ), 'Method __get does not exist' ); - } - - /** - * Test the get method when the property does exist - * - * @covers Pods::__get - * @depends test_method_exists_get - * @since 3.0.0 - */ - public function test_method_get() { - - $this->pods->data->field_foo = 'bar'; - - $this->assertEquals( 'bar', $this->pods->field_foo ); - } - - /** - * Test the get method when the property does exist in the deprecated class - * - * @covers Pods::__get - * @depends test_method_exists_get - * @since 3.0.0 - */ - public function test_method_get_deprecated_property() { - - $deprecated = Mockery::mock( 'Pods_Deprecated' ); - $deprecated->foo = 'bar'; - $this->pods->deprecated = $deprecated; - - $this->assertEquals( 'bar', @$this->pods->foo ); - } - - /** - * Test the get method error when the property does exist in the deprecated class - * - * @covers Pods::__get - * @depends test_method_exists_get - * @since 3.0.0 - */ - public function test_method_get_deprecated_property_error() { - - $deprecated = Mockery::mock( 'Pods_Deprecated' ); - $deprecated->foo = 'bar'; - $this->pods->deprecated = $deprecated; - - $this->markTestIncomplete( 'not yet implemented' ); - - // @todo needs fixing - // $this->setExpectedException( 'PHPUnit_Framework_Error_Notice' ); - // $test = $this->pods->foo; - } - - /** - * @covers Pods::__call - * @since 3.0.0 - */ - public function test_method_exists_call() { - - $this->assertTrue( method_exists( $this->pods, '__call' ), 'Method __call does not exist' ); - } - - /** - * Test the __call method when the called method does not exist in the deprecated class - * - * @covers Pods::__call - * @depends test_method_exists_call - * @since 3.0.0 - */ - public function test_method_call_method_does_not_exist() { - - $deprecated = Mockery::mock( 'Pods_Deprecated' ); - $this->pods->deprecated = $deprecated; - - $this->assertNull( @$this->pods->__call( 'foo', array() ) ); - } - - /** - * Test the __call method error when the called method does not exist in the deprecated class - * - * @covers Pods::__call - * @depends test_method_exists_call - * @since 3.0.0 - */ - public function test_method_call_deprecated_method_error() { - - $deprecated = Mockery::mock( 'Pods_Deprecated' ); - $this->pods->deprecated = $deprecated; - - $this->markTestIncomplete( 'not yet implemented' ); - - // $this->setExpectedException( 'PHPUnit_Framework_Error_Notice' ); - // $test = $this->pods->__call( 'foo', array() ); - } - - /** - * @covers Pods::id - * @since 3.0.0 - */ - public function test_method_id_field_does_not_exist() { - - $this->assertTrue( method_exists( $this->pods, 'id' ), 'Method id does not exist' ); - - $data = new \stdClass(); - $data->field_id = 1; - $this->setReflectionPropertyValue( $this->pods, 'data', $data ); - - $this->assertNull( $this->pods->id() ); - } -} diff --git a/tests/phpunit/includes/tests-shortcodes.php b/tests/phpunit/includes/tests-shortcodes.php deleted file mode 100644 index 86c2907509..0000000000 --- a/tests/phpunit/includes/tests-shortcodes.php +++ /dev/null @@ -1,133 +0,0 @@ -pod_id = pods_api()->save_pod( - array( - 'storage' => 'table', - 'type' => 'pod', - 'name' => 'planet', - ) - ); - $this->pod = pods( 'planet' ); - - // register the fields - $params = array( - 'pod' => 'planet', - 'pod_id' => $this->pod_id, - 'name' => 'number_of_moons', - 'type' => 'number', - ); - pods_api()->save_field( $params ); - - } - - public function tearDown() { - - pods_api()->delete_pod( array( 'id' => $this->pod_id ) ); - - } - - /** - * @since 3.0.0 - */ - public function test_shortcode_pods() { - - // add an item - $this->pod->add( - array( - 'name' => 'Tatooine', - 'number_of_moons' => 5, - ) - ); - - // test shortcode - $this->assertEquals( '5', do_shortcode( '[pods name="planet" where="t.number_of_moons=5"]{@number_of_moons}[/pods]' ) ); - - // add another item - $this->pod->add( - array( - 'name' => 'Alderaan', - 'number_of_moons' => 7, - ) - ); - - // test shortcode - $this->assertEquals( '5', do_shortcode( '[pods name="planet" where="t.number_of_moons=5"]{@number_of_moons}[/pods]' ) ); - - // add third item - $this->pod->add( - array( - 'name' => 'Hoth', - 'number_of_moons' => 5, - ) - ); - - // test shortcode - $this->assertEquals( '55', do_shortcode( '[pods name="planet" where="t.number_of_moons=5"]{@number_of_moons}[/pods]' ) ); - - // Test the pagination parameter - /** @see http://php.net/manual/en/filter.filters.validate.php FILTER_VALIDATE_BOOLEAN */ - $this->assertContains( 'assertContains( 'assertContains( 'assertContains( 'assertContains( 'assertContains( 'assertEquals( '~~', do_shortcode( '[pods name="planet" pagination="0" limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination="false" limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination="off" limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination="no" limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination=0 limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination=false limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination=-1 limit="2"]~[/pods]' ) ); - $this->assertEquals( '~~', do_shortcode( '[pods name="planet" pagination=xyzzy limit="2"]~[/pods]' ) ); - - // Not enough records to trigger pagination even if on - $this->assertNotContains( 'assertEquals( '57', do_shortcode( '[pods name="planet" page="1" limit="2"]{@number_of_moons}[/pods]' ) ); - $this->assertEquals( '5', do_shortcode( '[pods name="planet" page="2" limit="2"]{@number_of_moons}[/pods]' ) ); - - } - - /** - * PR 2339 - * - * @link https://github.com/pods-framework/pods/pull/2339 - * @since 3.0.0 - */ - public function test_shortcode_pods_field_in_shortcode() { - - // add an item - $this->pod->add( - array( - 'name' => 'Dagobah', - 'number_of_moons' => 5, - ) - ); - - // test shortcode - $this->assertEquals( '5', do_shortcode( '[pods name="planet" where="t.number_of_moons=5" field="number_of_moons"]' ) ); - - } - -} diff --git a/tests/phpunit/includes/tests-traversal.php b/tests/phpunit/includes/tests-traversal.php deleted file mode 100644 index 3b625b9b2e..0000000000 --- a/tests/phpunit/includes/tests-traversal.php +++ /dev/null @@ -1,1400 +0,0 @@ -_test_find_base( $variant_id, $options ); - - } - - /** - * @group traversal - * @group traversal-find - * @group traversal-shallow - * @group traversal-find-shallow - * @group traversal-query-fields - * - * @covers Pods::valid - * @covers Pods::find - * @covers Pods::total - * @covers Pods::total_found - * @covers Pods::fetch - * @covers Pods::id - * @covers PodsData::select - * @covers PodsData::build - * @covers PodsData::query - * - * @dataProvider data_provider_base - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_find_base_query_fields( $variant_id, $options ) { - - $this->_test_find_base( $variant_id, $options, true ); - - } - - /** - * @group traversal - * @group traversal-find - * @group traversal-shallow - * @group traversal-find-shallow - * - * @covers Pods::valid - * @covers Pods::find - * @covers Pods::total - * @covers Pods::total_found - * @covers Pods::fetch - * @covers Pods::id - * @covers PodsData::select - * @covers PodsData::build - * @covers PodsData::traverse - * @covers PodsData::traverse_build - * @covers PodsData::traverse_recurse - * @covers PodsData::query - * - * @dataProvider data_provider - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_find_traversal( $variant_id, $options ) { - - $this->_test_find_traversal( $variant_id, $options ); - - } - - /** - * @group traversal - * @group traversal-find - * @group traversal-shallow - * @group traversal-find-shallow - * @group traversal-query-fields - * - * @covers Pods::valid - * @covers Pods::find - * @covers Pods::total - * @covers Pods::total_found - * @covers Pods::fetch - * @covers Pods::id - * @covers PodsData::select - * @covers PodsData::build - * @covers PodsData::traverse - * @covers PodsData::traverse_build - * @covers PodsData::traverse_recurse - * @covers PodsData::query - * @covers PodsData::query_fields - * @covers PodsData::query_field - * - * @dataProvider data_provider - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_find_traversal_query_fields( $variant_id, $options ) { - - $this->_test_find_traversal( $variant_id, $options, false, true ); - - } - - /** - * @group traversal - * @group traversal-find - * @group traversal-deep - * @group traversal-find-deep - * - * @covers Pods::valid - * @covers Pods::find - * @covers Pods::total - * @covers Pods::total_found - * @covers Pods::fetch - * @covers Pods::id - * @covers PodsData::select - * @covers PodsData::build - * @covers PodsData::traverse - * @covers PodsData::traverse_build - * @covers PodsData::traverse_recurse - * @covers PodsData::query - * - * @dataProvider data_provider_deep - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_find_deep_traversal( $variant_id, $options ) { - - $this->_test_find_traversal( $variant_id, $options, true ); - - } - - /** - * @group traversal - * @group traversal-find - * @group traversal-deep - * @group traversal-find-deep - * @group traversal-query-fields - * - * @covers Pods::valid - * @covers Pods::find - * @covers Pods::total - * @covers Pods::total_found - * @covers Pods::fetch - * @covers Pods::id - * @covers PodsData::select - * @covers PodsData::build - * @covers PodsData::traverse - * @covers PodsData::traverse_build - * @covers PodsData::traverse_recurse - * @covers PodsData::query - * @covers PodsData::query_fields - * @covers PodsData::query_field - * - * @dataProvider data_provider_deep - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_find_deep_traversal_query_fields( $variant_id, $options ) { - - $this->markTestIncomplete( 'query_fields does not yet support traversal auto handling of prefix/suffix' ); - - $this->_test_find_traversal( $variant_id, $options, true, true ); - - } - - /** - * @group traversal - * @group traversal-field - * @group traversal-shallow - * @group traversal-field-shallow - * - * @covers Pods::valid - * @covers Pods::exists - * @covers Pods::field - * @covers Pods::display - * @covers Pods::id - * @covers PodsData::query - * - * @dataProvider data_provider_base - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_field_base( $variant_id, $options ) { - - // Suppress MySQL errors - add_filter( 'pods_error_die', '__return_false' ); - - // global $wpdb; - // $wpdb->suppress_errors( true ); - // $wpdb->hide_errors(); - // Options - $pod_type = $options['pod_type']; - $storage_type = $options['storage_type']; - $pod = $options['pod']; - - // Do setup for Pod (tearDown / setUp) per storage type - if ( in_array( $pod_type, array( 'user', 'media', 'comment' ) ) && 'meta' !== $storage_type ) { - return; - - // @todo do magic - $this->assertTrue( false, sprintf( 'Pod / Storage type requires new setUp() not yet built to continue [%s]', $variant_id ) ); - } - - $data = self::$related_items[ $pod['name'] ]; - - $data['id'] = (int) $data['id']; - - $p = pods( $pod['name'], $data['id'] ); - - $data['field_id'] = $p->pod_data['field_id']; - $data['field_index'] = $p->pod_data['field_index']; - - $this->assertTrue( is_object( $p ), sprintf( 'Pod not object [%s]', $variant_id ) ); - $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); - $this->assertInstanceOf( 'Pods', $p, sprintf( 'Pod object not a Pod [%s]', $variant_id ) ); - - $this->assertTrue( $p->exists(), sprintf( 'Pod item not found [%s]', $variant_id ) ); - - $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['field_id'], $variant_id ) ); - $this->assertEquals( (string) $data['id'], (string) $p->field( $data['field_id'] ), sprintf( 'Item ID not as expected (%s) [%s]', $data['field_id'], $variant_id ) ); - $this->assertEquals( (string) $data['id'], (string) $p->display( $data['field_id'] ), sprintf( 'Item ID not as expected (%s) [%s]', $data['field_id'], $variant_id ) ); - - $this->assertEquals( $data['field_index'], $p->data->field_index, sprintf( 'Item index not as expected (%s) [%s]', $data['field_index'], $variant_id ) ); - $this->assertEquals( $data['data'][ $data['field_index'] ], $p->display( $data['field_index'] ), sprintf( 'Item index not as expected (%s) [%s]', $data['field_index'], $variant_id ) ); - - } - - /** - * @group traversal - * @group traversal-field - * @group traversal-shallow - * @group traversal-field-shallow - * - * @covers Pods::valid - * @covers Pods::exists - * @covers Pods::field - * @covers Pods::id - * @covers PodsData::query - * - * @dataProvider data_provider - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_field_traversal( $variant_id, $options ) { - - $this->_test_field_traversal( $variant_id, $options, 'field', false ); - - } - - /** - * @group traversal - * @group traversal-field - * @group traversal-deep - * @group traversal-field-deep - * - * @covers Pods::valid - * @covers Pods::exists - * @covers Pods::field - * @covers Pods::id - * @covers PodsData::query - * - * @dataProvider data_provider_deep - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_field_deep_traversal( $variant_id, $options ) { - - $this->_test_field_traversal( $variant_id, $options, 'field', true ); - - } - - /** - * @group traversal - * @group traversal-display - * @group traversal-shallow - * @group traversal-display-shallow - * - * @covers Pods::valid - * @covers Pods::exists - * @covers Pods::field - * @covers Pods::display - * @covers Pods::id - * @covers PodsData::query - * - * @dataProvider data_provider - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_display_traversal( $variant_id, $options ) { - - $this->_test_field_traversal( $variant_id, $options, 'display', false ); - - } - - /** - * @group traversal - * @group traversal-display - * @group traversal-deep - * @group traversal-display-deep - * - * @covers Pods::valid - * @covers Pods::exists - * @covers Pods::field - * @covers Pods::display - * @covers Pods::id - * @covers PodsData::query - * - * @dataProvider data_provider_deep - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - */ - public function test_display_deep_traversal( $variant_id, $options ) { - - $this->_test_field_traversal( $variant_id, $options, 'display', true ); - - } - - /** - * Data provider for all data to pass into Traversal test methods - * for all variations and combinations to be covered. - */ - public function data_provider_base() { - - $data_base = array(); - - foreach ( self::$builds as $pod_type => $objects ) { - foreach ( $objects as $object => $storage_types ) { - foreach ( $storage_types as $storage_type => $pod ) { - $pod_name = $pod['name']; - - $data_base[] = array( - build_query( compact( array( 'pod_type', 'storage_type', 'pod_name' ) ) ), - array( - 'pod_type' => $pod_type, - 'storage_type' => $storage_type, - 'pod' => $pod, - ), - ); - } - } - } - - return $data_base; - - } - - /** - * Data provider for all data to pass into Traversal test methods - * for all variations and combinations to be covered. - */ - public function data_provider() { - - $data = array(); - - $api = pods_api(); - - foreach ( self::$builds as $pod_type => $objects ) { - foreach ( $objects as $object => $storage_types ) { - foreach ( $storage_types as $storage_type => $pod ) { - $pod['object_fields'] = $api->get_wp_object_fields( $pod_type, $pod ); - - foreach ( $pod['fields'] as $field_name => $field ) { - if ( in_array( - $field['type'], array( - 'pick', - 'taxonomy', - 'avatar', - 'author', - ) - ) && empty( $field['pick_val'] ) ) { - if ( empty( $field['pick_object'] ) ) { - continue; - } - - $field['pick_val'] = $field['pick_object']; - } - - $pod_name = $pod['name']; - $field_name = $field['name']; - - $data[] = array( - build_query( compact( array( 'pod_type', 'storage_type', 'pod_name', 'field_name' ) ) ), - array( - 'pod_type' => $pod_type, - 'storage_type' => $storage_type, - 'pod' => $pod, - 'field' => $field, - ), - ); - }//end foreach - - // Non-Pod Taxonomy field - if ( 'post_type' === $pod_type ) { - $field = $pod['object_fields']['test_non_pod_ct']; - - $pod_name = $pod['name']; - $field_name = $field['name']; - - $data[] = array( - build_query( compact( array( 'pod_type', 'storage_type', 'pod_name', 'field_name' ) ) ), - array( - 'pod_type' => $pod_type, - 'storage_type' => $storage_type, - 'pod' => $pod, - 'field' => $field, - ), - ); - } - }//end foreach - }//end foreach - }//end foreach - - return $data; - - } - - /** - * Data provider for all data to pass into Traversal test methods - * for all variations and combinations to be covered. - */ - public function data_provider_deep() { - - $data_deep = array(); - - foreach ( self::$builds as $pod_type => $objects ) { - foreach ( $objects as $object => $storage_types ) { - foreach ( $storage_types as $storage_type => $pod ) { - foreach ( $pod['fields'] as $field_name => $field ) { - if ( ! in_array( $field['type'], array( 'pick', 'taxonomy', 'avatar', 'author' ) ) ) { - continue; - } - - if ( empty( $field['pick_val'] ) ) { - if ( empty( $field['pick_object'] ) ) { - continue; - } - - $field['pick_val'] = $field['pick_object']; - } - - // Related pod traversal - if ( isset( self::$builds[ $field['pick_object'] ] ) && isset( self::$builds[ $field['pick_object'] ][ $field['pick_val'] ] ) && isset( self::$related_items[ $field['pick_val'] ] ) ) { - $related_pod = current( self::$builds[ $field['pick_object'] ][ $field['pick_val'] ] ); - - foreach ( $related_pod['fields'] as $related_pod_field ) { - if ( empty( $related_pod_field['pick_val'] ) && ! empty( $related_pod_field['pick_object'] ) ) { - $related_pod_field['pick_val'] = $related_pod_field['pick_object']; - } - - $pod_name = $pod['name']; - $field_name = $field['name']; - $related_pod_name = $related_pod['name']; - $related_pod_field_name = $related_pod_field['name']; - - $data_deep[] = array( - build_query( - compact( - array( - 'pod_type', - 'storage_type', - 'pod_name', - 'field_name', - 'related_pod_name', - 'related_pod_field_name', - ) - ) - ), - array( - 'pod_type' => $pod_type, - 'storage_type' => $storage_type, - 'pod' => $pod, - 'field' => $field, - 'related_pod' => $related_pod, - 'related_pod_field' => $related_pod_field, - ), - ); - - continue; - // To be continued.. - // @todo Handle one more level deeper - if ( ! in_array( - $related_pod_field['type'], array( - 'pick', - 'taxonomy', - 'avatar', - 'author', - ) - ) ) { - continue; - } - - if ( empty( $related_pod_field['pick_val'] ) ) { - if ( empty( $related_pod_field['pick_object'] ) ) { - continue; - } - - $related_pod_field['pick_val'] = $related_pod_field['pick_object']; - } - - // Related pod traversal - if ( isset( self::$builds[ $related_pod_field['pick_object'] ] ) && isset( self::$builds[ $related_pod_field['pick_object'] ][ $related_pod_field['pick_val'] ] ) && isset( self::$related_items[ $related_pod_field['pick_val'] ] ) ) { - $sub_related_pod = current( self::$builds[ $related_pod_field['pick_object'] ][ $related_pod_field['pick_val'] ] ); - - foreach ( $sub_related_pod['fields'] as $sub_related_pod_field ) { - if ( empty( $sub_related_pod_field['pick_val'] ) ) { - if ( empty( $sub_related_pod_field['pick_object'] ) ) { - continue; - } - - $sub_related_pod_field['pick_val'] = $sub_related_pod_field['pick_object']; - } - - $sub_related_pod_name = $sub_related_pod['name']; - $sub_related_pod_field_name = $sub_related_pod_field['name']; - - $data_deep[] = array( - build_query( - compact( - array( - 'pod_type', - 'storage_type', - 'pod_name', - 'field_name', - 'related_pod_name', - 'related_pod_field_name', - 'sub_related_pod_name', - 'sub_related_pod_field_name', - ) - ) - ), - array( - 'pod_type' => $pod_type, - 'storage_type' => $storage_type, - 'pod' => $pod, - 'field' => $field, - 'related_pod' => $related_pod, - 'related_pod_field' => $related_pod_field, - 'sub_related_pod' => $sub_related_pod, - 'sub_related_pod_field' => $sub_related_pod_field, - ), - ); - }//end foreach - }//end if - }//end foreach - }//end if - }//end foreach - }//end foreach - }//end foreach - }//end foreach - - return $data_deep; - - } - - /** - * - * Handle all find() base tests based on variations - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - * @param boolean $query_fields Whether to test query_fields WHERE syntax - */ - private function _test_find_base( $variant_id, $options, $query_fields = false ) { - - // Suppress MySQL errors - add_filter( 'pods_error_die', '__return_false' ); - - // global $wpdb; - // $wpdb->suppress_errors( true ); - // $wpdb->hide_errors(); - // Options - $pod_type = $options['pod_type']; - $storage_type = $options['storage_type']; - $pod = $options['pod']; - - // Do setup for Pod (tearDown / setUp) per storage type - if ( in_array( $pod_type, array( 'user', 'media', 'comment' ) ) && 'meta' !== $storage_type ) { - return; - - // @todo do magic - $this->assertTrue( false, sprintf( 'Pod / Storage type requires new setUp() not yet built to continue [%s]', $variant_id ) ); - } - - // Base find() $params - $params = array( - 'limit' => 1, - ); - - $p = pods( $pod['name'] ); - - $this->assertTrue( is_object( $p ), sprintf( 'Pod not object [%s]', $variant_id ) ); - $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); - $this->assertInstanceOf( 'Pods', $p, sprintf( 'Pod object not a Pod [%s]', $variant_id ) ); - - $where = array(); - - $data = self::$related_items[ $pod['name'] ]; - $data['field_id'] = $p->pod_data['field_id']; - $data['field_index'] = $p->pod_data['field_index']; - - $prefix = '`t`.'; - - $check_value = $data['id']; - $check_index = $data['data'][ $data['field_index'] ]; - - if ( $query_fields ) { - $where[] = array( - 'field' => $data['field_id'], - 'value' => (int) $check_value, - ); - - $where[] = array( - 'field' => $data['field_index'], - 'value' => $check_index, - ); - } else { - $where[] = $prefix . '`' . $data['field_id'] . '`' . ' = ' . (int) $check_value; - $where[] = $prefix . '`' . $data['field_index'] . '` = "' . pods_sanitize( $check_index ) . '"'; - - $where = implode( ' AND ', $where ); - } - - $params['where'] = $where; - - $p->find( $params ); - - $this->assertEquals( 1, $p->total(), sprintf( 'Total not correct [%s] | %s | %s', $variant_id, $p->sql, print_r( array( 'where' => $where, 'params' => $p->params ), true ) ) ); - $this->assertEquals( 1, $p->total_found(), sprintf( 'Total found not correct [%s] | %s | %s', $variant_id, $p->sql, print_r( array( 'where' => $where, 'params' => $p->params ), true ) ) ); - - $this->assertNotEmpty( $p->fetch(), sprintf( 'Item not fetched [%s]', $variant_id ) ); - - $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['field_id'], $variant_id ) ); - - } - - /** - * Handle all find() tests based on variations - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - * @param boolean $deep Whether to test deep traversal - * @param boolean $query_fields Whether to test query_fields WHERE syntax - */ - private function _test_find_traversal( $variant_id, $options, $deep = false, $query_fields = false ) { - - // Suppress MySQL errors - add_filter( 'pods_error_die', '__return_false' ); - - global $wpdb; - // $wpdb->suppress_errors( true ); - // $wpdb->hide_errors(); - // Options - $pod_type = $options['pod_type']; - $storage_type = $options['storage_type']; - $pod = $options['pod']; - $field = $options['field']; - $field_name = $field['name']; - $field_type = $field['type']; - $related_pod = array(); - $related_pod_field = array(); - - if ( 'taxonomy' === $pod_type && 'none' === $storage_type && function_exists( 'get_term_meta' ) ) { - $storage_type = 'meta'; - } - - if ( $deep ) { - $related_pod = $options['related_pod']; - $related_pod_field = $options['related_pod_field']; - } - - // Do setup for Pod (tearDown / setUp) per storage type - if ( in_array( $pod_type, array( 'user', 'media', 'comment' ) ) && 'meta' !== $storage_type ) { - return; - - // @todo do magic - $this->assertTrue( false, sprintf( 'Pod / Storage type requires new setUp() not yet built to continue [%s]', $variant_id ) ); - } - - // Base find() $params - $params = array( - 'limit' => 1, - ); - - $p = pods( $pod['name'] ); - - $this->assertTrue( is_object( $p ), sprintf( 'Pod not object [%s]', $variant_id ) ); - $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); - $this->assertInstanceOf( 'Pods', $p, sprintf( 'Pod object not a Pod [%s]', $variant_id ) ); - - $where = array(); - - $data = self::$related_items[ $pod['name'] ]; - $data['field_id'] = $p->pod_data['field_id']; - $data['field_index'] = $p->pod_data['field_index']; - - $podsrel_pod_id = $pod['id']; - $podsrel_field_id = $field['id']; - $podsrel_item_id = $data['id']; - - $prefix = ''; - $suffix = ''; - - if ( in_array( $field_type, array( 'pick', 'taxonomy', 'avatar', 'author' ) ) ) { - if ( ! isset( self::$related_items[ $field_name ] ) ) { - $this->assertTrue( false, sprintf( 'No related item found [%s]', $variant_id ) ); - - return; - } - - $related_data = self::$related_items[ $field_name ]; - - $podsrel_item_id = $related_data['id']; - - $prefix = '`' . $field_name . '`.'; - - if ( ! $deep ) { - $check_value = $related_data['id']; - $check_index = $related_data['data'][ $related_data['field_index'] ]; - - $check_multi_value = (array) $check_value; - $check_multi_index = (array) $check_index; - - if ( ! empty( $field[ $field_type . '_format_type' ] ) && 'multi' === $field[ $field_type . '_format_type' ] ) { - // Only go and get it if you need it - if ( $query_fields ) { - $check_multi_value = (array) array_keys( $related_data['sub_data'] ); - $check_multi_index = (array) wp_list_pluck( $related_data['sub_data'], $related_data['field_index'] ); - } - - $check_value = current( $check_multi_value ); - $check_index = current( $check_multi_index ); - } - - $related_where = array(); - - if ( empty( $check_value ) ) { - if ( $query_fields ) { - $related_where[] = array( - 'field' => $field_name . '.' . $related_data['field_id'], - 'compare' => 'NOT EXISTS', - ); - } else { - $related_where[] = $prefix . '`' . $related_data['field_id'] . '` IS NULL'; - } - } - - if ( $query_fields ) { - $related_where_set = array(); - - // Test IN / ALL (ALL uses IN logic in part of it) - if ( 1 < count( $check_multi_value ) ) { - $related_where_set[] = array( - 'field' => $field_name . '.' . $related_data['field_id'], - 'value' => $check_multi_value, - 'compare' => 'ALL', - ); - - $related_where_set[] = array( - 'field' => $field_name . '.' . $related_data['field_index'], - 'value' => $check_multi_index, - 'compare' => 'ALL', - ); - } else { - $related_where_set[] = array( - 'field' => $field_name . '.' . $related_data['field_id'], - 'value' => (int) $check_value, - ); - - $related_where_set[] = array( - 'field' => $field_name . '.' . $related_data['field_index'], - 'value' => $check_index, - ); - }//end if - - $related_where_set['relation'] = 'AND'; - - $related_where[] = $related_where_set; - - $related_where['relation'] = 'OR'; - } else { - $related_where[] = $prefix . '`' . $related_data['field_id'] . '` = ' . (int) $check_value . ' AND ' . $prefix . '`' . $related_data['field_index'] . '` = "' . pods_sanitize( $check_index ) . '"'; - - $related_where = '( ' . implode( ' OR ', $related_where ) . ' )'; - }//end if - - $where[] = $related_where; - - // var_dump( array( 1, $related_where, $check_value, $check_index ) ); - } else { - // Related pod traversal - $related_pod_type = $related_pod['type']; - $related_pod_storage_type = $related_pod['storage']; - - if ( 'taxonomy' === $related_pod_type && 'none' === $related_pod_storage_type && function_exists( 'get_term_meta' ) ) { - $related_pod_storage_type = 'meta'; - } - - $related_prefix = ''; - $related_suffix = ''; - - $related_where = array(); - - if ( in_array( $related_pod_field['type'], array( 'pick', 'taxonomy', 'avatar', 'author' ) ) ) { - if ( $field_name == $related_pod_field['name'] && ! isset( $related_data['data'][ $related_pod_field['name'] ] ) ) { - $this->assertTrue( false, sprintf( 'No deep related item found [%s] | %s', $variant_id, print_r( $related_data['data'], true ) ) ); - - return; - } - - $related_object = $related_pod_field['name']; - - if ( ! empty( $related_pod_field['pick_val'] ) ) { - $related_object = $related_pod_field['pick_val']; - } - - $related_prefix = '`' . $related_pod_field['name'] . '`.'; - - if ( isset( self::$related_items[ $related_pod_field['name'] ] ) ) { - $related_pod_data = self::$related_items[ $related_pod_field['name'] ]; - } elseif ( isset( self::$related_items[ $related_object ] ) ) { - $related_pod_data = self::$related_items[ $related_object ]; - } else { - // var_dump( array( 2, '$related_pod_field[ \'name\' ]' => $related_pod_field[ 'name' ], '$related_object' => $related_object ) ); - $this->assertTrue( false, sprintf( 'Invalid deep related item [%s]', $variant_id ) ); - - return; - } - - $podsrel_pod_id = $related_pod['id']; - $podsrel_field_id = $related_pod_field['id']; - $podsrel_item_id = $related_pod_data['id']; - - $check_value = $related_pod_data['id']; - - $check_index = ''; - - if ( isset( $related_pod_data['data'][ $related_pod_data['field_index'] ] ) ) { - $check_index = $related_pod_data['data'][ $related_pod_data['field_index'] ]; - } - - if ( ! empty( $related_pod_field[ $related_pod_field['type'] . '_format_type' ] ) && 'multi' === $related_pod_field[ $related_pod_field['type'] . '_format_type' ] ) { - $check_value = (array) $check_value; - $check_value = current( $check_value ); - } - - // Temporarily check against null too, recursive data not saved fully yet - if ( empty( $check_value ) ) { - if ( $query_fields ) { - $related_where[] = array( - 'field' => $field_name . '.' . $related_pod_field['name'] . '.' . $related_pod_data['field_id'], - 'compare' => 'NOT EXISTS', - ); - } else { - $related_where[] = $prefix . $related_prefix . '`' . $related_pod_data['field_id'] . '` IS NULL'; - } - - // var_dump( array( 3, $related_where, 'empty $check_value' ) ); - } - - if ( $query_fields ) { - $related_where[] = array( - 'relation' => 'AND', - array( - 'field' => $field_name . '.' . $related_pod_field['name'] . '.' . $related_pod_data['field_id'], - 'value' => (int) $check_value, - ), - array( - 'field' => $field_name . '.' . $related_pod_field['name'] . '.' . $related_pod_data['field_index'], - 'value' => $check_index, - ), - ); - - $related_where['relation'] = 'OR'; - } else { - $related_where[] = $prefix . $related_prefix . '`' . $related_pod_data['field_id'] . '` = ' . (int) $check_value . ' AND ' . $prefix . $related_prefix . '`' . $related_pod_data['field_index'] . '` = "' . pods_sanitize( $check_index ) . '"'; - - $related_where = '( ' . implode( ' OR ', $related_where ) . ' )'; - } - - // var_dump( array( 4, $related_where, $check_value, $check_index ) ); - } elseif ( 'none' !== $related_pod_storage_type ) { - if ( 'pod' === $related_pod_type ) { - // $related_prefix = '`t`.'; - } elseif ( 'table' === $related_pod_storage_type ) { - $related_prefix = '`d`.'; - } elseif ( 'meta' === $related_pod_storage_type ) { - $related_suffix = '.`meta_value`'; - } - - $check_related_value = ''; - - if ( isset( $related_data['data'][ $related_pod_field['name'] ] ) ) { - $check_related_value = $related_data['data'][ $related_pod_field['name'] ]; - } - - // Temporarily check against null too, recursive data not saved fully yet - if ( '.`meta_value`' === $related_suffix && '' === $check_related_value ) { - if ( $query_fields ) { - $related_where[] = array( - 'field' => $field_name . '.' . $related_pod_field['name'], - 'compare' => 'NOT EXISTS', - ); - } else { - $related_where[] = $prefix . $related_prefix . '`' . $related_pod_field['name'] . '`' . $related_suffix . ' IS NULL'; - } - } - - if ( $query_fields ) { - $related_where[] = array( - 'field' => $field_name . '.' . $related_pod_field['name'], - 'value' => $check_related_value, - ); - - $related_where['relation'] = 'OR'; - } else { - $related_where[] = $prefix . $related_prefix . '`' . $related_pod_field['name'] . '`' . $related_suffix . ' = "' . pods_sanitize( $check_related_value ) . '"'; - - $related_where = '( ' . implode( ' OR ', $related_where ) . ' )'; - } - - // var_dump( array( 5, $related_where, $related_suffix, $check_related_value, self::$related_items[ $field_name ] ) ); - }//end if - - if ( ! empty( $related_where ) ) { - $where[] = $related_where; - } - - // var_dump( array( 6, $where ) ); - }//end if - } elseif ( 'none' !== $storage_type && $field_name != $data['field_index'] ) { - if ( 'pod' === $pod_type ) { - $prefix = '`t`.'; - } elseif ( 'table' === $storage_type ) { - $prefix = '`d`.'; - } elseif ( 'meta' === $storage_type ) { - $suffix = '.`meta_value`'; - } - - $check_value = $data['data'][ $field_name ]; - - if ( $query_fields ) { - $where[] = array( - 'field' => $field_name, - 'value' => $check_value, - ); - } else { - $where[] = $prefix . '`' . $field_name . '`' . $suffix . ' = "' . pods_sanitize( $check_value ) . '"'; - } - }//end if - - $prefix = '`t`.'; - - $check_value = $data['id']; - - if ( $query_fields ) { - $where[] = array( - 'field' => $data['field_id'], - 'value' => (int) $check_value, - ); - } else { - $where[] = $prefix . '`' . $data['field_id'] . '`' . ' = ' . (int) $check_value; - - $where = implode( ' AND ', $where ); - } - - $params['where'] = $where; - - $p->find( $params ); - - $debug_related = count( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}podsrel` WHERE `item_id` = %d AND `pod_id` = %d AND `field_id` = %d", $check_value, $pod['id'], $field['id'] ) ) ) . ' related items'; - - if ( $deep ) { - $prepare_data = (array) $podsrel_item_id; - $prepare_data[] = $podsrel_pod_id; - $prepare_data[] = $podsrel_field_id; - - $debug_related .= ' | ' . count( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}podsrel` WHERE `item_id` IN ( " . implode( ',', array_fill( 0, count( (array) $podsrel_item_id ), '%d' ) ) . ' ) AND `pod_id` = %d AND `field_id` = %d', $prepare_data ) ) ) . ' deep related items'; - } - - $debug = sprintf( '%s | %s | %s', $p->sql, print_r( array( 'where' => $where, 'params' => $p->params ), true ), $debug_related ); - - $this->assertEquals( 1, $p->total(), sprintf( 'Total not correct [%s] | %s', $variant_id, $debug ) ); - $this->assertEquals( 1, $p->total_found(), sprintf( 'Total found not correct [%s] | %s', $variant_id, $debug ) ); - - $this->assertNotEmpty( $p->fetch(), sprintf( 'Item not fetched [%s]', $variant_id ) ); - - $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['field_id'], $variant_id ) ); - - } - - /** - * Handle all field() and display() tests based on variations - * - * @param string $variant_id Testing variant identification - * @param array $options Data config to test - * @param string $method Method to test - * @param boolean $deep Whether to test deep traversal - */ - private function _test_field_traversal( $variant_id, $options, $method, $deep ) { - - // Suppress MySQL errors - add_filter( 'pods_error_die', '__return_false' ); - - // global $wpdb; - // $wpdb->suppress_errors( true ); - // $wpdb->hide_errors(); - // Options - $pod_type = $options['pod_type']; - $storage_type = $options['storage_type']; - $pod = $options['pod']; - - if ( 'taxonomy' === $pod_type && 'none' === $storage_type && function_exists( 'get_term_meta' ) ) { - $storage_type = 'meta'; - } - - $field = $options['field']; - $field_type = $field['type']; - - $related_pod = array(); - $related_pod_field = array(); - - if ( $deep ) { - $related_pod = $options['related_pod']; - $related_pod_type = $related_pod['type']; - $related_pod_storage_type = $related_pod['storage']; - $related_pod_field = $options['related_pod_field']; - - if ( 'taxonomy' === $related_pod_type && 'none' === $related_pod_storage_type && function_exists( 'get_term_meta' ) ) { - $related_pod_storage_type = 'meta'; - } - } - - // Do setup for Pod (tearDown / setUp) per storage type - if ( in_array( $pod_type, array( 'user', 'media', 'comment' ) ) && 'meta' !== $storage_type ) { - return; - - // @todo do magic - $this->assertTrue( false, sprintf( 'Pod / Storage type requires new setUp() not yet built to continue [%s]', $variant_id ) ); - } - - $data = self::$related_items[ $pod['name'] ]; - - $data['id'] = (int) $data['id']; - - $p = pods( $pod['name'], $data['id'] ); - - $data['field_id'] = $p->pod_data['field_id']; - $data['field_index'] = $p->pod_data['field_index']; - - $this->assertTrue( is_object( $p ), sprintf( 'Pod not object [%s]', $variant_id ) ); - $this->assertTrue( $p->valid(), sprintf( 'Pod object not valid [%s]', $variant_id ) ); - $this->assertInstanceOf( 'Pods', $p, sprintf( 'Pod object not a Pod [%s]', $variant_id ) ); - - $this->assertTrue( $p->exists(), sprintf( 'Pod item not found [%s]', $variant_id ) ); - - $this->assertEquals( (string) $data['id'], (string) $p->id(), sprintf( 'Item ID not as expected (%s) [%s]', $data['field_id'], $variant_id ) ); - - if ( 'post_type' === $pod_type || 'media' === $pod_type ) { - $metadata_type = 'post'; - } elseif ( 'taxonomy' === $pod_type ) { - $metadata_type = 'term'; - } else { - $metadata_type = $pod_type; - } - - // @todo other field type coverage for relational - if ( in_array( $field_type, array( 'pick', 'taxonomy' ) ) ) { - if ( ! isset( self::$related_items[ $field['name'] ] ) ) { - $this->assertTrue( false, sprintf( 'No related item found [%s]', $variant_id ) ); - - return; - } - - $related_data = self::$related_items[ $field['name'] ]; - - $check_value = $related_data['id']; - $check_index = $related_data['data'][ $related_data['field_index'] ]; - - $check_display_value = $check_value; - $check_display_index = $check_index; - - $field_data = array(); - - if ( isset( $pod['fields'][ $field['name'] ] ) ) { - $field_data = $pod['fields'][ $field['name'] ]; - } elseif ( isset( $pod['object_fields'][ $field['name'] ] ) ) { - $field_data = $pod['object_fields'][ $field['name'] ]; - } elseif ( ! empty( $field ) ) { - $field_data = $field; - } else { - $this->assertTrue( false, sprintf( 'No related field data found [%s]', $variant_id ) ); - - return; - } - - if ( ! is_object( $field_data ) && ! empty( $field_data['options'] ) ) { - $field_data = array_merge( $field_data['options'], $field_data ); - } - - if ( ! empty( $field_data[ $field_type . '_format_type' ] ) && 'multi' === $field_data[ $field_type . '_format_type' ] ) { - $check_value = (array) $check_value; - - if ( ! empty( $related_data['limit'] ) ) { - $check_indexes = array(); - - $check_indexes[] = $check_index; - - for ( $x = 1; $x < $related_data['limit']; $x ++ ) { - $check_indexes[] = $check_index . ' (' . $x . ')'; - } - - $check_index = $check_indexes; - } else { - $check_index = (array) $check_index; - } - - $check_display_value = pods_serial_comma( $check_value ); - $check_display_index = pods_serial_comma( $check_index ); - } - - $prefix = $field['name'] . '.'; - $traverse_id = $prefix . $related_data['field_id']; - $traverse_index = $prefix . $related_data['field_index']; - - /* - if ( false === $p->field( $traverse_id ) ) { - var_dump( array( - 'pod' => $pod[ 'name' ], - 'storage' => $storage_type, - 'traverse_id' => $traverse_id, - 'check_value' => $check_value, - 'field_value' => $p->field( $traverse_id ), - 'check_display_value' => $check_display_value, - 'display_value' => $p->display( $traverse_id ), - 'check_index' => $check_index, - 'field_index' => $p->field( $traverse_index ), - 'check_display_index' => $check_display_index, - 'display_index' => $p->display( $traverse_index ), - 'field_full' => $p->field( $field[ 'name' ] ), - //'field_data' => $p->fields( $field[ 'name' ] ) - ) ); - }*/ - - if ( ! $deep ) { - if ( 'field' === $method ) { - $this->assertEquals( $check_value, $p->field( $traverse_id ), sprintf( 'Related Item field value not as expected (%s) [%s] {%s should be %s}', $traverse_id, $variant_id, var_export( $p->field( $traverse_id ), true ), var_export( $check_value, true ) ) ); - $this->assertEquals( $check_index, $p->field( $traverse_index ), sprintf( 'Related Item index field value not as expected (%s) [%s] {%s should be %s}', $traverse_index, $variant_id, var_export( $p->field( $traverse_index ), true ), var_export( $check_index, true ) ) ); - - if ( 'meta' === $storage_type && 'taxonomy' !== $field_type ) { - $check_value = array_map( 'absint', (array) $check_value ); - $check_index = (array) $check_index; - - /* - var_dump( array( - 'check_array' => $check_value, - 'metadata_array' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $traverse_id ) ), - - 'check_single' => current( $check_value ), - 'metadata_single' => (int) get_metadata( $metadata_type, $data[ 'id' ], $traverse_id, true ), - - 'check_index_array' => $check_index, - 'metadata_index_array' => get_metadata( $metadata_type, $data[ 'id' ], $traverse_index ), - - 'check_index_single' => current( $check_index ), - 'metadata_index_single' => get_metadata( $metadata_type, $data[ 'id' ], $traverse_index, true ), - - 'metadata_full' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $field[ 'name' ] ) ) - ) );*/ - - $this->assertEquals( $check_value, array_map( 'absint', get_metadata( $metadata_type, $data['id'], $traverse_id ) ), sprintf( 'Related Item field meta value not as expected (%s) [%s]', $traverse_id, $variant_id ) ); - $this->assertEquals( current( $check_value ), (int) get_metadata( $metadata_type, $data['id'], $traverse_id, true ), sprintf( 'Related Item field single meta value not as expected (%s) [%s]', $traverse_id, $variant_id ) ); - - $this->assertEquals( $check_index, get_metadata( $metadata_type, $data['id'], $traverse_index ), sprintf( 'Related Item index field meta value not as expected (%s) [%s]', $traverse_index, $variant_id ) ); - $this->assertEquals( current( $check_index ), get_metadata( $metadata_type, $data['id'], $traverse_index, true ), sprintf( 'Related Item index field single meta value not as expected (%s) [%s]', $traverse_index, $variant_id ) ); - }//end if - } elseif ( 'display' === $method ) { - $this->assertEquals( $check_display_value, $p->display( $traverse_id ), sprintf( 'Related Item field display value not as expected (%s) [%s]', $traverse_id, $variant_id ) ); - $this->assertEquals( $check_display_index, $p->display( $traverse_index ), sprintf( 'Related Item index field display value not as expected (%s) [%s]', $traverse_index, $variant_id ) ); - }//end if - } else { - // Related pod traversal - if ( in_array( $related_pod_field['type'], array( 'pick', 'taxonomy', 'avatar', 'author' ) ) ) { - if ( $field['name'] == $related_pod_field['name'] && ! isset( $related_data['data'][ $related_pod_field['name'] ] ) ) { - $this->assertTrue( false, sprintf( 'No deep related item found [%s] | %s', $variant_id, print_r( $related_data['data'], true ) ) ); - - return; - } - - $related_object = $related_pod_field['name']; - - if ( ! empty( $related_pod_field['pick_val'] ) ) { - $related_object = $related_pod_field['pick_val']; - } - - if ( isset( self::$related_items[ $related_pod_field['name'] ] ) ) { - $related_pod_data = self::$related_items[ $related_pod_field['name'] ]; - } elseif ( isset( self::$related_items[ $related_object ] ) ) { - $related_pod_data = self::$related_items[ $related_object ]; - } else { - // var_dump( array( 7, '$related_pod_field[ \'name\' ]' => $related_pod_field[ 'name' ], '$related_object' => $related_object ) ); - $this->assertTrue( false, sprintf( 'Invalid related item [%s]', $variant_id ) ); - - return; - } - - $related_prefix = $related_pod_field['name'] . '.'; - $related_traverse_id = $prefix . $related_prefix . $related_pod_data['field_id']; - $related_traverse_index = $prefix . $related_prefix . $related_pod_data['field_index']; - - $check_value = $related_pod_data['id']; - - $check_index = ''; - - if ( isset( $related_pod_data['data'][ $related_pod_data['field_index'] ] ) ) { - $check_index = $related_pod_data['data'][ $related_pod_data['field_index'] ]; - } - - $check_display_value = $check_value; - $check_display_index = $check_index; - - if ( ! empty( $related_pod['fields'][ $related_pod_field['name'] ][ $related_pod_field['type'] . '_format_type' ] ) && 'multi' === $related_pod['fields'][ $related_pod_field['name'] ][ $related_pod_field['type'] . '_format_type' ] ) { - $check_value = (array) $check_value; - - $check_indexes = array(); - - $check_indexes[] = $check_index; - - for ( $x = 1; $x < $related_pod_data['limit']; $x ++ ) { - $check_indexes[] = $check_index . ' (' . $x . ')'; - } - - $check_index = $check_indexes; - - $check_display_value = pods_serial_comma( $check_value ); - $check_display_index = pods_serial_comma( $check_index ); - } - - if ( 'field' === $method ) { - $this->assertEquals( - $check_value, $p->field( $related_traverse_id, ! is_array( $check_value ) ), sprintf( - 'Deep Related Item field value not as expected (%s) [%s] | %s', $related_traverse_id, $variant_id, var_export( - array( - '$check_value' => $check_value, - '$p->field( $related_traverse_id, true )' => $p->field( $related_traverse_id, ! is_array( $check_value ) ), - ), true - ) - ) - ); - $this->assertEquals( - $check_index, $p->field( $related_traverse_index, ! is_array( $check_index ) ), sprintf( - 'Deep Related Item index field value not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( - array( - '$check_index' => $check_index, - '$p->field( $related_traverse_index, true )' => $p->field( $related_traverse_index, ! is_array( $check_value ) ), - ), true - ) - ) - ); - - if ( 'meta' === $storage_type && 'taxonomy' !== $related_pod_field['type'] ) { - $check_value = array_map( 'absint', (array) $check_value ); - $check_index = (array) $check_index; - - /* - var_dump( array( - 'check_array' => $check_value, - 'metadata_array' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_id ) ), - - 'check_single' => current( $check_value ), - 'metadata_single' => (int) get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_id, true ), - - 'check_index_array' => $check_index, - 'metadata_index_array' => get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_index ), - - 'check_index_single' => current( $check_index ), - 'metadata_index_single' => get_metadata( $metadata_type, $data[ 'id' ], $related_traverse_index, true ), - - 'metadata_full' => array_map( 'absint', get_metadata( $metadata_type, $data[ 'id' ], $prefix . $related_pod_field[ 'name' ] ) ) - ) );*/ - - $this->assertEquals( $check_value, array_map( 'absint', get_metadata( $metadata_type, $data['id'], $related_traverse_id ) ), sprintf( 'Deep Related Item field meta value not as expected (%s) [%s]', $related_traverse_id, $variant_id ) ); - $this->assertEquals( current( $check_value ), (int) get_metadata( $metadata_type, $data['id'], $related_traverse_id, true ), sprintf( 'Deep Related Item field single meta value not as expected (%s) [%s]', $related_traverse_id, $variant_id ) ); - - $this->assertEquals( $check_index, get_metadata( $metadata_type, $data['id'], $related_traverse_index ), sprintf( 'Deep Related Item index field meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); - $this->assertEquals( current( $check_index ), get_metadata( $metadata_type, $data['id'], $related_traverse_index, true ), sprintf( 'Deep Related Item index field single meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); - }//end if - } elseif ( 'display' === $method ) { - $this->assertEquals( $check_display_value, $p->display( $related_traverse_id ), sprintf( 'Deep Related Item field display value not as expected (%s) [%s]', $related_traverse_id, $variant_id ) ); - $this->assertEquals( $check_display_index, $p->display( $related_traverse_index ), sprintf( 'Deep Related Item index field display value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); - }//end if - } elseif ( 'none' !== $related_pod_storage_type ) { - $check_related_value = ''; - $check_related_value_display = ''; - - if ( isset( $related_data['data'][ $related_pod_field['name'] ] ) ) { - $check_related_value = $related_data['data'][ $related_pod_field['name'] ]; - - $check_related_value_display = $check_related_value; - - if ( is_array( $check_value ) ) { - $check_related_value = array_fill( 0, count( $check_value ), $check_related_value ); - - $check_related_value_display = pods_serial_comma( $check_related_value ); - } - } - - $related_traverse_index = $prefix . $related_pod_field['name']; - - if ( 'field' === $method ) { - $this->assertEquals( - $check_related_value, $p->field( $related_traverse_index, ! is_array( $check_related_value ) ), sprintf( - 'Deep Related Item related field index not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( - array( - '$check_related_value' => $check_related_value, - '$p->field( $related_traverse_index, true )' => $p->field( $related_traverse_index, ! is_array( $check_related_value ) ), - '$related_data' => $related_data, - ), true - ) - ) - ); - - if ( 'meta' === $storage_type && 'taxonomy' !== $related_pod_field['type'] ) { - $check_related_value = (array) $check_related_value; - - $this->assertEquals( $check_related_value, get_metadata( $metadata_type, $data['id'], $related_traverse_index ), sprintf( 'Deep Related Item related field meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); - $this->assertEquals( current( $check_related_value ), get_metadata( $metadata_type, $data['id'], $related_traverse_index, true ), sprintf( 'Deep Related Item related field single meta value not as expected (%s) [%s]', $related_traverse_index, $variant_id ) ); - } - } elseif ( 'display' === $method ) { - $this->assertEquals( - $check_related_value_display, $p->display( $related_traverse_index, ! is_array( $check_related_value ) ), sprintf( - 'Deep Related Item related field display value not as expected (%s) [%s] | %s', $related_traverse_index, $variant_id, var_export( - array( - '$check_related_value' => $check_related_value, - '$p->display( $related_traverse_index, true )' => $p->display( $related_traverse_index, ! is_array( $check_related_value ) ), - '$related_data' => $related_data, - ), true - ) - ) - ); - }//end if - }//end if - }//end if - } elseif ( isset( $data['data'][ $field['name'] ] ) ) { - // Other field assertions - $check_value = $data['data'][ $field['name'] ]; - - if ( 'field' === $method ) { - $this->assertEquals( $check_value, $p->field( $field['name'] ), sprintf( 'Item field value not as expected [%s]', $variant_id ) ); - - if ( 'meta' === $storage_type ) { - $check_value = (array) $check_value; - - $this->assertEquals( $check_value, get_metadata( $metadata_type, $data['id'], $field['name'] ), sprintf( 'Item field meta value not as expected [%s]', $variant_id ) ); - $this->assertEquals( current( $check_value ), get_metadata( $metadata_type, $data['id'], $field['name'], true ), sprintf( 'Item field single meta value not as expected [%s]', $variant_id ) ); - } - } elseif ( 'display' === $method ) { - $this->assertEquals( $check_value, $p->display( $field['name'] ), sprintf( 'Item field display value not as expected [%s]', $variant_id ) ); - } - }//end if - - } - -} diff --git a/tribe-common/README.md b/tribe-common/README.md new file mode 100644 index 0000000000..0eaf4a026e --- /dev/null +++ b/tribe-common/README.md @@ -0,0 +1,2 @@ +# tribe-common +Common classes and functions used in our plugins diff --git a/tribe-common/node_modules/mt-a11y-dialog/a11y-dialog.min.js b/tribe-common/node_modules/mt-a11y-dialog/a11y-dialog.min.js new file mode 100644 index 0000000000..9c37e12966 --- /dev/null +++ b/tribe-common/node_modules/mt-a11y-dialog/a11y-dialog.min.js @@ -0,0 +1 @@ +!function(t){"use strict";function e(t){if(this.options=h({appendTarget:"",bodyLock:!0,closeButtonAriaLabel:"Close this dialog window",closeButtonClasses:"a11y-dialog__close-button",contentClasses:"a11y-dialog__content",effect:"none",effectSpeed:300,effectEasing:"ease-in-out",overlayClasses:"a11y-dialog__overlay",overlayClickCloses:!0,trigger:null,wrapperClasses:"a11y-dialog"},t),this._rendered=!1,this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this.trigger=a(this.options.trigger)?o(this.options.trigger,!0,document,!0):this.options.trigger,this.node=null,!this.trigger)return void console.warn("Lookup for a11y target node failed.");this._listeners={},this.create()}function i(t){var e=[],i=t.length;for(i;i--;e.unshift(t[i]));return e}function o(t,e,o,n){o||(o=document);var s=n?t:'[data-js="'+t+'"]',r=o.querySelectorAll(s);return e&&(r=i(r)),r}function n(t,e){return i((e||document).querySelectorAll(t))}function s(t){var e=d(t);e.length&&e[0].focus()}function r(t,e){e.parentNode.insertBefore(t,e.nextElementSibling)}function d(t){return n(p.join(","),t).filter(function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)})}function a(t){return"[object String]"===Object.prototype.toString.call(t)}function h(t,e){return Object.keys(e).forEach(function(i){t[i]=e[i]}),t}function c(t,e){var i=d(t),o=i.indexOf(document.activeElement);e.shiftKey&&0===o?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||o!==i.length-1||(i[0].focus(),e.preventDefault())}function l(){g=b.scrollTop,document.body.classList.add("a11y-dialog__body-locked"),document.body.style.position="fixed",document.body.style.width="100%",document.body.style.marginTop="-"+g+"px"}function u(){document.body.style.marginTop="",document.body.style.position="",document.body.style.width="",b.scrollTop=g,document.body.classList.remove("a11y-dialog__body-locked")}var f,p=["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","iframe","object","embed","[contenteditable]",'[tabindex]:not([tabindex^="-"])'],y=function(){var t=/(android)/i.test(navigator.userAgent),e=!!window.chrome,i="undefined"!=typeof InstallTrigger,o=document.documentMode,n=!o&&!!window.StyleMedia,s=!!navigator.userAgent.match(/(iPod|iPhone|iPad)/i),r=!!navigator.userAgent.match(/(iPod|iPhone)/i),d=!!window.opera||navigator.userAgent.indexOf(" OPR/")>=0;return{android:t,chrome:e,edge:n,firefox:i,ie:o,ios:s,iosMobile:r,opera:d,safari:Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0||!e&&!d&&"undefined"!==window.webkitAudioContext,os:navigator.platform}}(),g=0,b=y.ie||y.firefox||y.chrome&&!y.edge?document.documentElement:document.body;e.prototype.create=function(){return this.shown=!1,this.trigger.forEach(function(t){t.addEventListener("click",this._show)}.bind(this)),this._fire("create"),this},e.prototype.render=function(t){var e=o(this.trigger[0].dataset.content)[0];if(!e)return this;var i=document.createElement("div");i.setAttribute("aria-hidden","true"),i.classList.add(this.options.wrapperClasses),i.innerHTML='
            \n ";var n=this.trigger;return this.options.appendTarget.length&&(n=document.querySelectorAll(this.options.appendTarget)[0]||this.trigger),r(i,n),this.node=i,this.overlay=o("a11y-overlay",!1,this.node)[0],this.closeButton=o("a11y-close-button",!1,this.node)[0],this.options.overlayClickCloses&&this.overlay.addEventListener("click",this._hide),this.closeButton.addEventListener("click",this._hide),this._rendered=!0,this._fire("render",t),this},e.prototype.show=function(t){return this.shown?this:(this._rendered||this.render(t),this._rendered?(this.shown=!0,this._applyOpenEffect(),this.node.setAttribute("aria-hidden","false"),this.options.bodyLock&&l(),f=document.activeElement,s(this.node),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t),this):this)},e.prototype.hide=function(t){return this.shown?(this.shown=!1,"none"===this.options.effect&&this.node.setAttribute("aria-hidden","true"),this._applyCloseEffect(),this.options.bodyLock&&u(),f&&f.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},e.prototype.destroy=function(){return this.hide(),this.trigger.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._rendered&&(this.options.overlayClickCloses&&this.overlay.removeEventListener("click",this._hide),this.closeButton.removeEventListener("click",this._hide)),this._fire("destroy"),this._listeners={},this},e.prototype.on=function(t,e){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(e),this},e.prototype.off=function(t,e){var i=this._listeners[t].indexOf(e);return i>-1&&this._listeners[t].splice(i,1),this},e.prototype._fire=function(t,e){(this._listeners[t]||[]).forEach(function(t){t(this.node,e)}.bind(this))},e.prototype._bindKeypress=function(t){this.shown&&27===t.which&&(t.preventDefault(),this.hide()),this.shown&&9===t.which&&c(this.node,t)},e.prototype._maintainFocus=function(t){this.shown&&!this.node.contains(t.target)&&s(this.node)},e.prototype._applyOpenEffect=function(){var t=this;setTimeout(function(){t.node.classList.add("a11y-dialog--open")},50),"fade"===this.options.effect&&(this.node.style.opacity="0",this.node.style.transition="opacity "+this.options.effectSpeed+"ms "+this.options.effectEasing,setTimeout(function(){t.node.style.opacity="1"},50))},e.prototype._applyCloseEffect=function(){var t=this;this.node.classList.remove("a11y-dialog--open"),"fade"===this.options.effect?(this.node.style.opacity="0",setTimeout(function(){t.node.style.transition="",t.node.setAttribute("aria-hidden","true")},this.options.effectSpeed)):"css"===this.options.effect&&setTimeout(function(){t.node.setAttribute("aria-hidden","true")},this.options.effectSpeed)},"undefined"!=typeof module&&void 0!==module.exports?module.exports=e:"function"==typeof define&&define.amd?define("A11yDialog",[],function(){return e}):"object"==typeof t&&(t.A11yDialog=e)}("undefined"!=typeof global?global:window); \ No newline at end of file diff --git a/tribe-common/src/Tribe/Abstract_Deactivation.php b/tribe-common/src/Tribe/Abstract_Deactivation.php new file mode 100755 index 0000000000..b32c40f8d4 --- /dev/null +++ b/tribe-common/src/Tribe/Abstract_Deactivation.php @@ -0,0 +1,71 @@ +network = (bool) $network; + } + + /** + * Tell WordPress to flush rewrite rules. + * Since our post types are already registered, + * we delete the option and let WP regenerate it + * on the next page load. + */ + protected function flush_rewrite_rules() { + delete_option( 'rewrite_rules' ); + } + + /** + * Deactivate the plugin. This should not remove data. + * It's job is to remove run-time traces of the plugin. + * + * @return void + */ + public function deactivate() { + if ( is_multisite() && $this->network ) { + $this->multisite_deactivate(); + } else { + $this->blog_deactivate(); + } + } + + /** + * Run the deactivation script on every blog for a multisite install + * + * @return void + */ + protected function multisite_deactivate() { + /** @var wpdb $wpdb */ + global $wpdb; + $site = get_current_site(); + $blog_ids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id=%d", $site->id ) ); + $large = wp_is_large_network(); + foreach ( $blog_ids as $blog ) { + tribe_set_time_limit( 30 ); + switch_to_blog( $blog ); + $large ? $this->short_blog_deactivate() : $this->blog_deactivate(); + restore_current_blog(); + } + } + + /** + * The deactivation routine for a single blog + * + * @return void + */ + abstract protected function blog_deactivate(); + + + /** + * An abridged version that is less DB intensive for use on large networks. + * + * @see wp_is_large_network() and the 'wp_is_large_network' filter + * + * @return void + */ + protected function short_blog_deactivate() { + $this->blog_deactivate(); + } +} diff --git a/tribe-common/src/Tribe/Abstract_Plugin_Register.php b/tribe-common/src/Tribe/Abstract_Plugin_Register.php new file mode 100644 index 0000000000..d6d791aeb5 --- /dev/null +++ b/tribe-common/src/Tribe/Abstract_Plugin_Register.php @@ -0,0 +1,72 @@ + [], + 'co-dependencies' => [], + 'addon-dependencies' => [], + ]; + + /** + * Registers a plugin with dependencies + */ + public function register_plugin() { + tribe_register_plugin( + $this->base_dir, + $this->main_class, + $this->version, + $this->classes_req, + $this->dependencies + ); + } + + /** + * Returns whether or not the dependencies have been met + * + * This is basically an aliased function - register_plugins, upon + * second calling, returns whether or not a plugin should load. + * + * @deprecated since 4.9.17 It is unused by any Tribe plugins and returned void. + * @todo remove in 4.11 + */ + public function has_valid_dependencies() { + _deprecated_function( __METHOD__, '4.9.17' ); + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Admin/Activation_Page.php b/tribe-common/src/Tribe/Admin/Activation_Page.php new file mode 100644 index 0000000000..9d83bfdb6a --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Activation_Page.php @@ -0,0 +1,334 @@ +args = wp_parse_args( $args, [ + 'slug' => '', + 'activation_transient' => '', + 'version' => '', + 'plugin_path' => '', + 'version_history_slug' => '', + 'update_page_title' => '', + 'update_page_template' => '', + 'welcome_page_title' => '', + 'welcome_page_template' => '', + ] ); + + $this->update_slug .= $this->args['slug']; + $this->welcome_slug .= $this->args['slug']; + + $this->hooks(); + } + + /** + * Determines if we are currently on the Welcome page. + * + * @since 4.12.11 + * + * @return bool + */ + public function is_welcome_page() { + return isset( $_GET[ $this->welcome_slug ] ); + } + + /** + * Determines if we are currently on the update page. + * + * @since 4.12.11 + * + * @return bool + */ + public function is_update_page() { + return isset( $_GET[ $this->update_slug ] ); + } + + /** + * Listen for opportunities to show update and welcome splash pages. + */ + public function hooks() { + if ( + tribe_is_truthy( get_option( 'tribe_skip_welcome', false ) ) + || tribe_is_truthy( tribe_get_option( 'skip_welcome', false ) ) + ) { + return; + } + + add_action( 'admin_init', [ $this, 'maybe_redirect' ], 10, 0 ); + add_action( 'admin_menu', [ $this, 'register_page' ], 100, 0 ); // come in after the default page is registered + + add_action( 'update_plugin_complete_actions', [ $this, 'update_complete_actions' ], 15, 2 ); + add_action( 'update_bulk_plugins_complete_actions', [ $this, 'update_complete_actions' ], 15, 2 ); + } + + /** + * Filter the Default WordPress actions when updating the plugin to prevent users to be redirected if they have an + * specific intention of going back to the plugins page. + * + * @param array $actions The Array of links (html) + * @param string $plugin Which plugins are been updated + * @return array The filtered Links + */ + public function update_complete_actions( $actions, $plugin ) { + $plugins = []; + + if ( ! empty( $_GET['plugins'] ) ) { + $plugins = explode( ',', esc_attr( $_GET['plugins'] ) ); + } + + if ( ! in_array( $this->args['plugin_path'], $plugins ) ) { + return $actions; + } + + if ( isset( $actions['plugins_page'] ) ) { + $actions['plugins_page'] = '' . esc_html__( 'Return to Plugins page' ) . ''; + + if ( ! current_user_can( 'activate_plugins' ) ) { + unset( $actions['plugins_page'] ); + } + } + + if ( isset( $actions['updates_page'] ) ) { + $actions['updates_page'] = '' . esc_html__( 'Return to WordPress Updates' ) . ''; + } + + return $actions; + } + + /** + * Maybe redirect to the welcome page (or to the update page - though this is + * currently disabled). + */ + public function maybe_redirect() { + if ( ! empty( $_POST ) ) { + return; // don't interrupt anything the user's trying to do + } + + if ( ! is_admin() || defined( 'DOING_AJAX' ) ) { + return; + } + + if ( defined( 'IFRAME_REQUEST' ) && IFRAME_REQUEST ) { + return; // probably the plugin update/install iframe + } + + if ( isset( $_GET[ $this->welcome_slug ] ) || isset( $_GET[ $this->update_slug ] ) ) { + return; // no infinite redirects + } + + if ( isset( $_GET['tribe-skip-welcome'] ) ) { + return; // a way to skip these checks and + } + + // bail if we aren't activating a plugin + if ( ! get_transient( $this->args['activation_transient'] ) ) { + return; + } + + delete_transient( $this->args['activation_transient'] ); + + if ( ! current_user_can( Tribe__Settings::instance()->requiredCap ) ) { + return; + } + + if ( $this->showed_update_message_for_current_version() ) { + return; + } + + // the redirect might be intercepted by another plugin, but + // we'll go ahead and mark it as viewed right now, just in case + // we end up in a redirect loop + // see #31088 + $this->log_display_of_message_page(); + + if ( $this->is_new_install() ) { + $this->redirect_to_welcome_page(); + } + } + + /** + * Have we shown the welcome/update message for the current version? + * + * @return bool + */ + protected function showed_update_message_for_current_version() { + $message_version_displayed = Tribe__Settings_Manager::get_option( 'last-update-message-' . $this->args['slug'] ); + + if ( empty( $message_version_displayed ) ) { + return false; + } + if ( version_compare( $message_version_displayed, $this->args['version'], '<' ) ) { + return false; + } + return true; + } + + /** + * Records the fact that we displayed the update message in relation to a specific + * version of the plugin (so we don't show it again until/unless they update to + * a higher version). + */ + protected function log_display_of_message_page() { + Tribe__Settings_Manager::set_option( 'last-update-message-' . $this->args['slug'], $this->args['version'] ); + } + + /** + * The previous_ecp_versions option will be empty or set to 0 + * if the current version is the first version to be installed. + * + * @return bool + * @see Tribe__Events__Main::maybeSetTECVersion() + */ + protected function is_new_install() { + $previous_versions = Tribe__Settings_Manager::get_option( $this->args['version_history_slug'] ); + return empty( $previous_versions ) || ( end( $previous_versions ) == '0' ); + } + + /** + * Handles taking a user to a post-installation welcome page. + */ + protected function redirect_to_welcome_page() { + $url = $this->get_message_page_url( $this->welcome_slug ); + wp_safe_redirect( $url ); + exit(); + } + + /** + * Handles taking the user to a post-update splash screen. + * + * Disused since TEC PR 88 (targeting Tribe__Events__Activation_Page, + * which this class was derived from). + * + * @see https://github.com/the-events-calendar/the-events-calendar/pull/88 + * + * @todo decide whether to reinstate or remove + */ + protected function redirect_to_update_page() { + $url = $this->get_message_page_url( $this->update_slug ); + wp_safe_redirect( $url ); + exit(); + } + + /** + * Return the URL of the splash page. + * + * @param string $slug + * + * @return string + */ + protected function get_message_page_url( $slug ) { + $settings = Tribe__Settings::instance(); + // get the base settings page url + $url = apply_filters( + 'tribe_settings_url', + add_query_arg( 'page', $settings->adminSlug, admin_url( 'edit.php' ) ) + ); + $url = esc_url_raw( add_query_arg( $slug, 1, $url ) ); + return $url; + } + + /** + * Dynamically registers the splash page when required. + */ + public function register_page() { + if ( isset( $_GET[ $this->welcome_slug ] ) ) { + $this->current_context = 'welcome'; + } elseif ( isset( $_GET[ $this->update_slug ] ) ) { + $this->current_context = 'update'; + } else { + return; + } + + $this->disable_default_settings_page(); + add_filter( 'admin_body_class', [ $this, 'admin_body_class' ] ); + add_action( Tribe__Settings::instance()->admin_page, [ $this, 'display_page' ] ); + } + + /** + * Hooked to admin_body_class to add a class for the update or welcome page + * + * @param string $classes a space separated string of classes to be added to body + * + * @return string + */ + public function admin_body_class( $classes ) { + $classes .= ' tribe-' . $this->current_context; + return $classes; + } + + /** + * Deactivates the regular settings screen (the splash screen will display + * in the Events > Settings slot instead, for this request only). + */ + protected function disable_default_settings_page() { + remove_action( Tribe__Settings::instance()->admin_page, [ Tribe__Settings::instance(), 'generatePage' ] ); + } + + /** + * Prints the splash screen. + * + * @param string $context + * + * @return string|null + */ + public function display_page() { + if ( empty( $this->args[ $this->current_context . '_page_title' ] ) || empty( $this->args[ $this->current_context . '_page_template'] ) ) { + return null; + } + + do_action( 'tribe_settings_top' ); + + $context = isset( $_GET[ $this->welcome_slug ] ) ? 'welcome': 'update'; + $title = esc_html( $this->args[ $context . '_page_title'] ); + $html = $this->get_view( $this->args[ $context . '_page_template'] ); + + echo " +
            +

            {$title}

            + {$html} +
            + "; + + do_action( 'tribe_settings_bottom' ); + $this->log_display_of_message_page(); + } + + /** + * Returns the output of the specified template. + * + * @param string $path + * + * @return string + */ + protected function get_view( $path ) { + if ( ! file_exists( $path ) ) { + return ''; + } + + ob_start(); + include $path; + return ob_get_clean(); + } +} diff --git a/tribe-common/src/Tribe/Admin/Help_Page.php b/tribe-common/src/Tribe/Admin/Help_Page.php new file mode 100644 index 0000000000..b66b278c01 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Help_Page.php @@ -0,0 +1,916 @@ +is_screen( 'tribe_events_page_tribe-help' ) || Tribe__Admin__Helpers::instance()->is_screen( 'settings_page_tribe-common-help-network' ); + } + + /** + * Register the Admin assets for the help page + * + * @since 4.9.12 + * + * @return void + */ + public function register_assets() { + $plugin = Tribe__Main::instance(); + tribe_asset( + $plugin, + 'tribe-admin-help-page', + 'admin/help-page.js', + [ 'tribe-clipboard', 'tribe-common' ], + 'admin_enqueue_scripts', + [ + 'conditionals' => [ $this, 'is_current_page' ], + 'localize' => [ + 'name' => 'tribe_system_info', + 'data' => [ + 'sysinfo_optin_nonce' => wp_create_nonce( 'sysinfo_optin_nonce' ), + 'clipboard_btn_text' => __( 'Copy to clipboard', 'tribe-common' ), + 'clipboard_copied_text' => __( 'System info copied', 'tribe-common' ), + 'clipboard_fail_text' => __( 'Press "Cmd + C" to copy', 'tribe-common' ), + ], + ], + ] + ); + } + + /** + * Get the list of plugins + * + * @since 4.0 + * + * @param string $plugin_name Should get only one plugin? + * @param boolean $is_active Only get active plugins? + * @return array + */ + public function get_plugins( $plugin_name = null, $is_active = true ) { + $plugins = []; + + $plugins['the-events-calendar'] = [ + 'name' => 'the-events-calendar', + 'title' => esc_html__( 'The Events Calendar', 'tribe-common' ), + 'repo' => 'https://wordpress.org/plugins/the-events-calendar/', + 'forum' => 'https://wordpress.org/support/plugin/the-events-calendar/', + 'stars_url' => 'https://wordpress.org/support/plugin/the-events-calendar/reviews/?filter=5', + 'description' => esc_html__( + 'The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events.', + 'tribe-common' + ), + 'is_active' => false, + 'version' => null, + ]; + + if ( class_exists( 'Tribe__Events__Main' ) ) { + $plugins['the-events-calendar']['version'] = Tribe__Events__Main::VERSION; + $plugins['the-events-calendar']['is_active'] = true; + } + + $plugins['event-tickets'] = [ + 'name' => 'event-tickets', + 'title' => esc_html__( 'Event Tickets', 'tribe-common' ), + 'repo' => 'https://wordpress.org/plugins/event-tickets/', + 'forum' => 'https://wordpress.org/support/plugin/event-tickets', + 'stars_url' => 'https://wordpress.org/support/plugin/event-tickets/reviews/?filter=5', + 'description' => esc_html__( + 'Events Tickets is a carefully crafted, extensible plugin that lets you easily sell tickets for your events.', + 'tribe-common' + ), + 'is_active' => false, + 'version' => null, + ]; + + if ( class_exists( 'Tribe__Tickets__Main' ) ) { + $plugins['event-tickets']['version'] = Tribe__Tickets__Main::VERSION; + $plugins['event-tickets']['is_active'] = true; + } + + $plugins['advanced-post-manager'] = [ + 'name' => 'advanced-post-manager', + 'title' => esc_html__( 'Advanced Post Manager', 'tribe-common' ), + 'repo' => 'https://wordpress.org/plugins/advanced-post-manager/', + 'forum' => 'https://wordpress.org/support/plugin/advanced-post-manager/', + 'stars_url' => 'https://wordpress.org/support/plugin/advanced-post-manager/reviews/?filter=5', + 'description' => esc_html__( + 'Turbo charge your posts admin for any custom post type with sortable filters and columns, and auto-registration of metaboxes.', + 'tribe-common' + ), + 'is_active' => false, + 'version' => null, + ]; + + if ( class_exists( 'Tribe_APM' ) ) { + $plugins['advanced-post-manager']['version'] = 1; + $plugins['advanced-post-manager']['is_active'] = true; + } + + $plugins = (array) apply_filters( 'tribe_help_plugins', $plugins ); + + // Only active ones? + if ( true === $is_active ) { + foreach ( $plugins as $key => $plugin ) { + if ( true !== $plugin['is_active'] ) { + unset( $plugins[ $key ] ); + } + } + } + + // Do the search + if ( is_string( $plugin_name ) ) { + if ( isset( $plugins[ $plugin_name ] ) ) { + return $plugins[ $plugin_name ]; + } else { + return false; + } + } else { + return $plugins; + } + } + + /** + * Get the formatted links of the possible plugins + * + * @since 4.0 + * + * @param boolean $is_active Filter only active plugins + * @return array + */ + public function get_plugin_forum_links( $is_active = true ) { + $plugins = $this->get_plugins( null, $is_active ); + + $list = []; + foreach ( $plugins as $plugin ) { + $list[] = '' . $plugin['title'] . ''; + } + + return $list; + } + + /** + * Get the formatted text of the possible plugins + * + * @since 4.0 + * + * @param boolean $is_active Filter only active plugins + * @return string + */ + public function get_plugins_text( $is_active = true ) { + $plugins = array_merge( $this->get_plugins( null, $is_active ), $this->get_addons( null, $is_active, true ) ); + + $plugins_text = ''; + $i = 0; + $count = count( $plugins ); + foreach ( $plugins as $plugin ) { + $i++; + if ( ! isset( $plugin['is_active'] ) || $plugin['is_active'] !== $is_active ) { + continue; + } + + $plugins_text .= $plugin['title']; + + if ( $i === $count - 1 ) { + $plugins_text .= esc_html__( ' and ', 'tribe-common' ); + } elseif ( $i !== $count ) { + $plugins_text .= ', '; + } + } + + return $plugins_text; + } + + /** + * Get the Addons + * + * @since 4.0 + * + * @param string $plugin Plugin Name to filter + * @param string $is_active Filter if it's active + * @param string $is_important filter if the plugin is important + * @return array + */ + public function get_addons( $plugin = null, $is_active = null, $is_important = null ) { + $addons = []; + + $addons['events-calendar-pro'] = [ + 'id' => 'events-calendar-pro', + 'title' => esc_html__( 'Events Calendar PRO', 'tribe-common' ), + 'link' => 'http://evnt.is/dr', + 'plugin' => [ 'the-events-calendar' ], + 'is_active' => class_exists( 'Tribe__Events__Pro__Main' ), + 'is_important' => true, + ]; + + $addons['eventbrite-tickets'] = [ + 'id' => 'eventbrite-tickets', + 'title' => esc_html__( 'Eventbrite Tickets', 'tribe-common' ), + 'link' => 'http://evnt.is/ds', + 'plugin' => [ 'the-events-calendar' ], + 'is_active' => class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' ), + ]; + + $addons['community-events'] = [ + 'id' => 'community-events', + 'title' => esc_html__( 'Community Events', 'tribe-common' ), + 'link' => 'http://evnt.is/dt', + 'plugin' => [ 'the-events-calendar' ], + 'is_active' => class_exists( 'Tribe__Events__Community__Main' ), + ]; + + $addons['event-aggregator'] = [ + 'id' => 'event-aggregator', + 'title' => esc_html__( 'Event Aggregator', 'tribe-common' ), + 'link' => 'http://evnt.is/19mk', + 'plugin' => [ 'the-events-calendar' ], + 'is_active' => class_exists( 'Tribe__Events__Aggregator' ) && tribe( + 'events-aggregator.main' + )->is_service_active(), + ]; + + $addons['events-filter-bar'] = [ + 'id' => 'events-filter-bar', + 'title' => esc_html__( 'Filter Bar', 'tribe-common' ), + 'link' => 'http://evnt.is/hu', + 'plugin' => [ 'the-events-calendar' ], + 'is_active' => class_exists( 'Tribe__Events__Filterbar__View' ), + ]; + + $addons['events-virtual'] = [ + 'id' => 'events-virtual', + 'title' => esc_html__( 'Virtual Events', 'tribe-common' ), + 'link' => 'http://evnt.is/1alb', + 'plugin' => [ 'the-events-calendar' ], + 'is_active' => class_exists( '\Tribe\Events\Virtual\Plugin' ), + ]; + + $addons['event-tickets-plus'] = [ + 'id' => 'event-tickets-plus', + 'title' => esc_html__( 'Event Tickets Plus', 'tribe-common' ), + 'link' => 'http://evnt.is/18wa', + 'plugin' => [ 'event-tickets' ], + 'is_active' => class_exists( 'Tribe__Tickets_Plus__Main' ), + 'is_important' => true, + ]; + + $addons['event-community-tickets'] = [ + 'id' => 'event-community-tickets', + 'title' => esc_html__( 'Community Tickets', 'tribe-common' ), + 'link' => 'http://evnt.is/18m2', + 'plugin' => [ 'event-tickets' ], + 'is_active' => class_exists( 'Tribe__Events__Community__Tickets__Main' ), + ]; + + /** + * Filter the array of premium addons upsold on the sidebar of the Settings > Help tab + * + * @param array $addons + */ + $addons = (array) apply_filters( 'tribe_help_addons', $addons ); + + // Should I filter something + if ( is_null( $plugin ) && is_null( $is_active ) && is_null( $is_important ) ) { + return $addons; + } + + // Allow for easily grab the addons for a plugin + $filtered = []; + foreach ( $addons as $id => $addon ) { + if ( ! is_null( $plugin ) && ! in_array( $plugin, (array) $addon['plugin'] ) ) { + continue; + } + + // Filter by is_active + if ( + ! is_null( $is_active ) && + ( ! isset( $addon['is_active'] ) || $is_active !== $addon['is_active'] ) + ) { + continue; + } + + // Filter by is_important + if ( + ! is_null( $is_important ) && + ( ! isset( $addon['is_important'] ) || $is_important !== $addon['is_important'] ) + ) { + continue; + } + + $filtered[ $id ] = $addon; + } + + return $filtered; + } + + public function is_active( $should_be_active ) { + $plugins = $this->get_plugins( null, true ); + $addons = $this->get_addons( null, true ); + + $actives = array_merge( $plugins, $addons ); + $is_active = []; + + foreach ( $actives as $id => $active ) { + if ( in_array( $id, (array) $should_be_active ) ) { + $is_active[] = $id; + } + } + + return count( array_filter( $is_active ) ) === 0 ? false : true; + } + + /** + * From a Given link returns it with a GA arguments + * + * @since 4.0 + * + * @param string $link An absolute or a Relative link + * @param boolean $relative Is the Link absolute or relative? + * @return string Link with the GA arguments + */ + public function get_ga_link( $link = null, $relative = true ) { + $query_args = [ + 'utm_source' => 'helptab', + 'utm_medium' => 'plugin-tec', + 'utm_campaign' => 'in-app', + ]; + + if ( true === $relative ) { + $link = trailingslashit( Tribe__Main::$tec_url . $link ); + } + + return esc_url( add_query_arg( $query_args, $link ) ); + } + + /** + * Gets the Feed items from The Events Calendar's Blog + * + * @since 4.0 + * + * @return array Feed Title and Link + */ + public function get_feed_items() { + $news_rss = fetch_feed( Tribe__Main::FEED_URL ); + $news_feed = []; + + if ( ! is_wp_error( $news_rss ) ) { + /** + * Filter the maximum number of items returned from the tribe news feed + * + * @param int $max_items default 5 + */ + $maxitems = $news_rss->get_item_quantity( apply_filters( 'tribe_help_rss_max_items', 5 ) ); + $rss_items = $news_rss->get_items( 0, $maxitems ); + if ( $maxitems > 0 ) { + foreach ( $rss_items as $item ) { + $item = [ + 'title' => esc_html( $item->get_title() ), + 'link' => esc_url( $item->get_permalink() ), + ]; + $news_feed[] = $item; + } + } + } + + return $news_feed; + } + + /** + * Get the information from the Plugin API data + * + * @since 4.0 + * + * @param object $plugin Plugin Object to be used + * @return object An object with the API data + */ + private function get_plugin_api_data( $plugin = null ) { + if ( is_scalar( $plugin ) ) { + return false; + } + + $plugin = (object) $plugin; + + /** + * Filter the amount of time (seconds) we will keep api data to avoid too many external calls + * @var int + */ + $timeout = apply_filters( 'tribe_help_api_data_timeout', 3 * HOUR_IN_SECONDS ); + $transient = 'tribe_help_api_data-' . $plugin->name; + $data = get_transient( $transient ); + + if ( false === $data ) { + if ( ! function_exists( 'plugins_api' ) ) { + include_once ABSPATH . '/wp-admin/includes/plugin-install.php'; + } + + // Fetch the data + $data = plugins_api( 'plugin_information', [ + 'slug' => $plugin->name, + 'is_ssl' => is_ssl(), + 'fields' => [ + 'banners' => true, + 'reviews' => true, + 'downloaded' => true, + 'active_installs' => true, + ], + ] ); + + if ( ! is_wp_error( $data ) ) { + // Format Downloaded Infomation + $data->downloaded = $data->downloaded ? number_format( $data->downloaded ) : _x( 'n/a', 'not available', 'tribe-common' ); + } else { + // If there was a bug on the Current Request just leave + return false; + } + + set_transient( $transient, $data, $timeout ); + } + $data->up_to_date = ( version_compare( $plugin->version, $data->version, '<' ) ) ? esc_html__( 'You need to upgrade!', 'tribe-common' ) : esc_html__( 'You are up to date!', 'tribe-common' ); + + /** + * Filters the API data that was stored in the Transient option + * + * @var array + * @var object The plugin object, check `$this->get_plugins()` for more info + */ + return (object) apply_filters( 'tribe_help_api_data', $data, $plugin ); + } + + /** + * Parses the help text from an Array to the final HTML. + * + * It is the responsibility of code calling this function to ensure proper escaping + * within any HTML. + * + * @since 4.0 + * + * @param string|array $mixed The mixed value to create the HTML from + * @return string + */ + public function get_content_html( $mixed = '' ) { + // If it's an StdObj or String it will be converted + $mixed = (array) $mixed; + + // Loop to start the HTML + foreach ( $mixed as &$line ) { + // If we have content we use that + if ( isset( $line->content ) ) { + $line = $line->content; + } + + if ( is_string( $line ) ) { + continue; + } elseif ( is_array( $line ) ) { + // Allow the developer to pass some configuration + if ( empty( $line['type'] ) ) { + $line['type'] = 'ul'; + } + + $text = '<' . $line['type'] . '>' . "\n"; + foreach ( $line as $key => $item ) { + // Don't add non-numeric items (a.k.a.: configuration) + if ( ! is_numeric( $key ) ) { + continue; + } + + // Only add List Item if is a UL or OL + if ( in_array( $line['type'], [ 'ul', 'ol' ] ) ) { + $text .= '
          • ' . "\n"; + } + + $text .= $this->get_content_html( $item ); + + if ( in_array( $line['type'], [ 'ul', 'ol' ] ) ) { + $text .= '
          • ' . "\n"; + } + } + $text .= '' . "\n"; + + // Create the list as html instead of array + $line = $text; + } + } + + return wpautop( implode( "\n\n", $mixed ) ); + } + + /** + * A Private storage for sections. + * + * @since 4.0 + * + * @access private + * @var array + */ + private $sections = []; + + /** + * Incremented with each method call, then stored in $section->uid. + * + * Used when sorting two instances whose priorities are equal. + * + * @since 4.0 + * + * @static + * @access protected + * @var int + */ + protected static $section_count = 0; + + /** + * Helper function to compare two objects by priority, ensuring sort stability via uid. + * + * @since 4.0 + * + * @access protected + * @param object $a Object A. + * @param object $b Object B. + * + * @return int + */ + protected function by_priority( $a, $b ) { + if ( ! isset( $a->priority ) || ! isset( $b->priority ) || $a->priority === $b->priority ) { + if ( ! isset( $a->unique_call_order ) || ! isset( $b->unique_call_order ) ) { + return 0; + } else { + return $a->unique_call_order > $b->unique_call_order ? 1 : -1; + } + } else { + return $a->priority > $b->priority ? 1 : -1; + } + } + + /** + * Adds a new section to the Help Page + * + * @since 4.0 + * + * @param string $id HTML like ID + * @param string $title The Title of the section, doesn't allow HTML + * @param integer $priority A Numeric ordering for the Section + * @param string $type by default only 'default' or 'box' + * + * @return object The section added + */ + public function add_section( $id, $title = null, $priority = 10, $type = 'default' ) { + if ( empty( $id ) ) { + return false; + } + + // Everytime you call this we will add this up + self::$section_count++; + + $possible_types = (array) apply_filters( 'tribe_help_available_section_types', [ 'default', 'box' ] ); + + // Set a Default type + if ( empty( $type ) || ! in_array( $type, $possible_types ) ) { + $type = 'default'; + } + + // Create the section and Sanitize the values to avoid having to do it later + $section = (object) [ + 'id' => sanitize_html_class( $id ), + 'title' => esc_html( $title ), + 'priority' => absint( $priority ), + 'type' => sanitize_html_class( $type ), + + // This Method Unique count integer used for ordering with priority + 'unique_call_order' => self::$section_count, + + // Counter for ordering Content + 'content_count' => 0, + + // Setup the Base for the content to come + 'content' => [], + ]; + + $this->sections[ $section->id ] = $section; + + return $section; + } + + /** + * Add a New content Item to a Help page Section + * + * @since 4.0 + * + * @param string $section_id Which section this content should be assigned to + * @param string|array $content Item text or array of items, will be passed to `$this->get_content_html` + * @param integer $priority A Numeric priority + * @param array $arguments If you need arguments for item, they can be passed here + * + * @return object The content item added + */ + public function add_section_content( $section_id, $content, $priority = 10, $arguments = [] ) { + $section_id = sanitize_html_class( $section_id ); + + // Check if the section exists + if ( empty( $this->sections[ $section_id ] ) ) { + return false; + } + + // Make sure we have arguments as Array + if ( ! is_array( $arguments ) ) { + return false; + } + + $section = &$this->sections[ $section_id ]; + + // Increment the content counter + $section->content_count++; + + $item = (object) $arguments; + + // Set the priority + $item->priority = absint( $priority ); + + // Set the uid to help ordering + $item->unique_call_order = $section->content_count; + + // Content is not Safe, will be Sanitized on Output + $item->content = $content; + + $section->content[] = $item; + + return $item; + } + + /** + * Remove a section based on the ID + * This method will remove any sections that are indexed at that ID on the sections array + * And the sections that have a propriety of `id` equals to the given $section_id argument + * + * @param string|int $section_id You can use Numeric or String indexes to search + * @return bool|int Returns `false` when no sections were removed and an `int` with the number of sections removed + */ + public function remove_section( $section_id ) { + if ( + ! isset( $this->sections[ $section_id ] ) && + ! in_array( (object) [ 'id' => $section_id ], $this->sections, true ) + ) { + // There are no sections to remove, so false + return false; + } + + $removed = []; + foreach ( $this->sections as $id => $section ) { + if ( ! is_numeric( $id ) && ! is_numeric( $section_id ) && ! empty( $section->id ) ) { + if ( $section->id === $section_id ) { + unset( $this->sections[ $id ] ); + // Mark that this section was removed + $removed[ $id ] = true; + } + } elseif ( $id === $section_id ) { + unset( $this->sections[ $section_id ] ); + // Mark that this section was removed + $removed[ $id ] = true; + } else { + // Mark that this section was NOT removed + $removed[ $id ] = false; + } + } + + // Count how many were removed + $total = count( array_filter( $removed ) ); + + // if Zero just return false + return $total === 0 ? false : $total; + } + + /** + * Based on an Array of sections it render the Help Page contents + * + * @since 4.0 + * + * @param boolean $print Return or Print the HTML after + * @return void|string + */ + public function get_sections( $print = true ) { + /** + * Allow third-party sections here + * + * @var Tribe__Admin__Help_Page + */ + do_action( 'tribe_help_pre_get_sections', $this ); + + /** + * Allow developers to filter all the sections at once + * NOTE: You should be using `tribe_help_add_sections` to add new sections or content + * + * @var array + */ + $sections = apply_filters( 'tribe_help_sections', $this->sections ); + + if ( ! is_array( $sections ) || empty( $sections ) ) { + return false; + } + + // Sort by Priority + uasort( $sections, [ $this, 'by_priority' ] ); + + $html = []; + + foreach ( $sections as $index => $section ) { + $section = (object) $section; + + // If it has no ID or Content, skip + if ( empty( $section->id ) || empty( $section->content ) ) { + continue; + } + + // Set a Default type + if ( empty( $section->type ) ) { + $section->type = 'default'; + } + + /** + * Creates a way to filter a specific section based on the ID + * + * @var object + */ + $section = apply_filters( 'tribe_help_section_' . $section->id, $section, $this ); + + // Sort by Priority + uasort( $section->content, [ $this, 'by_priority' ] ); + + $html[ $section->id . '-start' ] = '
            '; + + if ( ! empty( $section->title ) ) { + $html[ $section->id . '-title' ] = '

            ' . esc_html__( $section->title ) . '

            '; + } + + $html[ $section->id . '-content' ] = $this->get_content_html( $section->content ); + + $html[ $section->id . '-end' ] = '
            '; + } + + /** + * Creates a way for developers to hook to the final HTML + * @var array $html + * @var array $sections + */ + $html = apply_filters( 'tribe_help_sections_html', $html, $sections ); + + if ( true === $print ) { + echo implode( "\n", $html ); + } else { + return $html; + } + + } + + /** + * Prints the Plugin box for the given plugin + * + * @since 4.0 + * + * @param string $plugin Plugin Name key + * @return void + */ + public function print_plugin_box( $plugin ) { + $plugin = (object) $this->get_plugins( $plugin, false ); + $api_data = $this->get_plugin_api_data( $plugin ); + $addons = $this->get_addons( $plugin->name ); + $plugins = get_plugins(); + + if ( $api_data ) { + if ( ! function_exists( 'install_plugin_install_status' ) ) { + include_once ABSPATH . '/wp-admin/includes/plugin-install.php'; + } + $status = install_plugin_install_status( $api_data ); + $plugin_active = is_plugin_active( $status['file'] ); + $plugin_exists = isset( $plugins[ $status['file'] ] ); + + if ( 'install' !== $status['status'] && ! $plugin_active ) { + $args = [ + 'action' => 'activate', + 'plugin' => $status['file'], + 'plugin_status' => 'all', + 'paged' => 1, + 's' => '', + ]; + $activate_url = wp_nonce_url( add_query_arg( $args, 'plugins.php' ), 'activate-plugin_' . $status['file'] ); + $link = '' . esc_html__( 'Activate Plugin', 'tribe-common' ) . ''; + } elseif ( 'update_available' === $status['status'] ) { + $args = [ + 'action' => 'upgrade-plugin', + 'plugin' => $status['file'], + ]; + $update_url = wp_nonce_url( add_query_arg( $args, 'update.php' ), 'upgrade-plugin_' . $status['file'] ); + + $link = '' . esc_html__( 'Upgrade Plugin', 'tribe-common' ) . ''; + } elseif ( $plugin_exists ) { + $link = '' . esc_html__( 'You are up to date!', 'tribe-common' ) . ''; + } + } + + if ( ! isset( $link ) ) { + if ( $api_data ) { + $args = [ + 'tab' => 'plugin-information', + 'plugin' => $plugin->name, + 'TB_iframe' => true, + 'width' => 772, + 'height' => 600, + ]; + $iframe_url = add_query_arg( $args, admin_url( '/plugin-install.php' ) ); + $link = '' . esc_html__( 'Install Plugin', 'tribe-common' ) . ''; + } else { + $link = null; + } + } + ?> +
            +

            title ); ?>

            + + description ) && ! $plugin->is_active ) { + echo wpautop( $plugin->description ); + } + ?> + + +
            +
            +
            version ); ?>
            + +
            +
            requires ); ?>+
            + +
            +
            active_installs ) ); ?>+
            + +
            +
            + + $api_data->rating, + 'type' => 'percent', + 'number' => $api_data->num_ratings, + ] ); + ?> + +
            +
            + + + ' . $link . '

            ' : ''; + } + ?> + + +

            + + +
            + doing_ajax() ) { + return false; + } + + // Avoid Notices by checking the object type of WP_Screen + if ( ! $this->is_wp_screen() ) { + return false; + } + + $defaults = apply_filters( 'tribe_is_post_type_screen_post_types', Tribe__Main::get_post_types() ); + + // Match any Post Type from Tribe + if ( is_null( $post_type ) && in_array( $current_screen->post_type, $defaults ) ) { + return true; + } + + // Match any of the post_types set + if ( ! is_scalar( $post_type ) && in_array( $current_screen->post_type, (array) $post_type ) ) { + return true; + } + + // Match a specific Post Type + if ( $current_screen->post_type === $post_type ) { + return true; + } + + return false; + } + + /** + * Matcher for administration pages that are from Tribe the easier way + * + * @param string|array|null $id What will be checked to see if we return true or false + * + * @return boolean + */ + public function is_screen( $id = null ) { + global $current_screen; + + // Not in the admin we don't even care + if ( ! is_admin() ) { + return false; + } + + // Doing AJAX? bail. + if ( tribe( 'context' )->doing_ajax() ) { + return false; + } + + // Avoid Notices by checking the object type of WP_Screen + if ( ! $this->is_wp_screen() ) { + return false; + } + + // Match any screen from Tribe + if ( is_null( $id ) && false !== strpos( $current_screen->id, 'tribe' ) ) { + return true; + } + + // Match any of the pages set + if ( ! is_scalar( $id ) && in_array( $current_screen->id, (array) $id ) ) { + return true; + } + + // Match a specific page + if ( $current_screen->id === $id ) { + return true; + } + + // Match any post type page in the supported post types + $defaults = apply_filters( 'tribe_is_post_type_screen_post_types', Tribe__Main::get_post_types() ); + if ( in_array( $current_screen->post_type, $defaults ) ) { + return true; + } + return false; + + } + + /** + * Matcher for administration pages action + * + * @param string|array|null $action What will be checked to see if we return true or false + * + * @return boolean + */ + public function is_action( $action = null ) { + global $current_screen; + + // Not in the admin we don't even care + if ( ! is_admin() ) { + return false; + } + + // Doing AJAX? bail. + if ( tribe( 'context' )->doing_ajax() ) { + return false; + } + + // Avoid Notices by checking the object type of WP_Screen + if ( ! $this->is_wp_screen() ) { + return false; + } + + // Match any of the pages set + if ( ! is_scalar( $action ) && in_array( $current_screen->action, (array) $action ) ) { + return true; + } + + // Match a specific page + if ( $current_screen->action === $action ) { + return true; + } + + return false; + } +} diff --git a/tribe-common/src/Tribe/Admin/Live_Date_Preview.php b/tribe-common/src/Tribe/Admin/Live_Date_Preview.php new file mode 100644 index 0000000000..9b53e99bc9 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Live_Date_Preview.php @@ -0,0 +1,68 @@ + Settings > Display admin screen. + */ +class Tribe__Admin__Live_Date_Preview { + protected $target_fields = [ + 'dateWithYearFormat', + 'dateWithoutYearFormat', + 'monthAndYearFormat', + 'weekDayFormat', + ]; + + /** + * Static Singleton Holder + * + * @var self + */ + protected static $instance; + + /** + * Static Singleton Factory Method + * + * @return self + */ + public static function instance() { + return self::$instance ? self::$instance : self::$instance = new self; + } + + /** + * Adds live date previews to the display settings tab (nothing is setup unless + * the user is actually on that tab). + */ + public function __construct() { + add_action( 'tribe_settings_after_do_tabs', [ $this, 'listen' ] ); + } + + /** + * If the user looking at the Display settings tab, adds live date preview facilities. + */ + public function listen() { + // We are only interested in the "Display" tab + if ( 'display' !== Tribe__Settings::instance()->currentTab ) { + return; + } + + /** + * Add or remove fields which should have live date/time preview facilities. + * + * @var array $target_fields + */ + $this->target_fields = (array) apply_filters( 'tribe_settings_date_preview_fields', $this->target_fields ); + + add_filter( 'tribe_field_div_end', [ $this, 'setup_date_previews' ], 10, 2 ); + + // We are still before `admin_enqueue_scripts` making it safe to use `tribe_asset` + tribe_asset( Tribe__Main::instance(), 'tribe-date-live-refresh', 'admin-date-preview.js', [ 'jquery' ], 'admin_enqueue_scripts' ); + } + + public function setup_date_previews( $html, $field ) { + // Not one of the fields we're interested in? Return without modification + if ( ! in_array( $field->id, $this->target_fields ) ) { + return $html; + } + + $preview = esc_html( date_i18n( $field->value ) ); + return " $preview $html"; + } +} diff --git a/tribe-common/src/Tribe/Admin/Notice/Marketing.php b/tribe-common/src/Tribe/Admin/Notice/Marketing.php new file mode 100644 index 0000000000..c4ea865516 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Notice/Marketing.php @@ -0,0 +1,186 @@ +tec_is_active = $tribe_dependency->is_plugin_active( 'Tribe__Events__Main' ); + $this->et_is_active = $tribe_dependency->is_plugin_active( 'Tribe__Tickets__Main' ); + } + + /** + * Register the various Marketing notices. + * + * @since 4.7.23 + */ + public function hook() { + $this->black_friday_hook_notice(); + } + + /** + * Register the Black Friday notice. + * + * @since 4.12.14 + */ + public function black_friday_hook_notice() { + + tribe_notice( + 'black-friday', + [ $this, 'black_friday_display_notice' ], + [ + 'type' => 'tribe-banner', + 'dismiss' => 1, + 'priority' => -1, + 'wrap' => false, + ], + [ $this, 'black_friday_should_display' ] + ); + } + + /** + * Unix time for Monday of Thanksgiving week @ 11am UTC. (11am UTC is 6am EST). + * + * @since 4.12.14 + * + * @return int + */ + public function get_black_friday_start_time() { + $date = Dates::build_date_object( 'fourth Thursday of November ' . date( 'Y' ), 'UTC' ); + $date = $date->modify( '-3 days' ); + $date = $date->setTime( 11, 0 ); + + $start_time = $date->format( 'U' ); + + /** + * Allow filtering of the Black Friday sale start date, mainly for testing purposes. + * + * @since 4.12.14 + * + * @param int $bf_start_date Unix time for the Monday of Thanksgiving week @ 6am UTC. + */ + return apply_filters( 'tribe_black_friday_start_time', $start_time ); + } + + /** + * Unix time for Dec 1 @ 5am UTC. (5am UTC is 12am EST). + * + * @since 4.12.14 + * + * @return int + */ + public function get_black_friday_end_time() { + $date = Dates::build_date_object( 'December 1st', 'UTC' ); + $date = $date->setTime( 5, 0 ); + + $end_time = $date->format( 'U' ); + + /** + * Allow filtering of the Black Friday sale end date, mainly for testing purposes. + * + * @since 4.12.14 + * + * @param int $bf_end_date Unix time for Dec 1 @ 6am UTC. + */ + return apply_filters( 'tribe_black_friday_end_time', $end_time ); + } + /** + * Whether the Black Friday notice should display. + * + * Unix times for Monday of Thanksgiving week @ 6am UTC and Dec 1 2020 @ 6am UTC. + * 6am UTC is midnight for TheEventsCalendar.com, which uses the America/Los_Angeles time zone. + * + * @since 4.12.14 + * + * @return boolean + */ + public function black_friday_should_display() { + // If upsells have been manually hidden, respect that. + if ( defined( 'TRIBE_HIDE_UPSELL' ) && TRIBE_HIDE_UPSELL ) { + return false; + } + + $now = Dates::build_date_object( 'now', 'UTC' )->format( 'U' ); + $bf_sale_start = $this->get_black_friday_start_time(); + $bf_sale_end = $this->get_black_friday_end_time(); + + $current_screen = get_current_screen(); + + $screens = [ + 'tribe_events_page_tribe-app-shop', // App shop. + 'events_page_tribe-app-shop', // App shop. + 'tribe_events_page_tribe-common', // Settings & Welcome. + 'events_page_tribe-common', // Settings & Welcome. + 'toplevel_page_tribe-common', // Settings & Welcome. + ]; + + // If not a valid screen, don't display. + if ( empty( $current_screen->id ) || ! in_array( $current_screen->id, $screens, true ) ) { + return false; + } + + return $bf_sale_start <= $now && $now < $bf_sale_end; + } + + /** + * HTML for the Black Friday notice. + * + * @since 4.12.14 + * + * @return string + */ + public function black_friday_display_notice() { + Tribe__Assets::instance()->enqueue( [ 'tribe-common-admin' ] ); + + $current_screen = get_current_screen(); + + $icon_url = Tribe__Main::instance()->plugin_url . 'src/resources/images/icons/sale-burst.svg'; + $cta_url = 'https://evnt.is/bf' . date( 'Y' ); + + // If we are on the settings page or a welcome page, change the Black Friday URL. + if ( + ! empty( $current_screen->id ) + && ( + 'tribe_events_page_tribe-common' === $current_screen->id + || 'events_page_tribe-common' === $current_screen->id + || 'toplevel_page_tribe-common' === $current_screen->id + ) + ) { + if ( isset( $_GET['welcome-message-the-events-calendar'] ) || isset( $_GET['welcome-message-event-tickets' ] ) ) { + $cta_url .= 'welcome'; + } else { + $cta_url .= 'settings'; + } + } + + ob_start(); + + include Tribe__Main::instance()->plugin_path . 'src/admin-views/notices/tribe-bf-general.php'; + + return ob_get_clean(); + } +} diff --git a/tribe-common/src/Tribe/Admin/Notice/Php_Version.php b/tribe-common/src/Tribe/Admin/Notice/Php_Version.php new file mode 100644 index 0000000000..3e5c0d8de9 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Notice/Php_Version.php @@ -0,0 +1,109 @@ + 'warning', + 'dismiss' => 1, + 'wrap' => 'p', + ], + [ $this, 'should_display' ] + ); + + } + + /** + * Return the list of the Tribe active plugins + * + * @since 4.7.16 + * + * @return string String of items + */ + public function get_active_plugins() { + + $active_plugins = Tribe__Dependency::instance()->get_active_plugins(); + + foreach ( $active_plugins as $active_plugin ) { + + if ( ! $active_plugin['path'] ) { + continue; + } + + $plugin_data = get_plugin_data( $active_plugin['path'] ); + $plugins[] = $plugin_data['Name']; + + } + + return $this->implode_with_grammar( $plugins ); + + } + + /** + * Implodes a list items using 'and' as the final separator and a comma everywhere else + * + * @param array $items List of items to implode + * @since 4.7.16 + * + * @return string String of items + */ + public function implode_with_grammar( $items ) { + + $separator = _x( ', ', 'separator used in a list of items', 'tribe-common' ); + $conjunction = _x( ' and ', 'the final separator in a list of two or more items', 'tribe-common' ); + $output = $last_item = array_pop( $items ); + + if ( $items ) { + $output = implode( $separator, $items ) . $conjunction . $last_item; + } + + return $output; + } + + /** + * We only want to display notices for users + * who are in PHP < 5.6 + * + * @since 4.7.16 + * + * @return boolean + */ + public function should_display() { + // Bail if the user is not admin or can manage plugins + if ( ! current_user_can( 'activate_plugins' ) ) { + return false; + } + + return ! ( version_compare( phpversion(), '5.6.0' ) > 0 ); + } + + /** + * HTML for the PHP notice + * + * @since 4.7.16 + * + * @return string + */ + public function display_notice() { + + // for PHP version above 5.4 and up to 5.6 + if ( version_compare( phpversion(), '5.4.0' ) >= 0 ) { + $text = __( 'Starting March 2019, %1$s will no longer support versions prior to PHP 5.6. Your site is currently using PHP version %2$s which will no longer be supported by %1$s. For best results, we recommend using PHP 5.6 or above.', 'tribe-common' ); + } else { + // for PHPversions below 5.4 + $text = __( 'Starting March 2019, %1$s will no longer work with versions prior to PHP 5.4. Currently your site is using PHP version %2$s. For best results, we recommend using PHP 5.6 or above.', 'tribe-common' ); + } + + $plugins = $this->get_active_plugins(); + + return sprintf( $text, $plugins, phpversion() ); + + } +} diff --git a/tribe-common/src/Tribe/Admin/Notice/Plugin_Download.php b/tribe-common/src/Tribe/Admin/Notice/Plugin_Download.php new file mode 100644 index 0000000000..c17e6c37c1 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Notice/Plugin_Download.php @@ -0,0 +1,166 @@ +plugin_path = $plugin_path; + + tribe_notice( + plugin_basename( $plugin_path ), + [ $this, 'show_inactive_plugins_alert' ] + ); + } + + /** + * Add a required plugin to the notice + * + * @since 4.8.3 Method introduced. + * @since 4.9 Added $version and $addon parameters. + * @since 4.9.12 Add $has_pue_notice param + * @since 4.9.17 Appended "+" to all version numbers to indicate "or any later version". + * + * @param string $name Name of the required plugin + * @param null $thickbox_url Download or purchase URL for plugin from within /wp-admin/ thickbox + * @param bool $is_active Indicates if the plugin is installed and active or not + * @param string $version Optional version number of the required plugin + * @param bool $addon Indicates if the plugin is an add-on for The Events Calendar or Event Tickets + * @param bool $has_pue_notice Indicates that we need to change the messaging due to expired key. + */ + public function add_required_plugin( $name, $thickbox_url = null, $is_active = null, $version = null, $addon = false, $has_pue_notice = false ) { + $this->plugins_required[ $name ] = [ + 'name' => $name, + 'thickbox_url' => $thickbox_url, + 'is_active' => $is_active, + 'version' => $version ? $version . '+' : null, + 'addon' => $addon, + 'has_pue_notice' => $has_pue_notice, + ]; + } + + /** + * Echoes the admin notice, attach to admin_notices + * + * @see \Tribe__Admin__Notice__Plugin_Download::add_required_plugin() + * + * @since 4.9.17 Altered the notice to remove "latest version" verbiage since "+" is now added to the version numbers. + */ + public function show_inactive_plugins_alert() { + if ( ! current_user_can( 'activate_plugins' ) ) { + return; + } + + $plugin_data = get_plugin_data( $this->plugin_path ); + $req_plugins = []; + + if ( empty( $this->plugins_required ) ) { + return; + } + + // Make sure Thickbox is available and consistent appearance regardless of which admin page we're on + wp_enqueue_style( 'plugin-install' ); + wp_enqueue_script( 'plugin-install' ); + add_thickbox(); + + $has_pue_notices = false; + + foreach ( $this->plugins_required as $req_plugin ) { + $item = $req_plugin['name']; + $version = empty( $req_plugin['version'] ) ? '' : ' (' . str_replace( '-dev', '', $req_plugin['version'] ) . ')'; + + if ( ! empty( $req_plugin['thickbox_url'] ) ) { + $item = sprintf( + '%3$s%4$s', + esc_attr( $req_plugin['thickbox_url'] ), + esc_attr( $req_plugin['name'] ), + esc_html( $item ), + esc_html( $version ) + ); + } + + if ( false === $req_plugin['is_active'] ) { + $item = sprintf( + '%1$s', + $item + ); + } + + if ( ! empty( $req_plugin['addon'] ) ) { + $plugin_name[] = $req_plugin['name']; + } + + $req_plugins[] = $item; + + // If any of the items has PUE notice we will warn the user. + if ( $req_plugin['has_pue_notice'] ) { + $has_pue_notices = true; + } + } + + // If empty then add in the default name. + if ( empty( $plugin_name[0] ) ) { + $plugin_name[] = $plugin_data['Name']; + } + + $allowed_html = [ + 'strong' => [], + 'a' => [ 'href' => [] ], + ]; + + $plugin_names_clean_text = wp_kses( $this->implode_with_grammar( $plugin_name ), $allowed_html ); + $req_plugin_names_clean_text = wp_kses( $this->implode_with_grammar( $req_plugins ), $allowed_html ); + + $notice_html_content = '

            ' . esc_html__( 'To begin using %2$s, please install and activate %3$s.', 'tribe-common' ) . '

            '; + + $read_more_link = '' . esc_html__( 'Read more', 'tribe-common' ) . '.'; + $pue_notice_text = esc_html__( 'Thereโ€™s a new version of %1$s available, but your license is expired. Youโ€™ll need to renew your license to get access to the latest version. If you plan to continue using your current version of the plugin(s), be sure to use a compatible version of The Events Calendar. %2$s', 'tribe-common' ); + $pue_notice_html = '

            ' . sprintf( $pue_notice_text, $plugin_names_clean_text, $read_more_link ) . '

            '; + + printf( + '
            ' + . $notice_html_content + . ( $has_pue_notices ? $pue_notice_html : '' ) + . '
            ', + esc_attr( sanitize_title( $plugin_data['Name'] ) ), + $plugin_names_clean_text, + $req_plugin_names_clean_text + ); + } + + /** + * Implodes a list of items with proper grammar. + * + * If only 1 item, no grammar. If 2 items, just conjunction. If 3+ items, commas with conjunction. + * + * @param array $items List of items to implode + * + * @return string String of items + */ + public function implode_with_grammar( $items ) { + $separator = _x( ', ', 'separator used in a list of items', 'tribe-common' ); + $conjunction = _x( ' and ', 'the final separator in a list of two or more items', 'tribe-common' ); + $output = $last_item = array_pop( $items ); + + if ( $items ) { + $output = implode( $separator, $items ); + + if ( 1 < count( $items ) ) { + $output .= $separator; + } + + $output .= $conjunction . $last_item; + } + + return $output; + } + +} diff --git a/tribe-common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php b/tribe-common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php new file mode 100644 index 0000000000..819d85ba54 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php @@ -0,0 +1,239 @@ +current_version = $current_version; + $this->plugin_path = $plugin_path; + + add_action( "in_plugin_update_message-$plugin_path", [ $this, 'maybe_run' ] ); + } + + /** + * Test if there is a plugin upgrade notice and displays it if so. + * + * Expects to fire during "in_plugin_update_message-{plugin_path}", therefore + * this should only run if WordPress has detected that an upgrade is indeed + * available. + */ + public function maybe_run() { + $this->test_for_upgrade_notice(); + + if ( $this->upgrade_notice ) { + $this->display_message(); + } + } + + /** + * Tests to see if an upgrade notice is available. + */ + protected function test_for_upgrade_notice() { + $cache_key = $this->cache_key(); + $this->upgrade_notice = get_transient( $cache_key ); + + if ( false === $this->upgrade_notice ) { + $this->discover_upgrade_notice(); + } + + set_transient( $cache_key, $this->upgrade_notice, $this->cache_expiration() ); + } + + /** + * Returns a cache key unique to the current plugin path and version, that + * still fits within the 45-char limit of regular WP transient keys. + * + * @return string + */ + protected function cache_key() { + return 'tribe_plugin_upgrade_notice-' . hash( 'crc32b', $this->plugin_path . $this->current_version ); + } + + /** + * Returns the period of time (in seconds) for which to cache plugin upgrade messages. + * + * @return int + */ + protected function cache_expiration() { + /** + * Number of seconds to cache plugin upgrade messages for. + * + * Defaults to one day, which provides a decent balance between efficiency savings + * and allowing for the possibility that some upgrade messages may be changed or + * rescinded. + * + * @var int $cache_expiration + */ + return (int) apply_filters( 'tribe_plugin_upgrade_notice_expiration', DAY_IN_SECONDS, $this->plugin_path ); + } + + /** + * Looks at the current stable plugin readme.txt and parses to try and find the first + * available upgrade notice relating to a plugin version higher than this one. + * + * By default, WP SVN is the source. + */ + protected function discover_upgrade_notice() { + /** + * The URL for the current plugin readme.txt file. + * + * @var string $url + * @var string $plugin_path + */ + $readme_url = apply_filters( 'tribe_plugin_upgrade_readme_url', + $this->form_wp_svn_readme_url(), + $this->plugin_path + ); + + if ( ! empty( $readme_url ) ) { + $response = wp_safe_remote_get( $readme_url ); + } + + if ( ! empty( $response ) && ! is_wp_error( $response ) ) { + $readme = $response['body']; + } + + if ( ! empty( $readme ) ) { + $this->parse_for_upgrade_notice( $readme ); + $this->format_upgrade_notice(); + } + + /** + * The upgrade notice for the current plugin (may be empty). + * + * @var string $upgrade_notice + * @var string $plugin_path + */ + return apply_filters( 'tribe_plugin_upgrade_notice', + $this->upgrade_notice, + $this->plugin_path + ); + } + + /** + * Forms the expected URL to the trunk readme.txt file as it is on WP SVN + * or an empty string if for any reason it cannot be determined. + * + * @return string + */ + protected function form_wp_svn_readme_url() { + $parts = explode( '/', $this->plugin_path ); + $slug = empty( $parts[0] ) ? '' : $parts[0]; + return esc_url( "https://plugins.svn.wordpress.org/$slug/trunk/readme.txt" ); + } + + /** + * Given a standard Markdown-format WP readme.txt file, finds the first upgrade + * notice (if any) for a version higher than $this->current_version. + * + * @param string $readme + * @return string + */ + protected function parse_for_upgrade_notice( $readme ) { + $in_upgrade_notice = false; + $in_version_notice = false; + $readme_lines = explode( "\n", $readme ); + + foreach ( $readme_lines as $line ) { + // Once we leave the Upgrade Notice section (ie, we encounter a new section header), bail + if ( $in_upgrade_notice && 0 === strpos( $line, '==' ) ) { + break; + } + + // Look out for the start of the Upgrade Notice section + if ( ! $in_upgrade_notice && preg_match( '/^==\s*Upgrade\s+Notice\s*==/i', $line ) ) { + $in_upgrade_notice = true; + } + + // Also test to see if we have left the version specific note (ie, we encounter a new sub heading or header) + if ( $in_upgrade_notice && $in_version_notice && 0 === strpos( $line, '=' ) ) { + break; + } + + // Look out for the first applicable version-specific note within the Upgrade Notice section + if ( $in_upgrade_notice && ! $in_version_notice && preg_match( '/^=\s*\[?([0-9\.]{3,})\]?\s*=/', $line, $matches ) ) { + // Is this a higher version than currently installed? + if ( version_compare( $matches[1], $this->current_version, '>' ) ) { + $in_version_notice = true; + } + } + + // Copy the details of the upgrade notice for the first higher version we find + if ( $in_upgrade_notice && $in_version_notice ) { + $this->upgrade_notice .= $line . "\n"; + } + } + } + + /** + * Convert the plugin version header and any links from Markdown to HTML. + */ + protected function format_upgrade_notice() { + // Convert [links](http://...) to tags + $this->upgrade_notice = preg_replace( + '/\[([^\]]*)\]\(([^\)]*)\)/', + '${1}', + $this->upgrade_notice + ); + + // Convert =4.0= headings to

            4.0

            tags + $this->upgrade_notice = preg_replace( + '/=\s*([a-zA-Z0-9\.]{3,})\s*=/', + '

            ${1}

            ', + $this->upgrade_notice + ); + } + + /** + * Render the actual upgrade notice. + * + * Please note if plugin-specific styling is required for the message, you can + * use an ID generated by WordPress for one of the message's parent elements + * which takes the form "{plugin_name}-update". Example: + * + * #the-events-calendar-update .tribe-plugin-update-message { ... } + */ + public function display_message() { + $notice = wp_kses_post( $this->upgrade_notice ); + echo "
            $notice
            "; + } +} diff --git a/tribe-common/src/Tribe/Admin/Notice/WP_Version.php b/tribe-common/src/Tribe/Admin/Notice/WP_Version.php new file mode 100644 index 0000000000..5a61a18f71 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Notice/WP_Version.php @@ -0,0 +1,87 @@ + 'warning', + 'dismiss' => 1, + 'priority' => -1, + 'wrap' => 'p', + ], + [ $this, 'wp_version_57_should_display' ] + ); + } + + /** + * Whether the WordPress 5.7 notice should display. + * + * @since 4.12.17 + * + * @return boolean + */ + public function wp_version_57_should_display() { + global $wp_version; + + $screens = [ + 'tribe_events_page_tribe-app-shop', // App shop. + 'events_page_tribe-app-shop', // App shop. + 'tribe_events_page_tribe-common', // Settings & Welcome. + 'events_page_tribe-common', // Settings & Welcome. + 'toplevel_page_tribe-common', // Settings & Welcome. + ]; + + // If not a valid screen, don't display. + if ( empty( $current_screen->id ) || ! in_array( $current_screen->id, $screens, true ) ) { + return false; + } + + $wp_version_min_version_required = '5.8'; + $common_version_required = '4.12.18-dev'; + + return + version_compare( Common::VERSION, $common_version_required, '<' ) + && version_compare( $wp_version, $wp_version_min_version_required, '<' ); + } + + /** + * HTML for the WordPress 5.7 notice. + * + * @since 4.12.17 + * + * @see https://evnt.is/wp5-7 + * + * @return string + */ + public function wp_version_57_display_notice() { + global $wp_version; + $is_wp_57 = version_compare( $wp_version, '5.7-beta', '>=' ); + $html = ''; + + if ( $is_wp_57 ) { + $html .= esc_html__( 'You are using WordPress 5.7 which included a major jQuery update that may cause compatibility issues with past versions of The Events Calendar, Event Tickets and other plugins.', 'tribe-common' ); + } else { + $html .= esc_html__( 'WordPress 5.7 includes a major jQuery update that may cause compatibility issues with past versions of The Events Calendar, Event Tickets and other plugins.', 'tribe-common' ); + } + $html .= ' ' . esc_html__( 'Read more.', 'tribe-common' ) . ''; + + return $html; + } +} diff --git a/tribe-common/src/Tribe/Admin/Notices.php b/tribe-common/src/Tribe/Admin/Notices.php new file mode 100644 index 0000000000..dad1c70345 --- /dev/null +++ b/tribe-common/src/Tribe/Admin/Notices.php @@ -0,0 +1,774 @@ +doing_ajax() ) { + return; + } + + // Hook the actual rendering of notices + add_action( 'current_screen', [ $this, 'hook' ], 20 ); + + // Add our notice dismissal script + tribe_asset( + Tribe__Main::instance(), + 'tribe-notice-dismiss', + 'notice-dismiss.js', + [ 'jquery' ], + 'admin_enqueue_scripts' + ); + } + + /** + * This will happen on the `current_screen` and will hook to the correct actions and display the notices + * + * @since 4.3 + * + * @return void + */ + public function hook() { + $transients = $this->get_transients(); + + foreach ( $transients as $slug => $transient ) { + if ( $this->transient_notice_expired( $slug ) ) { + continue; + } + list( $html, $args, $expire ) = $transients[ $slug ]; + $this->register( $slug, $html, $args ); + } + + foreach ( $this->notices as $notice ) { + if ( ! $this->showing_notice( $notice->slug ) ) { + continue; + } + + add_action( $notice->action, $notice->callback, $notice->priority ); + } + } + + /** + * This will allow the user to Dimiss the Notice using JS. + * + * We will dismiss the notice without checking to see if the slug was already + * registered (via a call to exists()) for the reason that, during a dismiss + * ajax request, some valid notices may not have been registered yet. + * + * @since 4.3 + * + * @return void + */ + public function maybe_dismiss() { + if ( empty( $_GET[ self::$meta_key ] ) ) { + wp_send_json( false ); + } + + $slug = sanitize_title_with_dashes( $_GET[ self::$meta_key ] ); + + // Send a JSON answer with the status of dimissal + wp_send_json( $this->dismiss( $slug ) ); + } + + /** + * Allows a Magic to remove the Requirement of creating a callback + * + * @since 4.3 + * + * @param string $name Name of the method used to create the slug of the notice. + * @param array $arguments Which arguments were used, normally empty. + * + * @return string + */ + public function __call( $name, $arguments ) { + // Transform from Method name to Notice number + $slug = preg_replace( '/render_/', '', $name, 1 ); + + if ( ! $this->exists( $slug ) ) { + return false; + } + + $notice = $this->get( $slug ); + + if ( + empty( $notice->active_callback ) + || ( + is_callable( $notice->active_callback ) + && true == call_user_func( $notice->active_callback ) + ) + ) { + $content = $notice->content; + $wrap = isset( $notice->wrap ) ? $notice->wrap : false; + + if ( is_callable( $content ) ) { + $content = call_user_func_array( $content, [ $notice ] ); + } + + // Return the rendered HTML + return $this->render( $slug, $content, false, $wrap ); + } + + return false; + } + + /** + * This is a helper to actually print the Message + * + * @since 4.3 + * + * @param string $slug The name of the notice. + * @param string $content The content of the notice. + * @param boolean $return Echo or return the content. + * @param string|bool $wrap An optional HTML tag to wrap the content. + * + * @return bool|string + */ + public function render( $slug, $content = null, $return = true, $wrap = false ) { + if ( ! $this->exists( $slug ) ) { + return false; + } + + // Bail if we already rendered + if ( $this->is_rendered( $slug ) ) { + if ( $this->is_rendered_html( $slug, $content ) && ! $return ) { + echo $content; + } + + return false; + } + + $notice = $this->get( $slug ); + $this->notices[ $slug ]->is_rendered = true; + + $classes = [ 'tribe-dismiss-notice', 'notice' ]; + $classes[] = sanitize_html_class( 'notice-' . $notice->type ); + $classes[] = sanitize_html_class( 'tribe-notice-' . $notice->slug ); + + if ( $notice->dismiss ) { + $classes[] = 'is-dismissible'; + } + + // Prevents Empty Notices + if ( empty( $content ) ) { + return false; + } + + if ( is_string( $wrap ) ) { + $content = sprintf( '<%1$s>' . $content . '', $wrap ); + } + + $html = sprintf( '
            %s
            ', implode( ' ', $classes ), $notice->slug, $content ); + + if ( ! $return ) { + echo $html; + } + + return $html; + } + + /** + * This is a helper to print the message surrounded by `p` tags. + * + * @since 4.3 + * + * @param string $slug The name of the notice. + * @param string $content The content of the notice. + * @param boolean $return Echo or return the content. + * + * @return boolean|string + */ + public function render_paragraph( $slug, $content = null, $return = true ) { + return $this->render( $slug, $content, $return, 'p' ); + } + + /** + * Checks if a given notice is rendered + * + * @since 4.7.10 + * + * @param string $slug Which notice to check. + * + * @return boolean + */ + public function is_rendered( $slug ) { + if ( ! $this->exists( $slug ) ) { + return false; + } + + $notice = $this->get( $slug ); + + return isset( $notice->is_rendered ) ? $notice->is_rendered : false; + } + + /** + * Checks if a given string is a notice rendered + * + * @since 4.7.10 + * + * @param string $slug Which notice to check. + * @param string $html Which html string we are check. + * + * @return boolean + */ + public function is_rendered_html( $slug, $html ) { + if ( ! $this->exists( $slug ) ) { + return false; + } + + $search = sprintf( 'data-ref="%s"', $slug ); + + return false !== strpos( $html, $search ); + } + + /** + * Checks if a given user has dismissed a given notice. + * + * @since 4.13.0 + * + * @param string $slug The name of the notice. + * @param int|null $user_id The user ID. + * + * @return boolean + */ + public function has_user_dismissed( $slug, $user_id = null ) { + + if ( is_null( $user_id ) ) { + $user_id = get_current_user_id(); + } + + $dismissed_notices = get_user_meta( $user_id, self::$meta_key ); + + if ( ! is_array( $dismissed_notices ) ) { + return false; + } + + if ( ! in_array( $slug, $dismissed_notices ) ) { + return false; + } + + $notice = $this->get( $slug ); + if ( + is_object( $notice ) + && $notice->recurring + && $this->should_recurring_notice_show( $slug, $user_id ) + ) { + return false; + } + + return true; + } + + /** + * Checks if a given user has dismissed a given notice. + * + * @since 4.3 + * @deprecated 4.13.0 Deprecated in favor of correcting the typo. + * + * @param string $slug The Name of the Notice + * @param int|null $user_id The user ID + * + * @return boolean + */ + public function has_user_dimissed( $slug, $user_id = null ) { + return $this->has_user_dismissed( $slug, $user_id ); + } + + /** + * Gets the last Dismissal for a given notice slug and user. + * + * @since 4.13.0 + * + * @param string $slug Slug of the notice to look for. + * @param int|null $user_id Which user? If null will default to current user. + * + * @return false|\Tribe\Utils\Date_I18n + */ + public function get_last_dismissal( $slug, $user_id = null ) { + if ( is_null( $user_id ) ) { + $user_id = get_current_user_id(); + } + + $dismissed_time = get_user_meta( $user_id, static::$meta_key_time_prefix . $slug, true ); + + if ( ! is_numeric( $dismissed_time ) ) { + return false; + } + + return Dates::build_date_object( $dismissed_time ); + } + + /** + * Determines if a given notice needs to be re-displayed in case of recurring notice. + * + * @since 4.13.0 + * + * @param string $slug Slug of the notice to look for. + * @param int|null $user_id Which user? If null will default to current user. + * + * @return false|\Tribe\Utils\Date_I18n + */ + public function should_recurring_notice_show( $slug, $user_id = null ) { + $notice = $this->get( $slug ); + if ( ! is_object( $notice ) ) { + return false; + } + + if ( ! $notice->recurring || ! $notice->recurring_interval ) { + return false; + } + + if ( is_null( $user_id ) ) { + $user_id = get_current_user_id(); + } + + $interval = Dates::interval( $notice->recurring_interval ); + $last_dismissal = $this->get_last_dismissal( $slug, $user_id ); + if ( ! $last_dismissal ) { + return false; + } + + $next_dismissal = $last_dismissal->add( $interval ); + $now = Dates::build_date_object( 'now' ); + + if ( $now >= $next_dismissal ) { + delete_user_meta( $user_id, self::$meta_key, $slug ); + + return true; + } + + return false; + } + + /** + * A Method to actually add the Meta value telling that this notice has been dismissed + * + * @since 4.3 + * + * @param string $slug The Name of the Notice + * @param int|null $user_id The user ID + * + * @return boolean + */ + public function dismiss( $slug, $user_id = null ) { + if ( is_null( $user_id ) ) { + $user_id = get_current_user_id(); + } + + // If this user has dismissed we don't care either + if ( $this->has_user_dismissed( $slug, $user_id ) ) { + return true; + } + + update_user_meta( $user_id, static::$meta_key_time_prefix . $slug, time() ); + + return add_user_meta( $user_id, self::$meta_key, $slug, false ); + } + + /** + * Removes the User meta holding if a notice was dismissed + * + * @param string $slug The Name of the Notice + * @param int|null $user_id The user ID + * + * @return boolean + */ + public function undismiss( $slug, $user_id = null ) { + if ( is_null( $user_id ) ) { + $user_id = get_current_user_id(); + } + + // If this user has dismissed we don't care either + if ( ! $this->has_user_dismissed( $slug, $user_id ) ) { + return false; + } + + return delete_user_meta( $user_id, self::$meta_key, $slug ); + } + + /** + * Undismisses the specified notice for all users. + * + * @since 4.3 + * + * @param string $slug + * + * @return int + */ + public function undismiss_for_all( $slug ) { + $user_query = new WP_User_Query( [ + 'meta_key' => self::$meta_key, + 'meta_value' => $slug, + ] ); + + $affected = 0; + + foreach ( $user_query->get_results() as $user ) { + if ( $this->undismiss( $slug, $user->ID ) ) { + $affected ++; + } + } + + return $affected; + } + + /** + * Register a Notice and attach a callback to the required action to display it correctly + * + * @since 4.3 + * + * @param string $slug Slug to save the notice + * @param callable|string $callback A callable Method/Function to actually display the notice + * @param array $arguments Arguments to Setup a notice + * @param callable|null $active_callback An optional callback that should return bool values + * to indicate whether the notice should display or not. + * + * @return stdClass + */ + public function register( $slug, $callback, $arguments = [], $active_callback = null ) { + // Prevent weird stuff here + $slug = sanitize_title_with_dashes( $slug ); + + $defaults = [ + 'callback' => null, + 'content' => null, + 'action' => 'admin_notices', + 'priority' => 10, + 'expire' => false, + 'dismiss' => false, + 'recurring' => false, + 'recurring_interval' => null, + 'type' => 'error', + 'is_rendered' => false, + 'wrap' => false, + ]; + + $defaults['callback'] = [ $this, 'render_' . $slug ]; + $defaults['content'] = $callback; + + if ( is_callable( $active_callback ) ) { + $defaults['active_callback'] = $active_callback; + } + + // Merge Arguments + $notice = (object) wp_parse_args( $arguments, $defaults ); + + // Enforce this one + $notice->slug = $slug; + + // Clean these + $notice->priority = absint( $notice->priority ); + $notice->expire = (bool) $notice->expire; + $notice->dismiss = (bool) $notice->dismiss; + $notice->recurring = (bool) $notice->recurring; + + // Set the Notice on the array of notices + $this->notices[ $slug ] = $notice; + + // Return the notice Object because it might be modified + return $notice; + } + + /** + * Create a transient Admin Notice easily. + * + * A transient admin notice is a "fire-and-forget" admin notice that will display once registered and + * until dismissed (if dismissible) without need, on the side of the source code, to register it on each request. + * + * @since 4.7.7 + * + * @param string $slug Slug to save the notice + * @param string $html The notice output HTML code + * @param array $arguments Arguments to Setup a notice + * @param int $expire After how much time (in seconds) the notice will stop showing. + * + * @return stdClass Which notice was registered + */ + public function register_transient( $slug, $html, $arguments = [], $expire = null ) { + $notices = $this->get_transients(); + $notices[ $slug ] = [ $html, $arguments, time() + $expire ]; + $this->set_transients( $notices ); + } + + /** + * Removes a transient notice based on its slug. + * + * @since 4.7.7 + * + * @param string $slug + */ + public function remove_transient( $slug ) { + $notices = $this->get_transients(); + unset( $notices[ $slug ] ); + $this->set_transients( $notices ); + } + + /** + * Removes a notice based on its slug. + * + * @since 4.3 + * + * @param string $slug + * + * @return bool + */ + public function remove( $slug ) { + if ( ! $this->exists( $slug ) ) { + return false; + } + + unset( $this->notices[ $slug ] ); + + return true; + } + + /** + * Gets the configuration for the Notices + * + * @since 4.3 + * + * @param string $slug + * + * @return array|null + */ + public function get( $slug = null ) { + // Prevent weird stuff here + $slug = sanitize_title_with_dashes( $slug ); + + if ( is_null( $slug ) ) { + return $this->notices; + } + + if ( ! empty( $this->notices[ $slug ] ) ) { + return $this->notices[ $slug ]; + } + + return null; + } + + /** + * Checks if a given notice exists + * + * @since 4.3 + * + * @param string $slug + * + * @return bool + */ + public function exists( $slug ) { + return is_object( $this->get( $slug ) ) ? true : false; + } + + /** + * Returns an array of registered transient notices. + * + * @since 4.7.7 + * + * @return array An associative array in the shape [ => [ , , ] ] + */ + protected function get_transients() { + $cached = tribe( 'cache' )['transient_admin_notices']; + + if ( false !== $cached ) { + return $cached; + } + + $transient = self::$transient_notices_name; + $notices = get_transient( $transient ); + $notices = is_array( $notices ) ? $notices : []; + + if ( $this->did_prune_transients ) { + $this->did_prune_transients = true; + foreach ( $notices as $key => $notice ) { + list( $html, $args, $expire_at ) = $notice; + + if ( $expire_at < time() ) { + unset( $notices[ $key ] ); + } + } + } + + tribe( 'cache' )['transient_admin_notices'] = $notices; + + return $notices; + } + + /** + * Updates/sets the transient notices transient. + * + * @since 4.7.7 + * + * @param array $notices An associative array in the shape [ => [ , , ] ] + */ + protected function set_transients( $notices ) { + $transient = self::$transient_notices_name; + set_transient( $transient, $notices, MONTH_IN_SECONDS ); + } + + /** + * Checks whether a specific transient admin notices is being shown or not, depending on its expiration and + * dismissible status. + * + * + * @since 4.11.1 + * + * @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used + * to register the transient notice in the `tribe_transient_notice` function or the + * `Tribe__Admin__Notices::register_transient()` method. + * + * @return bool Whether the transient notice is showing or not. + */ + public function showing_transient_notice( $slug ) { + $transient_notices = (array) $this->get_transients(); + + return isset( $transient_notices[ $slug ] ) + && ! $this->has_user_dismissed( $slug ) + && ! $this->transient_notice_expired( $slug ); + } + + /** + * Checks whether a transient notice expired or not. + * + * @since 4.11.1 + * + * @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used + * to register the transient notice in the `tribe_transient_notice` function or the + * `Tribe__Admin__Notices::register_transient()` method. + * + * @return bool Whether the transient notice is expired or not. + */ + protected function transient_notice_expired( $slug ) { + $transients = (array) $this->get_transients(); + + if ( ! isset( $transients[ $slug ] ) ) { + return true; + } + + list( $html, $args, $expire ) = $transients[ $slug ]; + if ( $expire < time() ) { + return true; + } + + return false; + } + + /** + * Checks whether a notice is being shown or not; the result takes the notice callback and dismissible status into + * account. + * + * @since 4.11.1 + * + * @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used + * to register the transient notice in the `tribe_transient_notice` function or the + * `Tribe__Admin__Notices::register_transient()` method. + * + * @return bool Whether the notice is showing or not. + */ + public function showing_notice( $slug ) { + if ( ! isset( $this->notices[ $slug ] ) ) { + return false; + } + + $notice = $this->notices[ $slug ]; + if ( $notice->dismiss && $this->has_user_dismissed( $notice->slug ) ) { + return false; + } + + if ( + ! empty( $notice->active_callback ) + && is_callable( $notice->active_callback ) + && false == call_user_func( $notice->active_callback ) + ) { + return false; + } + + return true; + } +} diff --git a/tribe-common/src/Tribe/Ajax/Dropdown.php b/tribe-common/src/Tribe/Ajax/Dropdown.php new file mode 100644 index 0000000000..fd490f4ef3 --- /dev/null +++ b/tribe-common/src/Tribe/Ajax/Dropdown.php @@ -0,0 +1,336 @@ + $search Search string from Select2 + * @param int $page When we deal with pagination + * @param array $args Which arguments we got from the Template + * @param string $source What source it is + * + * @return array + */ + public function search_terms( $search, $page, $args, $source ) { + $data = []; + + if ( empty( $args['taxonomy'] ) ) { + $this->error( esc_attr__( 'Cannot look for Terms without a taxonomy', 'tribe-common' ) ); + } + + // We always want all the fields so we overwrite it + $args['fields'] = isset( $args['fields'] ) ? $args['fields'] : 'all'; + $args['hide_empty'] = isset( $args['hide_empty'] ) ? $args['hide_empty'] : false; + + if ( ! empty( $search ) ) { + if ( ! is_array( $search ) ) { + // For older pieces that still use Select2 format. + $args['search'] = $search; + } else { + // Newer SelectWoo uses a new search format. + $args['search'] = $search['term']; + } + } + + // On versions older than 4.5 taxonomy goes as an Param + if ( version_compare( $GLOBALS['wp_version'], '4.5', '<' ) ) { + $terms = get_terms( $args['taxonomy'], $args ); + } else { + $terms = get_terms( $args ); + } + + $results = []; + + // Respect the parent/child_of argument if set + $parent = ! empty( $args['child_of'] ) ? (int) $args['child_of'] : 0; + $parent = ! empty( $args['parent'] ) ? (int) $args['parent'] : $parent; + + if ( empty( $args['search'] ) ) { + $this->sort_terms_hierarchically( $terms, $results, $parent ); + $results = $this->convert_children_to_array( $results ); + } else { + foreach ( $terms as $term ) { + // Prep for Select2 + $term->id = $term->term_id; + $term->text = $term->name; + $term->breadcrumbs = []; + + if ( 0 !== (int) $term->parent ) { + $ancestors = get_ancestors( $term->id, $term->taxonomy ); + $ancestors = array_reverse( $ancestors ); + foreach ( $ancestors as $ancestor ) { + $ancestor = get_term( $ancestor ); + $term->breadcrumbs[] = $ancestor->name; + } + } + + $results[] = $term; + } + } + + $data['results'] = $results; + $data['taxonomies'] = get_taxonomies(); + + return $data; + } + + /** + * Search for Posts using Select2 + * + * @since 4.12.17 + * + * @param string|array $search Search string from Select2. + * @param int $page Page we want when we're dealing with pagination. + * @param array $args Arguments to pass to the query. + * @param string|int $selected Selected item ID. + * + * @return array An Array of results. + */ + public function search_posts( $search, $page = 1, $args = [], $selected = null ) { + if ( ! empty( $search ) ) { + if ( is_array( $search ) ) { + // Newer SelectWoo uses a new search format. + $args['s'] = $search['term']; // post? + } else { + // For older pieces that still use Select2 format. + $args['s'] = $search; + } + } + + $args['paged'] = $page; + $args['update_post_meta_cache'] = false; + $args['update_post_term_cache'] = false; + + $results = new WP_Query( $args ); + $has_pagination = $results->post_count < $results->found_posts; + + return $this->format_posts_for_dropdown( $results->posts, $selected, $has_pagination ); + } + + /** + * Formats a given array of posts to be displayed into the Dropdown.js module with SelectWoo. + * + * @since 4.12.17 + * + * @param array $posts + * @param null|int $selected + * @param boolean $pagination + * + * @return array + */ + public function format_posts_for_dropdown( array $posts, $selected = null, $pagination = false ) { + $data = [ + 'posts' => [], + 'pagination' => $pagination, + ]; + + // Skip when we don't have posts + if ( empty( $posts ) ) { + return $data; + } + + foreach ( $posts as $post ) { + if ( ! $post instanceof \WP_Post ) { + $post = get_post( $post ); + } + + // Skip non WP Post Objects. + if ( ! $post instanceof \WP_Post ) { + continue; + } + + // Prep for Select2. + $data['posts'][] = [ + 'id' => $post->ID, + 'text' => ! empty( $post->post_title_formatted ) ? $post->post_title_formatted : $post->post_title, + 'selected' => ! empty( $selected ) && (int) $post->ID === (int) $selected, + ]; + } + + return $data; + } + + /** + * Sorts all the Terms for Select2 hierarchically. + * + * @since 4.6 + * + * @param array &$terms Array of Terms from `get_terms`. + * @param array &$into Variable where we will store the. + * @param integer $parent Used for the recursion. + * + * @return array + */ + public function sort_terms_hierarchically( &$terms, &$into, $parent = 0 ) { + foreach ( $terms as $i => $term ) { + if ( $term->parent === $parent ) { + // Prep for Select2 + $term->id = $term->term_id; + $term->text = $term->name; + + $into[ $term->term_id ] = $term; + unset( $terms[ $i ] ); + } + } + + foreach ( $into as $term ) { + $term->children = []; + $this->sort_terms_hierarchically( $terms, $term->children, $term->term_id ); + } + } + + /** + * Makes sure we have arrays for the JS data for Select2 + * + * @since 4.6 + * + * @param object|array $results The Select2 results + * + * @return array + */ + public function convert_children_to_array( $results ) { + if ( isset( $results->children ) ) { + $results->children = $this->convert_children_to_array( $results->children ); + if ( empty( $results->children ) ) { + unset( $results->children ); + } + } else { + foreach ( $results as $key => $item ) { + $item = $this->convert_children_to_array( $item ); + } + } + + if ( empty( $results ) ) { + return []; + } + + return array_values( (array) $results ); + } + + /** + * Parses the Params coming from Select2 Search box + * + * @since 4.6 + * + * @param array $params Params to overwrite the defaults + * + * @return object + */ + public function parse_params( $params ) { + $defaults = [ + 'search' => null, + 'page' => 0, + 'args' => [], + 'source' => null, + ]; + + $arguments = wp_parse_args( $params, $defaults ); + + // Return Object just for the sake of making it simpler to read + return (object) $arguments; + } + + /** + * The default Method that will route all the AJAX calls from our Dropdown AJAX requests + * It is like a Catch All on `wp_ajax_tribe_dropdown` and `wp_ajax_nopriv_tribe_dropdown` + * + * @since 4.6 + * + * @return void + */ + public function route() { + // Push all POST params into a Default set of data + $args = $this->parse_params( empty( $_POST ) ? [] : $_POST ); + + if ( empty( $args->source ) ) { + $this->error( esc_attr__( 'Missing data source for this dropdown', 'tribe-common' ) ); + } + + // Define a Filter to allow external calls to our Select2 Dropdowns. + $filter = sanitize_key( 'tribe_dropdown_' . $args->source ); + if ( has_filter( $filter ) ) { + $data = apply_filters( $filter, [], $args->search, $args->page, $args->args, $args->source ); + } else { + $data = call_user_func_array( [ $this, $args->source ], (array) $args ); + } + + // If we've got a empty dataset we return an error. + if ( empty( $data ) ) { + $this->error( esc_attr__( 'Empty data set for this dropdown', 'tribe-common' ) ); + } else { + $this->success( $data ); + } + } + + /** + * Prints a success message and ensures that we don't hit bugs on Select2 + * + * @since 4.6 + * + * @param array $data + * + * @return void + */ + private function success( $data ) { + // We need a Results item for Select2 Work + if ( ! isset( $data['results'] ) ) { + $data['results'] = []; + } + + wp_send_json_success( $data ); + } + + /** + * Prints an error message and ensures that we don't hit bugs on Select2 + * + * @since 4.6 + * + * @param string $message + * + * @return void + */ + private function error( $message ) { + $data = [ + 'message' => $message, + 'results' => [], + ]; + + wp_send_json_error( $data ); + } + + /** + * Avoid throwing fatals or notices on sources that are invalid + * + * @since 4.6 + * + * @param string $name + * @param mixed $arguments + * + * @return void + */ + public function __call( $name, $arguments ) { + $message = __( 'The "%s" source is invalid and cannot be reached on "%s" instance.', 'tribe-common' ); + + return $this->error( sprintf( $message, $name, __CLASS__ ) ); + } +} diff --git a/tribe-common/src/Tribe/Ajax/Operations.php b/tribe-common/src/Tribe/Ajax/Operations.php new file mode 100644 index 0000000000..09b54ae99e --- /dev/null +++ b/tribe-common/src/Tribe/Ajax/Operations.php @@ -0,0 +1,22 @@ +register_assets(); + } + + /** + * Adds the page to the admin menu + */ + public function add_menu_page() { + if ( ! Tribe__Settings::instance()->should_setup_pages() ) { + return; + } + + $page_title = esc_html__( 'Event Add-Ons', 'tribe-common' ); + $menu_title = esc_html__( 'Event Add-Ons', 'tribe-common' ); + $capability = apply_filters( 'tribe_events_addon_page_capability', 'install_plugins' ); + + $where = Tribe__Settings::instance()->get_parent_slug(); + + $this->admin_page = add_submenu_page( + $where, + $page_title, + $menu_title, + $capability, + self::MENU_SLUG, + [ + $this, + 'do_menu_page', + ] + ); + } + + /** + * Adds a link to the shop app to the WP admin bar + */ + public function add_toolbar_item() { + + $capability = apply_filters( 'tribe_events_addon_page_capability', 'install_plugins' ); + + // prevent users who cannot install plugins from seeing addons link + if ( current_user_can( $capability ) ) { + global $wp_admin_bar; + + $wp_admin_bar->add_menu( [ + 'id' => 'tribe-events-app-shop', + 'title' => esc_html__( 'Event Add-Ons', 'tribe-common' ), + 'href' => Tribe__Settings::instance()->get_url( [ 'page' => self::MENU_SLUG ] ), + 'parent' => 'tribe-events-settings-group', + ] ); + } + } + + /** + * Registers the plugin assets + */ + protected function register_assets() { + tribe_assets( + Tribe__Main::instance(), + [ + [ 'tribe-app-shop-css', 'app-shop.css' ], + [ 'tribe-app-shop-js', 'app-shop.js', [ 'jquery' ] ], + ], + 'admin_enqueue_scripts', + [ + 'conditionals' => [ $this, 'is_current_page' ], + ] + ); + } + + /** + * Checks if the current page is the app shop + * + * @since 4.5.7 + * + * @return bool + */ + public function is_current_page() { + if ( ! Tribe__Settings::instance()->should_setup_pages() || ! did_action( 'admin_menu' ) ) { + return false; + } + + if ( is_null( $this->admin_page ) ) { + _doing_it_wrong( + __FUNCTION__, + 'Function was called before it is possible to accurately determine what the current page is.', + '4.5.6' + ); + return false; + } + + return Tribe__Admin__Helpers::instance()->is_screen( $this->admin_page ); + } + + /** + * Renders the Shop App page + */ + public function do_menu_page() { + $main = Tribe__Main::instance(); + $products = $this->get_all_products(); + $bundles = $this->get_bundles(); + $extensions = $this->get_extensions(); + include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/app-shop.php'; + } + + /** + * Gets all products from the API + * + * @return array|WP_Error + */ + private function get_all_products() { + $all_products = tribe( 'plugins.api' )->get_products(); + + $products = [ + 'the-events-calendar' => (object) $all_products['the-events-calendar'], + 'events-calendar-pro' => (object) $all_products['events-calendar-pro'], + 'events-virtual' => (object) $all_products['events-virtual'], + 'event-aggregator' => (object) $all_products['event-aggregator'], + 'event-tickets' => (object) $all_products['event-tickets'], + 'event-tickets-plus' => (object) $all_products['event-tickets-plus'], + 'promoter' => (object) $all_products['promoter'], + 'tribe-filterbar' => (object) $all_products['tribe-filterbar'], + 'events-community' => (object) $all_products['events-community'], + 'events-community-tickets' => (object) $all_products['events-community-tickets'], + 'tribe-eventbrite' => (object) $all_products['tribe-eventbrite'], + 'image-widget-plus' => (object) $all_products['image-widget-plus'], + ]; + + return $products; + } + + /** + * Gets product bundles + * + * @return array|WP_Error + */ + private function get_bundles() { + $bundles = [ + (object) [ + 'title' => __( 'Events Marketing Bundle', 'tribe-common' ), + 'logo' => 'images/logo/bundle-event-marketing.svg', + 'link' => 'https://evnt.is/1aj3', + 'discount' => __( 'Save over 20%', 'tribe-common' ), + 'description' => __( 'Ticket sales, attendee management, and email marketing for your events', 'tribe-common' ), + 'includes' => [ + 'events-calendar-pro', + 'event-tickets-plus', + 'promoter', + ], + ], + (object) [ + 'title' => __( 'Event Importer Bundle', 'tribe-common' ), + 'logo' => 'images/logo/bundle-event-importer.svg', + 'link' => 'https://evnt.is/1aj2', + 'discount' => __( 'Save over 25%', 'tribe-common' ), + 'description' => __( 'Fill your calendar with events from across the web, including Google Calendar, Meetup, and more.', 'tribe-common' ), + 'includes' => [ + 'events-calendar-pro', + 'tribe-filterbar', + 'event-aggregator' + ], + ], + (object) [ + 'title' => __( 'Virtual Events Marketing Bundle', 'tribe-common' ), + 'logo' => 'images/logo/bundle-virtual-events.svg', + 'link' => 'http://evnt.is/ve-bundle', + 'discount' => __( 'Save over 20%', 'tribe-common' ), + 'description' => __( 'Streamline your online events and increase revenue.', 'tribe-common' ), + 'includes' => [ + 'events-calendar-pro', + 'event-tickets-plus', + 'events-virtual', + 'promoter', + ], + 'features' => [ + __( 'Sell tickets and earn revenue for online events', 'tribe-common' ), + __( 'Zoom integration', 'tribe-common' ), + __( 'Automated emails optimized for virtual events', 'tribe-common' ), + __( 'Add recurring events', 'tribe-common' ), + ], + ], + (object) [ + 'title' => __( 'Community Manager Bundle', 'tribe-common' ), + 'logo' => 'images/logo/bundle-community-manager.svg', + 'link' => 'https://evnt.is/1aj4', + 'discount' => __( 'Save over 20%', 'tribe-common' ), /* code review: fix this */ + 'description' => __( 'Handle event submissions with ticket sales and everything you need to build a robust community.', 'tribe-common' ), + 'includes' => [ + 'event-tickets-plus', + 'events-community', + 'events-community-tickets', + 'tribe-filterbar', + ], + ], + (object) [ + 'title' => __( 'Ultimate Bundle', 'tribe-common' ), + 'logo' => 'images/logo/bundle-ultimate.svg', + 'link' => 'https://evnt.is/1aj5', + 'discount' => __( 'Save over 20%', 'tribe-common' ), /* code review: fix this */ + 'description' => __( 'All of our premium events management plugins at a deep discount.', 'tribe-common' ), + 'includes' => [ + 'events-calendar-pro', + 'event-tickets-plus', + //'events-virtual', // not yet added to the bundle + 'events-community', + 'events-community-tickets', + 'tribe-filterbar', + 'event-aggregator', + 'tribe-eventbrite', + //'promoter', // not yet added to the bundle + ], + ], + + ]; + + return $bundles; + } + + /** + * Gets product extensions + * + * @return array|WP_Error + */ + private function get_extensions() { + $extensions = [ + (object) [ + 'title' => __( 'Website URL CTA', 'tribe-common' ), + 'link' => 'https://evnt.is/1aj6', + 'image' => 'images/shop/extension-web-url-cta.jpg', + 'description' => __( 'Create a strong call-to-action for attendees to "Join Webinar" instead of only sharing a website address.', 'tribe-common' ), + ], + (object) [ + 'title' => __( 'Link Directly to Webinar', 'tribe-common' ), + 'link' => 'https://evnt.is/1aj7', + 'image' => 'images/shop/extension-link-to-webinar.jpg', + 'description' => __( 'When users click on the event title, theyโ€™ll be taken right to the source of your event, offering a direct route to join.', 'tribe-common' ), + ], + (object) [ + 'title' => __( 'Events Happening Now', 'tribe-common' ), + 'link' => 'https://evnt.is/1aj8', + 'image' => 'images/shop/extension-events-happening-now.jpg', + 'description' => __( 'Use this shortcode to display events that are currently in progress, like webinars and livestreams.', 'tribe-common' ), + ], + (object) [ + 'title' => __( 'Custom Venue Links', 'tribe-common' ), + 'link' => 'https://evnt.is/1aj9', + 'image' => 'images/shop/extension-custom-venue-links.jpg', + 'description' => __( 'Turn the venue name for your event into a clickable URL โ€” a great way to link directly to a venueโ€™s website or a virtual meeting.', 'tribe-common' ), + ], + (object) [ + 'title' => __( 'Adjust Label', 'tribe-common' ), + 'link' => 'https://evnt.is/1aja', + 'image' => 'images/shop/extension-change-label.jpg', + 'description' => __( 'Change "Events" to "Webinars," or "Venues" to "Livestream," or "Organizers" to "Hosts." Tailor your calendar for virtual events and meetings.', 'tribe-common' ), + ], + (object) [ + 'title' => __( 'Reach Attendees', 'tribe-common' ), + 'link' => 'https://evnt.is/1ajc', + 'image' => 'images/shop/extension-advanced-options.jpg', + 'description' => __( 'From registration to attendance history, view every step of the event lifecycle with this HubSpot integration.', 'tribe-common' ), + ], + ]; + + return $extensions; + } + + /** + * Static Singleton Factory Method + * + * @return Tribe__App_Shop + */ + public static function instance() { + if ( ! isset( self::$instance ) ) { + $className = __CLASS__; + self::$instance = new $className; + } + + return self::$instance; + } + } +} diff --git a/tribe-common/src/Tribe/Asset/Data.php b/tribe-common/src/Tribe/Asset/Data.php new file mode 100644 index 0000000000..2dd9957340 --- /dev/null +++ b/tribe-common/src/Tribe/Asset/Data.php @@ -0,0 +1,67 @@ +objects[ $object_name ] = $data; + } + + /** + * Outputs the + * @internal + */ + public function render_json() { + if ( empty( $this->objects ) ) { + return; + } + + echo ''; + } +} diff --git a/tribe-common/src/Tribe/Asset/Factory.php b/tribe-common/src/Tribe/Asset/Factory.php new file mode 100644 index 0000000000..fee20c5779 --- /dev/null +++ b/tribe-common/src/Tribe/Asset/Factory.php @@ -0,0 +1,56 @@ +get_asset_class_name( $name ); + + // `Jquery_Resize` to `Tribe__Asset__Jquery_Resize` + $full_class_name = $this->get_asset_full_class_name( $class_name ); + + return class_exists( $full_class_name ) ? new $full_class_name() : false; + } + + protected function get_asset_class_name( $name ) { + // `jquery-resize` to `Jquery_Resize` + $class_name = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $name ) ) ); + + return $class_name; + } + + /** + * @param string $class_name + * + * @return string + */ + private function get_asset_full_class_name( $class_name ) { + // `Jquery_Resize` to `Tribe__Asset__Jquery_Resize` + $full_class_name = $this->get_asset_class_name_prefix() . $class_name; + + return $full_class_name; + } + + /** + * @return string + */ + protected function get_asset_class_name_prefix() { + return 'Tribe__Asset__'; + } + + /** + * @return Tribe__Asset__Factory + */ + public static function instance() { + static $instance; + + if ( ! $instance ) { + $instance = new self; + } + + return $instance; + } +} diff --git a/tribe-common/src/Tribe/Assets.php b/tribe-common/src/Tribe/Assets.php new file mode 100644 index 0000000000..f431e56a76 --- /dev/null +++ b/tribe-common/src/Tribe/Assets.php @@ -0,0 +1,840 @@ +get( $handle ) ) { + return $tag; + } + + // Bail when not dealing with JS assets. + if ( 'js' !== $asset->type ) { + return $tag; + } + + // Only localize on JS and if we have data. + if ( empty( $asset->localize ) ) { + return $tag; + } + + global $wp_scripts; + + // Makes sure we have an Array of Localize data. + if ( is_object( $asset->localize ) ) { + $localization = [ $asset->localize ]; + } else { + $localization = (array) $asset->localize; + } + + /** + * Check to ensure we haven't already localized it before. + * + * @since 4.5.8 + */ + foreach ( $localization as $localize ) { + if ( in_array( $localize->name, $this->localized ) ) { + continue; + } + + // If we have a Callable as the Localize data we execute it. + if ( is_callable( $localize->data ) ) { + $localize->data = call_user_func( $localize->data, $asset ); + } + + wp_localize_script( $asset->slug, $localize->name, $localize->data ); + + $this->localized[] = $localize->name; + } + + // Fetch the HTML for all the localized data. + ob_start(); + $wp_scripts->print_extra_script( $asset->slug, true ); + $localization_html = ob_get_clean(); + + // After printing it remove data;| + $wp_scripts->add_data( $asset->slug, 'data', '' ); + + return $localization_html . $tag; + } + + /** + * Filters the Script tags to attach Async and/or Defer based on the rules we set in our Asset class. + * + * @since 4.13.0 + * + * @param string $tag Tag we are filtering. + * @param string $handle Which is the ID/Handle of the tag we are about to print. + * + * @return string Script tag with the defer and/or async attached. + */ + public function filter_tag_async_defer( $tag, $handle ) { + // Only filter for own own filters. + if ( ! $asset = $this->get( $handle ) ) { + return $tag; + } + + // Bail when not dealing with JS assets. + if ( 'js' !== $asset->type ) { + return $tag; + } + + // When async and defer are false we bail with the tag. + if ( ! $asset->defer && ! $asset->async ) { + return $tag; + } + + $tag_has_async = false !== strpos( $tag, ' async ' ); + $tag_has_defer = false !== strpos( $tag, ' defer ' ); + $replacement = '\n" + . $tag + . "\n"; + } + return $tag; + } +} diff --git a/tribe-common/src/Tribe/Autoloader.php b/tribe-common/src/Tribe/Autoloader.php new file mode 100755 index 0000000000..90a01e0272 --- /dev/null +++ b/tribe-common/src/Tribe/Autoloader.php @@ -0,0 +1,297 @@ +register_prefix( 'Tribe__Admin__', $this_dir . '/src/Tribe/admin' ); + * $autoloader->register_prefix( 'Tribe__Admin__', $this_dir . '/src/Tribe/another-dir' ); + * $autoloader->register_prefix( 'Tribe__Utils__', $this_dir . '/src/Tribe/another-dir' ); + * + * // register a direct class to path + * $autoloader->register_class( 'Tribe__Some_Class', $this_dir . '/some/path/to/Some_Class.php' ); + * + * // register a fallback dir to be searched for the class before giving up + * $autoloader->add_fallback_dir( $this_dir . '/all-the-classes' ); + * + * // calls `spl_autoload_register` + * $autoloader->register_autoloader(); + * + * // class will be searched in the path + * // `/var/www/site/wp-content/plugins/the-events-calendar/src/Tribe/admin/Some_Class.php' + * // and + * // `/var/www/site/wp-content/plugins/the-events-calendar/src/Tribe/another-dir/Some_Class.php' + * $i = new Tribe__Admin__Some_Class(); + * + * // class will be searched in the path + * // `/var/www/site/wp-content/plugins/the-events-calendar/utils/some-dir/Some_Util.php' + * $i = new Tribe__Utils__Some_Util(); + * + * // class will be searched in the path + * // `/var/www/site/wp-content/plugins/the-events-calendar/deprecated/Tribe_DeprecatedClass.php' + * $i = new Tribe_DeprecatedClass(); + */ + class Tribe__Autoloader { + + /** + * @var Tribe__Autoloader + */ + protected static $instance; + + /** + * An arrays of arrays each containing absolute paths. + * + * Paths are stored trimming any trailing `/`. + * E.g. `/var/www/tribe-pro/wp-content/plugins/the-events-calendar/src/Tribe` + * + * @var string[][] + */ + protected $prefixes; + + /** + * An array of registered prefixes with unique slugs. + * + * @var string[] + */ + protected $prefix_slugs; + + /** + * The string acting as a directory separator in a class name. + * + * E.g.: given `__` as `$dir_separator` then `Admin__Metabox__Some_Metabox` + * will map to `/Admin/Metabox/SomeMetabox.php`. + * + * @var string + */ + protected $dir_separator = '__'; + + /** @var string[] */ + protected $fallback_dirs = []; + + /** + * @var array + */ + protected $class_paths = []; + + /** + * Returns the singleton instance of the class. + * + * @return Tribe__Autoloader + */ + public static function instance() { + if ( ! self::$instance instanceof Tribe__Autoloader ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Registers prefixes and root dirs using an array. + * + * Same as calling `register_prefix` on each one. + * + * @param array $prefixes_to_root_dirs + */ + public function register_prefixes( array $prefixes_to_root_dirs ) { + foreach ( $prefixes_to_root_dirs as $prefix => $root_dir ) { + $this->register_prefix( $prefix, $root_dir ); + } + } + + /** + * Associates a class prefix to an absolute path. + * + * @param string $prefix A class prefix, e.g. `Tribe__Admin__` + * @param string $root_dir The absolute path to the dir containing + * the prefixed classes. + * @param string $slug An optional unique slug to associate to the prefix. + */ + public function register_prefix( $prefix, $root_dir, $slug = '' ) { + $root_dir = $this->normalize_root_dir( $root_dir ); + + // Determine if we need to normalize the $prefix. + $is_namespaced = false !== strpos( $prefix, '\\' ); + + if ( $is_namespaced ) { + // If the prefix is a namespace, then normalize it. + $prefix = trim( $prefix, '\\' ) . '\\'; + } + + if ( ! isset( $this->prefixes[ $prefix ] ) ) { + $this->prefixes[ $prefix ] = []; + } + + $this->prefixes[ $prefix ][] = $root_dir; + + // Let's make sure we're not adding duplicates. + $this->prefixes[ $prefix ] = array_unique( $this->prefixes[ $prefix ] ); + + if ( $slug ) { + $this->prefix_slugs[ $slug ] = $prefix; + } + } + + /** + * Triggers the registration of the autoload method in the SPL + * autoload register. + */ + public function register_autoloader() { + spl_autoload_register( [ $this, 'autoload' ] ); + } + + /** + * Includes the file defining a class. + * + * This is the function that's registered as an autoloader. + * + * @param string $class + */ + public function autoload( $class ) { + $include_path = $this->get_class_path( $class ); + if ( ! empty( $include_path ) ) { + include_once( $include_path ); + } + } + + private function normalize_root_dir( $root_dir ) { + return rtrim( $root_dir, '/' ); + } + + protected function get_prefixed_path( $class ) { + foreach ( $this->prefixes as $prefix => $dirs ) { + $is_namespaced = false !== strpos( $prefix, '\\' ); + + if ( strpos( $class, $prefix ) !== 0 ) { + continue; + } + + $class_name = str_replace( $prefix, '', $class ); + + if ( ! $is_namespaced ) { + $class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php'; + } else { + $class_path_frag = implode( '/', explode( '\\', $class_name ) ) . '.php'; + } + + foreach ( $dirs as $dir ) { + $path = $dir . '/' . $class_path_frag; + if ( ! file_exists( $path ) ) { + // check if the file exists in lowercase + $class_path_frag = strtolower( $class_path_frag ); + $path = $dir . '/' . $class_path_frag; + } + if ( ! file_exists( $path ) ) { + continue; + } + + return $path; + } + } + return false; + } + + protected function get_fallback_path( $class ) { + foreach ( $this->fallback_dirs as $fallback_dir ) { + $include_path = $fallback_dir . '/' . $class . '.php'; + if ( ! file_exists( $include_path ) ) { + // check if the file exists in lowercase + $class = strtolower( $class ); + $include_path = $fallback_dir . '/' . $class . '.php'; + } + if ( ! file_exists( $include_path ) ) { + continue; + } + + return $include_path; + } + } + + /** + * Gets the absolute path to a class file. + * + * @param string $class The class name + * + * @return string Either the absolute path to the class file or an + * empty string if the file was not found. + */ + public function get_class_path( $class ) { + $prefixed_path = $this->get_prefixed_path( $class ); + if ( $prefixed_path ) { + return $prefixed_path; + } + + $class_path = ! empty( $this->class_paths[ $class ] ) ? $this->class_paths[ $class ] :false; + if ( $class_path ) { + return $class_path; + } + + $fallback_path = $this->get_fallback_path( $class ); + + return $fallback_path ? $fallback_path : ''; + } + + /** + * Get the registered prefix by slug + * + * @param string $slug Unique slug for registered prefix. + * + * @return false|string Either the prefix registered to the + * unique slug or false if not found. + */ + public function get_prefix_by_slug( $slug ) { + $prefix = false; + + if ( isset( $this->prefix_slugs[ $slug ] ) ) { + $prefix = $this->prefix_slugs[ $slug ]; + } + + return $prefix; + } + + /** + * Adds a folder to search for classes that were not found among + * the prefixed ones. + * + * This is the method to use to register a directory of deprecated + * classes. + * + * @param string $dir An absolute path dto a dir. + */ + public function add_fallback_dir( $dir ) { + if ( in_array( $dir, $this->fallback_dirs ) ) { + return; + } + $this->fallback_dirs[] = $this->normalize_root_dir( $dir ); + } + + /** + * @return string + */ + public function get_dir_separator() { + return $this->dir_separator; + } + + /** + * @param string $dir_separator + */ + public function set_dir_separator( $dir_separator ) { + $this->dir_separator = $dir_separator; + } + + public function register_class( $class, $path ) { + $this->class_paths[ $class ] = $path; + } + } + } diff --git a/tribe-common/src/Tribe/Cache.php b/tribe-common/src/Tribe/Cache.php new file mode 100755 index 0000000000..72ae358409 --- /dev/null +++ b/tribe-common/src/Tribe/Cache.php @@ -0,0 +1,539 @@ +get_id( $id, $expiration_trigger ); + + /** + * Filters the expiration for cache objects to provide the ability + * to make non-persistent objects be treated as persistent. + * + * @since 4.8 + * + * @param int $expiration Cache expiration time. + * @param string $id Cache ID. + * @param mixed $value Cache value. + * @param string|array $expiration_trigger Action that triggers automatic expiration. + * @param string $key Unique cache key based on Cache ID and expiration trigger last run time. + */ + $expiration = apply_filters( 'tribe_cache_expiration', $expiration, $id, $value, $expiration_trigger, $key ); + + if ( self::NON_PERSISTENT === $expiration ) { + $group = 'tribe-events-non-persistent'; + $expiration = 1; + + // Add so we know what group to use in the future. + $this->non_persistent_keys[ $id ] = $id; + } else { + $group = 'tribe-events'; + } + + return wp_cache_set( $key, $value, $group, $expiration ); + } + + /** + * @param $id + * @param $value + * @param int $expiration + * @param string|array $expiration_trigger + * + * @return bool + */ + public function set_transient( $id, $value, $expiration = 0, $expiration_trigger = '' ) { + if ( $this->data_size_over_packet_size( $value ) ) { + return false; + } + + return set_transient( $this->get_id( $id, $expiration_trigger ), $value, $expiration ); + } + + /** + * Get cached data. Optionally set data if not previously set. + * + * Note: When a default value or callback is specified, this value gets set in the cache. + * + * @param string $id The key for the cached value. + * @param string|array $expiration_trigger Optional. Hook to trigger cache invalidation. + * @param mixed $default Optional. A default value or callback that returns a default value. + * @param int $expiration Optional. When the default value expires, if it gets set. + * @param mixed $args Optional. Args passed to callback. + * + * @return mixed + */ + public function get( $id, $expiration_trigger = '', $default = false, $expiration = 0, $args = [] ) { + $group = isset( $this->non_persistent_keys[ $id ] ) ? 'tribe-events-non-persistent' : 'tribe-events'; + $value = wp_cache_get( $this->get_id( $id, $expiration_trigger ), $group ); + + // Value found. + if ( false !== $value ) { + return $value; + } + + if ( is_callable( $default ) ) { + // A callback has been specified. + $value = call_user_func_array( $default, $args ); + } else { + // Default is a value. + $value = $default; + } + + // No need to set a cache value to false since non-existent values return false. + if ( false !== $value ) { + $this->set( $id, $value, $expiration, $expiration_trigger ); + } + + return $value; + } + + /** + * @param string $id + * @param string|array $expiration_trigger + * + * @return mixed + */ + public function get_transient( $id, $expiration_trigger = '' ) { + return get_transient( $this->get_id( $id, $expiration_trigger ) ); + } + + /** + * @param string $id + * @param string|array $expiration_trigger + * + * @return bool + */ + public function delete( $id, $expiration_trigger = '' ) { + $group = isset( $this->non_persistent_keys[ $id ] ) ? 'tribe-events-non-persistent' : 'tribe-events'; + + // Delete from non-persistent keys list. + if ( 'tribe-events-non-persistent' === $group ) { + unset( $this->non_persistent_keys[ $id ] ); + } + + return wp_cache_delete( $this->get_id( $id, $expiration_trigger ), $group ); + } + + /** + * @param string $id + * @param string|array $expiration_trigger + * + * @return bool + */ + public function delete_transient( $id, $expiration_trigger = '' ) { + return delete_transient( $this->get_id( $id, $expiration_trigger ) ); + } + + /** + * Purge all expired tribe_ transients. + * + * This uses a modification of the the query from https://core.trac.wordpress.org/ticket/20316 + * + * @since 4.11.0 + * + * @return void Just execute the database SQL no return required. + */ + public function delete_expired_transients() { + if ( tribe_get_var( 'has_deleted_expired_transients', false ) ) { + return; + } + + global $wpdb; + + $time = time(); + + $sql = " + DELETE + a, + b + FROM + {$wpdb->options} a + INNER JOIN {$wpdb->options} b + ON b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) ) + AND b.option_value < {$time} + WHERE + a.option_name LIKE '\_transient\_tribe\_%' + AND a.option_name NOT LIKE '\_transient\_timeout\_tribe\_%' + "; + + /** + * Allow third party filtering of the SQL used for deleting expired transients. + * + * @since 4.11.5 + * + * @param string $sql The SQL we execute to delete all the expired transients. + * @param int $time Time we are using to determine what is expired. + */ + $sql = apply_filters( 'tribe_cache_delete_expired_transients_sql', $sql, $time ); + + if ( empty( $sql ) ) { + return; + } + + $wpdb->query( $sql ); + + // Set the variable to prevent this call from running twice. + tribe_set_var( 'has_deleted_expired_transients', true ); + } + + /** + * Flag if we should delete + * + * @since 4.11.5 + * + * @param boolean $value If we should delete transients or not on shutdown. + * + * @return void No return for setting the flag. + */ + public function flag_required_delete_transients( $value = true ) { + tribe_set_var( 'should_delete_expired_transients', $value ); + } + + /** + * Runs on hook `shutdown` and will delete transients on the end of the request. + * + * @since 4.11.5 + * + * @return void No return for action hook method. + */ + public function maybe_delete_expired_transients() { + if ( ! tribe_get_var( 'should_delete_expired_transients', false ) ) { + return; + } + + $this->delete_expired_transients(); + } + + /** + * @param string $key + * @param string|array $expiration_trigger + * + * @return string + */ + public function get_id( $key, $expiration_trigger = '' ) { + if ( is_array( $expiration_trigger ) ) { + $triggers = $expiration_trigger; + } else { + $triggers = array_filter( explode( '|', $expiration_trigger ) ); + } + + $last = 0; + foreach ( $triggers as $trigger ) { + // Bail on empty trigger otherwise it creates a `tribe_last_` opt on the DB. + if ( empty( $trigger ) ) { + continue; + } + + $occurrence = $this->get_last_occurrence( $trigger ); + + if ( $occurrence > $last ) { + $last = $occurrence; + } + } + + $last = empty( $last ) ? '' : $last; + $id = $key . $last; + if ( strlen( $id ) > 80 ) { + $id = 'tribe_' . md5( $id ); + } + + return $id; + } + + /** + * Returns the time of an action last occurrence. + * + * @since 4.9.14 Changed the return value type from `int` to `float`. + * + * @param string $action The action to return the time for. + * + * @return float The time (microtime) an action last occurred, or the current microtime if it never occurred. + */ + public function get_last_occurrence( $action ) { + static $cache_var_name = __METHOD__; + + $cache_last_actions = tribe_get_var( $cache_var_name, [] ); + + if ( isset( $cache_last_actions[ $action ] ) ) { + return $cache_last_actions[ $action ]; + } + + $last_action = (float) get_option( 'tribe_last_' . $action, null ); + + if ( ! $last_action ) { + $last_action = microtime( true ); + $this->set_last_occurrence( $action, $last_action ); + } + + $cache_last_actions[ $action ] = (float) $last_action; + + tribe_set_var( $cache_var_name, $cache_last_actions ); + + return $cache_last_actions[ $action ]; + } + + /** + * Sets the time (microtime) for an action last occurrence. + * + * @since 4.9.14 Changed the type of the time stored from an `int` to a `float`. + * + * @param string $action The action to record the last occurrence of. + * @param int|float $timestamp The timestamp to assign to the action last occurrence or the current time (microtime). + * + * @return boolean IF we were able to set the last occurrence or not. + */ + public function set_last_occurrence( $action, $timestamp = 0 ) { + if ( empty( $timestamp ) ) { + $timestamp = microtime( true ); + } + $updated = update_option( 'tribe_last_' . $action, (float) $timestamp ); + + // For performance reasons we will only expire cache once per request, when needed. + if ( $updated ) { + $this->flag_required_delete_transients( true ); + } + + return $updated; + } + + /** + * Builds a key from an array of components and an optional prefix. + * + * @param mixed $components Either a single component of the key or an array of key components. + * @param string $prefix + * @param bool $sort Whether component arrays should be sorted or not to generate the key; defaults to + * `true`. + * + * @return string The resulting key. + */ + public function make_key( $components, $prefix = '', $sort = true ) { + $key = ''; + $components = is_array( $components ) ? $components : [ $components ]; + foreach ( $components as $component ) { + if ( $sort && is_array( $component ) ) { + $is_associative = count( array_filter( array_keys( $component ), 'is_numeric' ) ) < count( array_keys( $component ) ); + if ( $is_associative ) { + ksort( $component ); + } else { + sort( $component ); + } + } + $key .= maybe_serialize( $component ); + } + + return $this->get_id( $prefix . md5( $key ) ); + } + + /** + * Whether a offset exists. + * + * @since 4.11.0 + * + * @link http://php.net/manual/en/arrayaccess.offsetexists.php + * + * @param mixed $offset An offset to check for. + * + * @return boolean Whether the offset exists in the cache. + */ + public function offsetExists( $offset ) { + return isset( $this->non_persistent_keys[ $offset ] ); + } + + /** + * Offset to retrieve. + * + * @link http://php.net/manual/en/arrayaccess.offsetget.php + * + * @since 4.11.0 + * + * @param mixed $offset The offset to retrieve. + * + * @return mixed Can return all value types. + */ + public function offsetGet( $offset ) { + return $this->get( $offset ); + } + + /** + * Offset to set. + * + * @since 4.11.0 + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php + * + * @param mixed $offset The offset to assign the value to. + * @param mixed $value The value to set. + * + * @return void + */ + public function offsetSet( $offset, $value ) { + $this->set( $offset, $value, self::NON_PERSISTENT ); + } + + /** + * Offset to unset. + * + * @since 4.11.0 + * + * @link http://php.net/manual/en/arrayaccess.offsetunset.php + * + * @param mixed $offset The offset to unset. + * + * @return void + */ + public function offsetUnset( $offset ) { + $this->delete( $offset ); + } + + /** + * Warms up the caches for a collection of posts. + * + * @since 4.10.2 + * + * @param array|int $post_ids A post ID, or a collection of post IDs. + * @param bool $update_post_meta_cache Whether to warm-up the post meta cache for the posts or not. + */ + public function warmup_post_caches( $post_ids, $update_post_meta_cache = false ) { + if ( empty( $post_ids ) ) { + return; + } + + $post_ids = (array) $post_ids; + + global $wpdb; + + $already_cached_ids = []; + foreach ( $post_ids as $post_id ) { + if ( wp_cache_get( $post_id, 'posts' ) instanceof \WP_Post ) { + $already_cached_ids[] = $post_id; + } + } + + $required = array_diff( $post_ids, $already_cached_ids ); + + if ( empty( $required ) ) { + return; + } + + /** @var Tribe__Feature_Detection $feature_detection */ + $feature_detection = tribe( 'feature-detection' ); + $limit = $feature_detection->mysql_limit_for_example( 'post_result' ); + + /** + * Filters the LIMIT that should be used to warm-up post caches and postmeta caches (if the + * `$update_post_meta_cache` parameter is `true`). + * + * Lower this value on less powerful hosts. Return `0` to disable the warm-up completely, and `-1` to remove the + * limit (not recommended). + * + * @since 4.10.2 + * + * @param int $limit The number of posts whose caches will be warmed up, per query. + */ + $limit = (int) apply_filters( 'tribe_cache_warmup_post_cache_limit', min( $limit, count( $post_ids ) ) ); + + if ( 0 === $limit ) { + // Warmup disabled. + return; + } + + $buffer = $post_ids; + $page = 0; + + do { + $limit_clause = $limit < 0 ? sprintf( 'LIMIT %d,%d', $limit * $page, $limit ) : ''; + $page++; + $these_ids = array_splice( $buffer, 0, $limit ); + $interval = implode( ',', array_map( 'absint', $these_ids ) ); + $posts_query = "SELECT * FROM {$wpdb->posts} WHERE ID IN ({$interval}) {$limit_clause}"; + $post_objects = $wpdb->get_results( $posts_query ); + if ( is_array( $post_objects ) && ! empty( $post_objects ) ) { + foreach ( $post_objects as $post_object ) { + $post = new \WP_Post( $post_object ); + wp_cache_set( $post_object->ID, $post, 'posts' ); + } + + if ( $update_post_meta_cache ) { + update_meta_cache( 'post', $these_ids ); + } + } + } while ( ! empty( $post_objects ) && is_array( $post_objects ) && count( $post_objects ) < count( $post_ids ) ); + } + + /** + * If NOT using an external object caching system, then check if the size, in bytes, of the data + * to write to the database would fit into the `max_allowed_packet` setting or not. + * + * @since 4.12.14 + * + * @param string|array|object $value The value to check. + * + * @return bool Whether the data, in its serialized form, would fit into the current database `max_allowed_packet` + * setting or not. + */ + public function data_size_over_packet_size( $value ) { + if ( wp_using_ext_object_cache() ) { + // We cannot know and that is a concern of the external caching system. + return false; + } + + try { + $serialized_value = maybe_serialize( $value ); + $size = strlen( $serialized_value ); + } catch ( Exception $e ) { + // The underlying function would run into the same issue, bail and do not set the transient. + return true; + } + + /** @var Tribe__Feature_Detection $feature_detection */ + $feature_detection = tribe( 'feature-detection' ); + + // If the size of the string is above 90% of the database `max_allowed_packet` setting, then it should not be written to the db. + return $size > ( $feature_detection->get_mysql_max_packet_size() * .9 ); + } +} diff --git a/tribe-common/src/Tribe/Cache_Listener.php b/tribe-common/src/Tribe/Cache_Listener.php new file mode 100755 index 0000000000..bfa3fce112 --- /dev/null +++ b/tribe-common/src/Tribe/Cache_Listener.php @@ -0,0 +1,171 @@ +cache = new Tribe__Cache(); + } + + /** + * Run the init functionality (like add_hooks). + * + * @return void + */ + public function init() { + $this->add_hooks(); + } + + /** + * Add the hooks necessary. + * + * @return void + */ + private function add_hooks() { + add_action( 'save_post', [ $this, 'save_post' ], 0, 2 ); + add_action( 'updated_option', [ $this, 'update_last_updated_option' ], 10, 3 ); + add_action( 'updated_option', [ $this, 'update_last_save_post' ], 10, 3 ); + add_action( 'generate_rewrite_rules', [ $this, 'generate_rewrite_rules' ] ); + } + + /** + * Run the caching functionality that is executed on save post. + * + * @param int $post_id The post_id. + * @param WP_Post $post The current post object being saved. + */ + public function save_post( $post_id, $post ) { + if ( in_array( $post->post_type, Tribe__Main::get_post_types() ) ) { + $this->cache->set_last_occurrence( self::TRIGGER_SAVE_POST ); + } + } + + /** + * Run the caching functionality that is executed on saving tribe calendar options. + * + * @see 'updated_option' + * + * @param string $option_name Name of the updated option. + * @param mixed $old_value The old option value. + * @param mixed $value The new option value. + */ + public function update_last_save_post( $option_name, $old_value, $value ) { + $triggers = [ + 'tribe_events_calendar_options' => true, + 'permalink_structure' => true, + 'rewrite_rules' => true, + 'start_of_week' => true, + ]; + if ( ! empty( $triggers[ $option_name ] ) ) { + $this->cache->set_last_occurrence( self::TRIGGER_SAVE_POST ); + } + } + + /** + * Run the caching functionality that is executed on saving tribe calendar options. + * + * @see 'updated_option' + * + * @since 4.11.0 + * + * @param string $option_name Name of the updated option. + * @param mixed $old_value The old option value. + * @param mixed $value The new option value. + */ + public function update_last_updated_option( $option_name, $old_value, $value ) { + $triggers = [ + 'active_plugins' => true, + 'tribe_events_calendar_options' => true, + 'permalink_structure' => true, + 'rewrite_rules' => true, + 'start_of_week' => true, + 'sidebars_widgets' => true, + 'stylesheet' => true, + 'template' => true, + 'WPLANG' => true, + ]; + + if ( ! empty( $triggers[ $option_name ] ) ) { + $this->cache->set_last_occurrence( self::TRIGGER_UPDATED_OPTION ); + } + } + + /** + * For any hook that doesn't need any additional filtering + * + * @param $method + * @param $args + */ + public function __call( $method, $args ) { + $this->cache->set_last_occurrence( $method ); + } + + /** + * Instance method of the cache listener. + * + * @return Tribe__Cache_Listener + */ + public static function instance() { + if ( empty( self::$instance ) ) { + self::$instance = self::create_listener(); + } + + return self::$instance; + } + + /** + * Create a cache listener. + * + * @return Tribe__Cache_Listener + */ + private static function create_listener() { + $listener = new self(); + $listener->init(); + + return $listener; + } + + /** + * Run the caching functionality that is executed when rewrite rules are generated. + * + * @since 4.9.11 + */ + public function generate_rewrite_rules() { + $this->cache->set_last_occurrence( self::TRIGGER_GENERATE_REWRITE_RULES ); + } + } diff --git a/tribe-common/src/Tribe/Changelog_Reader.php b/tribe-common/src/Tribe/Changelog_Reader.php new file mode 100755 index 0000000000..43041367e6 --- /dev/null +++ b/tribe-common/src/Tribe/Changelog_Reader.php @@ -0,0 +1,53 @@ +version_count = (int) $version_count; + $this->readme_file = empty( $readme_file ) ? $this->default_readme_file() : $readme_file; + } + + protected function default_readme_file() { + return dirname( Tribe__Main::instance()->plugin_path ) . '/readme.txt'; + } + + public function get_changelog() { + $contents = $this->extract_changelog_section(); + $lines = explode( "\n", $contents ); + + $sections = []; + $current_section = ''; + foreach ( $lines as $line ) { + $line = trim( $line ); + if ( substr( $line, 0, 1 ) == '=' ) { + if ( count( $sections ) >= $this->version_count ) { + break; + } + $header = trim( $line, '= ' ); + $current_section = esc_html( $header ); + $sections[ $current_section ] = []; + } elseif ( strlen( $line ) > 0 ) { + $message = trim( $line, '* ' ); + $sections[ $current_section ][] = esc_html( $message ); + } + } + return $sections; + } + + protected function extract_changelog_section() { + $contents = $this->get_readme_file_contents(); + $start = strpos( $contents, '== Changelog ==' ); + if ( $start === false ) { + return ''; + } + $start += 16; // account for the length of the header + $end = strpos( $contents, '==', $start ); + return trim( substr( $contents, $start, $end - $start ) ); + } + + protected function get_readme_file_contents() { + return file_get_contents( $this->readme_file ); + } +} diff --git a/tribe-common/src/Tribe/Container.php b/tribe-common/src/Tribe/Container.php new file mode 100644 index 0000000000..72a30906fa --- /dev/null +++ b/tribe-common/src/Tribe/Container.php @@ -0,0 +1,340 @@ +doSomething(); + * + * Need the class built immediately? Build it and register it: + * + * tribe_singleton( 'tec.admin.class', new Tribe__Admin__Class() ); + * + * // some code later... + * + * tribe( 'tec.admin.class' )->doSomething(); + * + * Need a very custom way to build the class? Register a callback: + * + * tribe_singleton( 'tec.admin.class', array( Tribe__Admin__Class__Factory, 'make' ) ); + * + * // some code later... + * + * tribe( 'tec.admin.class' )->doSomething(); + * + * Or register the methods that should be called on the object after its construction: + * + * tribe_singleton( 'tec.admin.class', 'Tribe__Admin__Class', array( 'hook', 'register' ) ); + * + * // some code later... + * + * // the `hook` and `register` methods will be called on the built instance. + * tribe( 'tec.admin.class' )->doSomething(); + * + * The class will be built only once (if passing the class name or a callback function), stored + * and the same instance will be returned from that moment on. + * + * @param string $slug The human-readable and catchy name of the class. + * @param string|object|callable $class The full class name or an instance of the class + * or a callback that will return the instance of the class. + * @param array $after_build_methods An array of methods that should be called on + * the built object after the `__construct` method; the methods + * will be called only once after the singleton instance + * construction. + */ + function tribe_singleton( $slug, $class, array $after_build_methods = null ) { + Tribe__Container::init()->singleton( $slug, $class, $after_build_methods ); + } +} + +if ( ! function_exists( 'tribe_register' ) ) { + /** + * Registers a class. + * + * Each call to obtain an instance of this class made using the `tribe( $slug )` function + * will return a new instance; the instances are built just in time (if not passing an + * object instance, in that case it will work as a singleton) and on the first request. + * The container will call the class `__construct` method on the class (if not passing an object + * or a callback function) and will try to automagically resolve dependencies. + * + * Example use: + * + * tribe_register( 'tec.some', 'Tribe__Some' ); + * + * // some code later... + * + * // class is built here + * $some_one = tribe( 'tec.some' )->doSomething(); + * + * // $some_two !== $some_one + * $some_two = tribe( 'tec.some' )->doSomething(); + * + * Need the class built immediately? Build it and register it: + * + * tribe_register( 'tec.admin.class', new Tribe__Admin__Class() ); + * + * // some code later... + * + * // $some_two === $some_one + * // acts like a singleton + * $some_one = tribe( 'tec.some' )->doSomething(); + * $some_two = tribe( 'tec.some' )->doSomething(); + * + * Need a very custom way to build the class? Register a callback: + * + * tribe_register( 'tec.some', array( Tribe__Some__Factory, 'make' ) ); + * + * // some code later... + * + * // $some_two !== $some_one + * $some_one = tribe( 'tec.some' )->doSomething(); + * $some_two = tribe( 'tec.some' )->doSomething(); + * + * Or register the methods that should be called on the object after its construction: + * + * tribe_singleton( 'tec.admin.class', 'Tribe__Admin__Class', array( 'hook', 'register' ) ); + * + * // some code later... + * + * // the `hook` and `register` methods will be called on the built instance. + * tribe( 'tec.admin.class' )->doSomething(); + * + * @param string $slug The human-readable and catchy name of the class. + * @param string|object|callable $class The full class name or an instance of the class + * or a callback that will return the instance of the class. + * @param array $after_build_methods An array of methods that should be called on + * the built object after the `__construct` method; the methods + * will be called each time after the instance contstruction. + */ + function tribe_register( $slug, $class, array $after_build_methods = null ) { + Tribe__Container::init()->bind( $slug, $class, $after_build_methods ); + } +} + +if ( ! function_exists( 'tribe' ) ) { + /** + * Returns a ready to use instance of the requested class. + * + * Example use: + * + * tribe_singleton( 'common.main', 'Tribe__Main'); + * + * // some code later... + * + * tribe( 'common.main' )->do_something(); + * + * @param string|null $slug_or_class Either the slug of a binding previously registered using `tribe_singleton` or + * `tribe_register` or the full class name that should be automagically created or + * `null` to get the container instance itself. + * + * @return mixed|object|Tribe__Container The instance of the requested class. Please note that the cardinality of + * the class is controlled registering it as a singleton using `tribe_singleton` + * or `tribe_register`; if the `$slug_or_class` parameter is null then the + * container itself will be returned. + */ + function tribe( $slug_or_class = null ) { + $container = Tribe__Container::init(); + + return null === $slug_or_class ? $container : $container->make( $slug_or_class ); + } +} + +if ( ! function_exists( 'tribe_set_var' ) ) { + /** + * Registers a value under a slug in the container. + * + * Example use: + * + * tribe_set_var( 'tec.url', 'http://example.com' ); + * + * @param string $slug The human-readable and catchy name of the var. + * @param mixed $value The variable value. + */ + function tribe_set_var( $slug, $value ) { + $container = Tribe__Container::init(); + $container->setVar( $slug, $value ); + } +} + +if ( ! function_exists( 'tribe_get_var' ) ) { + /** + * Returns the value of a registered variable. + * + * Example use: + * + * tribe_set_var( 'tec.url', 'http://example.com' ); + * + * $url = tribe_get_var( 'tec.url' ); + * + * @param string $slug The slug of the variable registered using `tribe_set_var`. + * @param null $default The value that should be returned if the variable slug + * is not a registered one. + * + * @return mixed Either the registered value or the default value if the variable + * is not registered. + */ + function tribe_get_var( $slug, $default = null ) { + $container = Tribe__Container::init(); + + try { + $var = $container->getVar( $slug ); + } catch ( InvalidArgumentException $e ) { + return $default; + } + + return $var; + } +} + +if ( ! function_exists( 'tribe_unset_var' ) ) { + /** + * Returns the value of a registered variable. + * + * Example use: + * + * tribe_set_var( 'tec.url', 'http://example.com' ); + * + * tribe_unset_var( 'tec.url' ); + * + * @since 4.11.0 + * + * @param string $slug The slug of the variable registered using `tribe_unset_var`. + * + * @return void + */ + function tribe_unset_var( $slug ) { + $container = Tribe__Container::init(); + try { + $container->offsetUnset( $slug ); + } catch ( Exception $e ) {} + } +} + +if ( ! function_exists( 'tribe_isset_var' ) ) { + /** + * Returns the value of a registered variable. + * + * Example use: + * + * tribe_set_var( 'tec.url', 'http://example.com' ); + * + * tribe_isset_var( 'tec.url' ); + * + * @since 4.11.0 + * + * @param string $slug The slug of the variable checked using `tribe_isset_var`. + * + * @return boolean Either a the given slug exists. + */ + function tribe_isset_var( $slug ) { + $container = Tribe__Container::init(); + return $container->offsetExists( $slug ); + } +} + +if ( ! function_exists( 'tribe_register_provider' ) ) { + /** + * Registers a service provider in the container. + * + * Service providers must implement the `tad_DI52_ServiceProviderInterface` interface or extend + * the `tad_DI52_ServiceProvider` class. + * + * @see tad_DI52_ServiceProvider + * @see tad_DI52_ServiceProviderInterface + * + * @param string $provider_class + */ + function tribe_register_provider( $provider_class ) { + $container = Tribe__Container::init(); + + $container->register( $provider_class ); + } + + if ( ! function_exists( 'tribe_callback' ) ) { + /** + * Returns a lambda function suitable to use as a callback; when called the function will build the implementation + * bound to `$classOrInterface` and return the value of a call to `$method` method with the call arguments. + * + * @since 4.7 + * @since 4.6.2 Included the $argsN params + * + * @param string $slug A class or interface fully qualified name or a string slug. + * @param string $method The method that should be called on the resolved implementation with the + * specified array arguments. + * @param mixed [$argsN] (optional) Any number of arguments that will be passed down to the Callback + * + * @return callable A PHP Callable based on the Slug and Methods passed + */ + function tribe_callback( $slug, $method ) { + $container = Tribe__Container::init(); + $arguments = func_get_args(); + $is_empty = 2 === count( $arguments ); + + if ( $is_empty ) { + $callable = $container->callback( $slug, $method ); + } else { + $callback = $container->callback( 'callback', 'get' ); + $callable = call_user_func_array( $callback, $arguments ); + } + + return $callable; + } + } + + if ( ! function_exists( 'tribe_callback_return' ) ) { + /** + * Returns a tribe_callback for a very simple Return value method + * + * Example of Usage: + * + * add_filter( 'admin_title', tribe_callback_return( __( 'Ready to work.' ) ) ); + * + * @since 4.6.2 + * + * @param mixed $value The value to be returned + * + * @return callable A PHP Callable based on the Slug and Methods passed + */ + function tribe_callback_return( $value ) { + return tribe_callback( 'callback', 'return_value', $value ); + } + } +} diff --git a/tribe-common/src/Tribe/Context.php b/tribe-common/src/Tribe/Context.php new file mode 100644 index 0000000000..b7188c0cfb --- /dev/null +++ b/tribe-common/src/Tribe/Context.php @@ -0,0 +1,1643 @@ + => [ 'read' => , 'write' => ] ]. + * The key is used to identify the property that will be accessible with the `get` and + * 'dangerously_set_global_context' method, e.g. `$context->get( 'event_display', 'list' );`. + * The locations is a list of locations the context will search, top to bottom, left to right, to find a value that's + * not empty or the default one, here's a list of supported lookup locations: + * + * request_var - look into $_GET, $_POST, $_PUT, $_DELETE, $_REQUEST. + * query_var - get the value from the main WP_Query object query vars. + * query_prop - get the value from a property of the main WP_Query object. + * tribe_option - get the value from a Tribe option. + * option - get the value from a database option. + * transient - get the value from a transient. + * constant - get the value from a constant, can also be a class constant with ::. + * global_var - get the value from a global variable + * static_prop - get the value from a class static property, format: `array( $class, $prop )`. + * prop - get the value from a tribe() container binding, format `array( $binding, $prop )`. + * static_method - get the value from a class static method. + * method - get the value calling a method on a tribe() container binding. + * func - get the value from a function or a closure. + * filter - get the value by applying a filter. + * location_func - get the value by applying a callback to the value of a location. + * + * For each location additional arguments can be specified: + * orm_arg - if `false` then the location will never produce an ORM argument, if provided the ORM arg produced bye the + * location will have this name. + * orm_transform - if provided the value of the location will be obtained by passing it as an argument to a callable. + * + * As the Context locations increase in number it would be impractical to define them inline here. + * The locations will be loaded by the `Tribe__Context::populate_locations` method from the `Context/locations.php` + * file. + * + * @var array + */ + protected static $locations = []; + + /** + * A utility static property keeping track of write locations that + * will be defined as associative arrays. + * + * @var array + */ + protected static $associative_locations = [ + self::TRANSIENT, + self::METHOD, + self::STATIC_METHOD, + self::PROP, + self::STATIC_PROP, + ]; + + /** + * Whether the static dynamic locations were set or not. + * + * @var bool + */ + protected static $did_populate_locations = false; + + /** + * A list of override locations to read and write from. + * + * This list has the same format and options as the static `$locations` property + * but allows a context instance to override, or add, read and write locations. + * + * @var array + */ + protected $override_locations = []; + + /** + * Whether the context of the current HTTP request is an AJAX one or not. + * + * @var bool + */ + protected $doing_ajax; + + /** + * Whether the context of the current HTTP request is a Cron one or not. + * + * @var bool + */ + protected $doing_cron; + + /** + * A request-based array cache to store the values fetched by the context. + * + * @var array + */ + protected $request_cache = []; + + /** + * Whether this context should use the default locations or not. + * This flag property is set to `false` when a context is obtained using + * the `set_locations` method; it will otherwise be set to `true`. + * + * @var bool + */ + protected $use_default_locations = true; + + /** + * Whether we are currently creating a new post, a post of post type(s) or not. + * + * @since 4.7.7 + * + * @param null $post_type The optional post type to check. + * + * @return bool Whether we are currently creating a new post, a post of post type(s) or not. + */ + public function is_new_post( $post_type = null ) { + global $pagenow; + $is_new = 'post-new.php' === $pagenow; + + return $is_new && $this->is_editing_post( $post_type ); + } + + /** + * Whether we are currently editing a post(s), post type(s) or not. + * + * @since 4.7.7 + * + * @param null|array|string|int $post_or_type A post ID, post type, an array of post types or post IDs, `null` + * to just make sure we are currently editing a post. + * + * @return bool + */ + public function is_editing_post( $post_or_type = null ) { + global $pagenow; + $is_new = 'post-new.php' === $pagenow; + $is_post = 'post.php' === $pagenow; + $is_editing = 'edit.php' === $pagenow; + + if ( ! ( $is_new || $is_post || $is_editing ) ) { + return false; + } + + if ( ! empty( $post_or_type ) ) { + $lookup = [ $_GET, $_POST, $_REQUEST ]; + + $current_post = Tribe__Utils__Array::get_in_any( $lookup, 'post', get_post() ); + + if ( is_numeric( $post_or_type ) ) { + + $post = $is_post ? get_post( $post_or_type ) : null; + + return ! empty( $post ) && $post == $current_post; + } + + $post_types = is_array( $post_or_type ) ? $post_or_type : [ $post_or_type ]; + + $post = $is_post ? get_post( $current_post ) : null; + + if ( count( array_filter( $post_types, 'is_numeric' ) ) === count( $post_types ) ) { + return ! empty( $post ) && in_array( $post->ID, $post_types ); + } + + if ( $is_post && $post instanceof WP_Post ) { + $post_type = $post->post_type; + } else { + $post_type = Tribe__Utils__Array::get_in_any( $lookup, 'post_type', 'post' ); + } + + return (bool) count( array_intersect( $post_types, [ $post_type ] ) ); + } + + return $is_new || $is_post; + } + + /** + * Helper function to indicate whether the current execution context is AJAX. + * + * This method exists to allow us test code that behaves differently depending on the execution + * context. + * + * @since 4.7.12 + * @since 4.9.5 Removed the $doing_ajax parameter. + * + * @return boolean + */ + public function doing_ajax() { + return function_exists( 'wp_doing_ajax' ) + ? wp_doing_ajax() + : defined( 'DOING_AJAX' ) && DOING_AJAX; + } + + /** + * Checks whether the context of the current HTTP request is a Cron one or not. + * + * @since 4.7.23 + * @since 4.9.5 Removed the $doing_cron parameter. + * + * @return bool Whether the context of the current HTTP request is a Cron one or not. + */ + public function doing_cron() { + return function_exists( 'wp_doing_cron' ) + ? wp_doing_cron() + : defined( 'DOING_CRON' ) && DOING_CRON; + } + + /** + * Gets a value reading it from the location(s) defined in the `Tribe__Context::$props + * + * @since 4.9.5 + * + * @param string $key The key of the variable to fetch. + * @param mixed|null $default The default value to return if not found. + * @param bool $force Whether to force the re-fetch of the value from the context or + * not; defaults to `false`. + * + * @return mixed The value from the first location that can provide it or the default + * value if not found. + */ + public function get( $key, $default = null, $force = false ) { + /** + * Filters the value of a context variable skipping all of its logic. + * + * @since 4.9.5 + * + * @param mixed $value The value for the key before it's fetched from the context. + * @param string $key The key of the value to fetch from the context. + * @param mixed $default The default value that should be returned if the value is + * not set in the context. + * @param bool $force Whether to force the re-fetch of the value from the context or + * not; defaults to `false`. + */ + $value = apply_filters( "tribe_context_pre_{$key}", null, $key, $default, $force ); + if ( null !== $value ) { + return $value; + } + + $value = $default; + $locations = $this->get_locations(); + $found = false; + + if ( ! $force && isset( $this->request_cache[ $key ] ) ) { + $value = $this->request_cache[ $key ]; + } elseif ( ! empty( $locations[ $key ]['read'] ) ) { + foreach ( $locations[ $key ]['read'] as $location => $keys ) { + $the_value = $this->$location( (array) $keys, $default ); + + if ( $default !== $the_value && static::NOT_FOUND !== $the_value ) { + $found = true; + $value = $the_value; + break; + } + } + } + + /** + * Filters the value fetched from the context for a key. + * + * Useful for testing and local override. + * + * @since 4.9.5 + * + * @param mixed $value The value as fetched from the context. + */ + $value = apply_filters( "tribe_context_{$key}", $value ); + + // Only cache if the value was found. + if ( $found ) { + $this->request_cache[ $key ] = $value; + } + + return $value; + } + + /** + * Alters the context. + * + * Due to its immutable nature setting values on the context will NOT modify the + * context but return a modified clone. + * If you need to modify the global context update the location(s) it should read from + * and call the `refresh` method. + * Example: `$widget_context = tribe_context()->alter( $widget_args );`. + * + * @since 4.9.5 + * + * @param array $values An associative array of key-value pairs to modify the context. + * + * @return \Tribe__Context A clone, with modified, values, of the context the method was called on. + */ + public function alter( array $values ) { + $clone = clone $this; + + $clone->request_cache = array_merge( $clone->request_cache, $values ); + + return $clone; + } + + /** + * Clears the context cache forcing a re-fetch of the variables from the context. + * + * @since 4.9.5 + * + * @param string $key An optional specific key to refresh, if passed only this key + * will be refreshed. + */ + public function refresh( $key = null ) { + if ( null !== $key ) { + unset( $this->request_cache[ $key ] ); + } else { + $this->request_cache = []; + } + } + + /** + * Returns the read and write locations set on the context. + * + * @since 4.9.5 + * + * @return array An array of read and write location in the shape of the `Tribe__Context::$locations` one, + * `[ => [ 'read' => , 'write' => ] ]`. + */ + public function get_locations() { + $this->populate_locations(); + + $locations = $this->use_default_locations + ? array_merge( self::$locations, $this->override_locations ) + : $this->override_locations; + + if ( $this->use_default_locations ) { + /** + * Filters the locations registered in the Context. + * + * @since 4.10.2 + * + * @param $locations array An array of read and write location in the shape of the `Tribe__Context::$locations` one, + * `[ => [ 'read' => , 'write' => ] ]`. + * @param $context Tribe__Context Current instance of the context. + */ + $locations = apply_filters( 'tribe_context_locations', $locations, $this ); + } + + return $locations; + } + + /** + * Reads the value from one or more $_REQUEST vars. + * + * @since 4.9.5 + * + * @param array $request_vars The list of request vars to lookup, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function request_var( array $request_vars, $default ) { + $value = $default; + + foreach ( $request_vars as $request_var ) { + $the_value = tribe_get_request_var( $request_var, self::NOT_FOUND ); + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more global WP_Query object query variables. + * + * @since 4.9.5 + * + * @param array $query_vars The list of query vars to look up, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function query_var( array $query_vars, $default ) { + $value = $default; + + global $wp_query; + + if ( ! $wp_query instanceof \WP_Query ) { + return $value; + } + + foreach ( $query_vars as $query_var ) { + $the_value = $wp_query->get( $query_var, self::NOT_FOUND ); + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more global WP_Query object properties. + * + * @since 4.9.5 + * + * @param array $query_props The list of properties to look up, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function query_prop( array $query_props, $default ) { + $value = $default; + + global $wp_query; + foreach ( $query_props as $query_prop ) { + $the_value = isset( $wp_query->{$query_prop} ) ? $wp_query->{$query_prop} : self::NOT_FOUND; + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one more more `tribe_option`s. + * + * @since 4.9.5 + * + * @param array $tribe_options The list of `tribe_option`s to lookup, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function tribe_option( array $tribe_options, $default ) { + $value = $default; + + foreach ( $tribe_options as $option_name ) { + $the_value = tribe_get_option( $option_name, self::NOT_FOUND ); + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more options. + * + * @since 4.9.5 + * + * @param array $options The list of options to lookup, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function option( array $options, $default ) { + $value = $default; + + foreach ( $options as $option_name ) { + $the_value = get_option( $option_name, self::NOT_FOUND ); + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more transients. + * + * @since 4.9.5 + * + * @param array $transients The list of transients to lookup, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function transient( array $transients, $default ) { + $value = $default; + + foreach ( $transients as $transient ) { + $the_value = get_transient( $transient ); + if ( false !== $the_value ) { + $value = $the_value; + /* + * This will fail when the value is actually `false`. + */ + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more constants. + * + * @since 4.9.5 + * + * @param array $constants The list of constants to lookup, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function constant( array $constants, $default ) { + $value = $default; + + foreach ( $constants as $constant ) { + $the_value = defined( $constant ) ? constant( $constant ) : self::NOT_FOUND; + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more global variable. + * + * @since 4.9.5 + * + * @param array $global_vars The list of global variables to look up, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function global_var( array $global_vars, $default ) { + $value = $default; + + foreach ( $global_vars as $var ) { + $the_value = isset( $GLOBALS[ $var ] ) ? $GLOBALS[ $var ] : self::NOT_FOUND; + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more class static properties. + * + * @since 4.9.5 + * + * @param array $classes_and_props An associative array in the shape [ => ]. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function static_prop( array $classes_and_props, $default ) { + $value = $default; + + foreach ( $classes_and_props as $class => $prop ) { + if ( class_exists( $class ) ) { + // PHP 5.2 compat, on PHP 5.3+ $class::$$prop + $vars = get_class_vars( $class ); + $the_value = isset( $vars[ $prop ] ) ? $vars[ $prop ] : self::NOT_FOUND; + + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + } + + return $value; + } + + /** + * Reads the value from one or more properties of implementations bound in the `tribe()` container. + * + * @since 4.9.5 + * + * @param array $bindings_and_props An associative array in the shape [ => ]. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + protected function prop( array $bindings_and_props, $default ) { + $value = $default; + + foreach ( $bindings_and_props as $binding => $prop ) { + $the_value = tribe()->offsetExists( $binding ) && property_exists( tribe( $binding ), $prop ) + ? tribe( $binding )->{$prop} + : self::NOT_FOUND; + + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the values from one or more static class methods. + * + * @since 4.9.5 + * + * @param array $classes_and_methods An associative array in the shape [ => ]. + * @param mixed $default The default value to return. + * + * @return mixed The first value that's not equal to the default one, the default value + * otherwise. + */ + protected function static_method( array $classes_and_methods, $default ) { + $value = $default; + + foreach ( $classes_and_methods as $class => $method ) { + $the_value = class_exists( $class ) && method_exists( $class, $method ) + ? call_user_func( [ $class, $method ] ) + : self::NOT_FOUND; + + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more methods called on implementations bound in the `tribe()` container. + * + * @since 4.9.5 + * + * @param array $bindings_and_methods An associative array in the shape [ => ]. + * @param mixed $default The default value to return. + * + * @return mixed The first value that's not equal to the default one, the default value + * otherwise. + */ + protected function method( array $bindings_and_methods, $default ) { + $value = $default; + $the_value = self::NOT_FOUND; + + foreach ( $bindings_and_methods as $binding => $method ) { + if ( tribe()->offsetExists( $binding ) ) { + $implementation = tribe( $binding ); + if ( method_exists( $implementation, $method ) ) { + $the_value = $implementation->$method(); + } + } + + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Reads the value from one or more functions until one returns a value that's not the default one. + * + * @since 4.9.5 + * + * @param array $functions An array of functions to call, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first value that's not equal to the default one, the default value + * otherwise. + */ + protected function func( array $functions, $default ) { + $value = $default; + $the_value = self::NOT_FOUND; + + foreach ( $functions as $function ) { + if ( is_callable( $function ) || function_exists( $function ) ) { + $the_value = $function(); + } + + if ( $the_value !== self::NOT_FOUND ) { + $value = $the_value; + break; + } + } + + return $value; + } + + /** + * Modifies the global context using the defined write locations to persist the altered values. + * + * Please keep in mind this will set the the global context for the whole request and, when the + * write location is an option, to the database. + * With great power comes great responsibility: think a lot before using this. + * + * @param array|null $fields An optional whitelist or blacklist of fields to write + * depending on the value of the `$whitelist` parameter; + * defaults to writing all available fields. + * @param bool $whitelist Whether the list of fields provided in the `$fields` + * parameter should be treated as a whitelist (`true`) or + * blacklist (`false`). + * + * @since 4.9.5 + */ + public function dangerously_set_global_context( array $fields = null, $whitelist = true ) { + $locations = $this->get_locations(); + + if ( null !== $fields ) { + $locations = $whitelist + ? array_intersect_key( $locations, array_combine( $fields, $fields ) ) + : array_diff_key( $locations, array_combine( $fields, $fields ) ); + } + + /** + * Here we intersect with the request cache to only write values we've actually read + * or modified. If none of the two happened then there's no need to write anything. + */ + foreach ( array_intersect_key( $this->request_cache, $locations ) as $key => $value ) { + if ( ! isset( $locations[ $key ]['write'] ) ) { + continue; + } + + foreach ( (array) $locations[ $key ]['write'] as $location => $targets ) { + $targets = (array) $targets; + $write_func = 'write_' . $location; + + foreach ( $targets as $arg_1 => $arg_2 ) { + if ( self::FUNC === $location && is_array( $arg_2 ) && is_callable( $arg_2 ) ) { + // Handles write functions specified as an array. + $location_args = [ $arg_2 ]; + } else { + $location_args = in_array( $location, self::$associative_locations, true ) + ? [ $arg_1, $arg_2 ] + : (array) $arg_2; + } + + $args = array_merge( $location_args, [ $value ] ); + + call_user_func_array( [ $this, $write_func ], $args ); + } + } + } + } + + /** + * Writes an altered context value to a request var. + * + * @since 4.9.5 + * + * @param string $request_var The request var to write. + * @param mixed $value The value to set on the request var. + */ + protected function write_request_var( $request_var, $value ) { + if ( isset( $_REQUEST ) ) { + $_REQUEST[ $request_var ] = $value; + } + if ( isset( $_GET ) ) { + $_GET[ $request_var ] = $value; + } + if ( isset( $_POST ) ) { + $_POST[ $request_var ] = $value; + } + } + + /** + * Writes an altered context value to a global WP_Query object properties. + * + * @since 4.9.5 + * + * @param string $query_prop The global WP_Query object property to write. + * @param mixed $value The value to set on the query property. + */ + protected function write_query_prop( $query_prop, $value ) { + global $wp_query; + + if ( ! $wp_query instanceof WP_Query ) { + return; + } + + $wp_query->{$query_prop} = $value; + } + + /** + * Writes an altered context value to a global WP_Query object query var. + * + * @since 4.9.5 + * + * @param string $query_var The global WP_Query query var to write. + * @param mixed $value The value to set on the query var. + */ + protected function write_query_var( $query_var, $value ) { + global $wp_query; + + if ( ! $wp_query instanceof WP_Query ) { + return; + } + + $wp_query->set( $query_var, $value ); + } + + /** + * Writes an altered context value to a `tribe_option`. + * + * @since 4.9.5 + * + * @param string $tribe_option The `tribe_option` to write. + * @param mixed $value The value to set on the `tribe_option`. + */ + protected function write_tribe_option( $tribe_option, $value ) { + tribe_update_option( $tribe_option, $value ); + } + + /** + * Writes an altered context value to an option. + * + * @since 4.9.5 + * + * @param string $option_name The option to write. + * @param mixed $value The value to set on the option. + */ + protected function write_option( $option_name, $value ) { + update_option( $option_name, $value ); + } + + /** + * Writes an altered context value to a transient. + * + * @since 4.9.5 + * + * @param string $transient The transient to write. + * @param int $expiration The transient expiration time, in seconds. + * @param mixed $value The value to set on the transient. + */ + protected function write_transient( $transient, $expiration, $value ) { + set_transient( $transient, $value, $expiration ); + } + + /** + * Writes an altered context value to a constant. + * + * @since 4.9.5 + * + * @param string $constant The constant to define. + * @param mixed $value The value to set on the constant. + */ + protected function write_constant( $constant, $value ) { + if ( defined( $constant ) ) { + return; + } + define( $constant, $value ); + } + + /** + * Writes an altered context value to a global var. + * + * @since 4.9.5 + * + * @param string $global_var The global var to set. + * @param mixed $value The value to set on the global_var. + */ + protected function write_global_var( $global_var, $value ) { + $GLOBALS[ $global_var ] = $value; + } + + /** + * Writes an altered context value setting a public static property on a class. + * + * @since 4.9.5 + * + * @param string $class The class to set the static public property on. + * @param string $prop The static public property to set. + * @param mixed $value The value to set on the property. + */ + protected function write_static_prop( $class, $prop, $value ) { + if ( ! ( class_exists( $class ) && property_exists( $class, $prop ) ) ) { + return; + } + + $class::$$prop = $value; + } + + /** + * Writes an altered context value setting a public property on a `tribe()` binding. + * + * @since 4.9.5 + * + * @param string $binding The container binding to set the public property on. + * @param string $prop The public property to set. + * @param mixed $value The value to set on the property. + */ + protected function write_prop( $binding, $prop, $value ) { + if ( ! tribe()->offsetExists( $binding ) ) { + return; + } + + $implementation = tribe( $binding ); + + if ( ! property_exists( $implementation, $prop ) ) { + return; + } + + $implementation->{$prop} = $value; + } + + /** + * Writes an altered context value calling a public static method on a class. + * + * @since 4.9.5 + * + * @param string $class The class to call the public static method on. + * @param string $method The static method to call. + * @param mixed $value The value to pass to the public static method. + */ + protected function write_static_method( $class, $method, $value ) { + if ( ! class_exists( $class ) ) { + return; + } + call_user_func( [ $class, $method ], $value ); + } + + /** + * Writes an altered context value calling a public method on a `tribe()` binding. + * + * @since 4.9.5 + * + * @param string $binding The `tribe()` container binding to call the public method on. + * @param string $method The method to call. + * @param mixed $value The value to pass to the public method. + */ + protected function write_method( $binding, $method, $value ) { + if ( ! tribe()->offsetExists( $binding ) ) { + return; + } + call_user_func( [ tribe( $binding ), $method ], $value ); + } + + /** + * Writes an altered context value calling a function or closure. + * + * @since 4.9.5 + * + * @param callable $func function, closure or callable to call. + * @param mixed $value The value to pass to the callable. + */ + protected function write_func( $func, $value ) { + if ( ! is_callable( $func ) ) { + return; + } + call_user_func( $func, $value ); + } + + /** + * Adds/replaces read and write locations to a context. + * + * Locations are merged with an `array_merge` call. To refine the locations get them first with the + * `get_locations` method. + * + * @since 4.9.5 + * + * @param array $locations An array of read and write locations to add to the context. + * The array should have the same shape as the static `$locations` + * one: `[ => [ 'read' => , 'write' => ] ]`. + * + * + * @return \Tribe__Context A clone of the current context with the additional read and + * write locations added. + */ + public function add_locations( array $locations ) { + $clone = clone $this; + $clone->override_locations = array_merge( $clone->override_locations, $locations ); + + return $clone; + } + + /** + * Sets, replacing them, the locations used by this context. + * + * + * @since 4.9.5 + * + * @param array $locations An array of locations to replace the current ones. + * @param bool $use_default_locations Whether the context should use the default + * locations defined in the static `$locations` + * property or not. + * + * @return \Tribe__Context A clone of the current context with modified locations. + */ + public function set_locations( array $locations, $use_default_locations = true ) { + $clone = clone $this; + $clone->override_locations = $locations; + $clone->use_default_locations = (bool) $use_default_locations; + + return $clone; + } + + /** + * Returns an array representation of the context. + * + * @since 4.9.5 + * + * @return array An associative array of the context keys and values. + */ + public function to_array( ) { + $locations = array_keys( array_merge( $this->get_locations(), $this->request_cache ) ); + $dump = []; + + foreach ( $locations as $location ) { + $the_value = $this->get( $location, self::NOT_FOUND ); + + if ( self::NOT_FOUND === $the_value ) { + continue; + } + + $dump[ $location ] = $the_value; + } + + return $dump; + } + + /** + * Returns the current context state in a format suitable to hydrate a Redux-like + * store on the front-end. + * + * This method is a filtered wrapper around the the `Tribe__Context::to_array` method to allow the + * customization of the format when producing a store-compatible state. + * + * @param array|null $fields An optional whitelist or blacklist of fields to include + * depending on the value of the `$whitelist` parameter; + * defaults to returning all available fields. + * @param bool $whitelist Whether the list of fields provided in the `$fields` + * parameter should be treated as a whitelist (`true`) or + * blacklist (`false`). + * + * @since 4.9.5 + * + * @return array + */ + public function get_state( array $fields = null, $whitelist = true ) { + $state = $this->to_array(); + $is_global_context = tribe_context() === $this; + + if ( null !== $fields ) { + $state = $whitelist + ? array_intersect_key( $state, array_combine( $fields, $fields ) ) + : array_diff_key( $state, array_combine( $fields, $fields ) ); + } + + /** + * Filters the Redux store compatible state produced from the current context. + * + * @since 4.9.5 + * + * @param array $state The Redux store compatible state produced from the current context. + * @param bool $is_global_context Whether the context producing the state is the global one + * or a modified clone of it. + * @param Tribe__Context The context object producing the state. + */ + $state = apply_filters( 'tribe_context_state', $state, $is_global_context, $this ); + + if ( $is_global_context ) { + /** + * Filters the Redux store compatible state produced from the global context. + * + * While the `tribe_context_state` filter will apply to all contexts producing a + * state this filter will only apply to the global context. + * + * @since 4.9.5 + * + * @param array $state The Redux store compatible state produced from the global context. + * @param Tribe__Context The global context object producing the state. + */ + $state = apply_filters( 'tribe_global_context_state', $state, $this ); + } + + return $state; + } + + /** + * Returns an array of ORM arguments generated from the current context values. + * + * @since 4.9.5 + * + * @param array|null $fields An optional whitelist or blacklist of fields to include + * depending on the value of the `$whitelist` parameter; + * defaults to returning all available fields. + * @param bool $whitelist Whether the list of fields provided in the `$fields` + * parameter should be treated as a whitelist (`true`) or + * blacklist (`false`). + * + * @return array A map of ORM fields produced from the context current values. + */ + public function get_orm_args( array $fields = null, $whitelist = true ) { + $locations = $this->get_locations(); + $dump = $this->to_array(); + $orm_args = []; + $is_global_context = tribe_context() === $this; + + foreach ( $dump as $key => $value ) { + $alias = isset( $locations[ $key ]['orm_arg'] ) + ? $locations[ $key ]['orm_arg'] + : $key; + + if ( false === $alias ) { + // Do not provide the variable as an ORM arg. + continue; + } + + if ( isset( $locations[ $key ]['orm_transform'] ) ) { + $value = call_user_func( $locations[ $key ]['orm_transform'], $value ); + } + + $orm_args[ $alias ] = $value; + } + + if ( null !== $fields ) { + /* + * Only keep wanted fields, the filtering is done on the resolved aliases, + * from the perspective of the client code that might ignore the source keys. + */ + $orm_args = $whitelist + ? array_intersect_key( $orm_args, array_combine( $fields, $fields ) ) + : array_diff_key( $orm_args, array_combine( $fields, $fields ) ); + } + + /** + * Filters the ORM arguments produced from the current context. + * + * @since 4.9.5 + * + * @param array $orm_args The ORM args produced from the current context. + * @param bool $is_global_context Whether the context producing the ORM args is the global one + * or a modified clone of it. + * @param Tribe__Context The context object producing the ORM args. + */ + $orm_args = apply_filters( 'tribe_context_orm_args', $orm_args, $is_global_context, $this ); + + if ( $is_global_context ) { + /** + * Filters the ORM arguments produced from the global context. + * + * While the `tribe_context_orm_args` filter will apply to all contexts producing ORM + * args this filter will only apply to the global context. + * + * @since 4.9.5 + * + * @param array $orm_args The ORM args produced from the global context. + * @param Tribe__Context The global context object producing the ORM args. + */ + $orm_args = apply_filters( 'tribe_global_context_orm_args', $orm_args, $this ); + } + + return $orm_args; + } + + /** + * Sets some locations that can only be set at runtime. + * + * Using a flag locations are added only once per request. + * + * @since 4.9.8 + */ + protected function populate_locations() { + if ( static::$did_populate_locations ) { + return; + } + + // To improve the class readability, and as a small optimization, locations are loaded from a file. + static::$locations = include __DIR__ . '/Context/locations.php'; + + /** + * Filters the locations registered in the Context. + * + * @since 4.9.8 + * + * @param array $locations An array of locations registered on the Context object. + */ + static::$locations = apply_filters( 'tribe_context_locations', static::$locations, $this ); + + static::$did_populate_locations = true; + } + + /** + * Just dont... + * Unless you very specifically know what you are doing **DO NOT USE THIS METHOD**! + * + * Please keep in mind this will set force the context to repopulate all locations for the whole request, expensive + * and very dangerous overall since it could affect all this things we hold dear in the request. + * + * With great power comes great responsibility: think a lot before using this. + * + * @since 4.13.0 + */ + public function dangerously_repopulate_locations() { + static::$did_populate_locations = false; + $this->populate_locations(); + } + + /** + * Reads (gets) the value applying one or more filters. + * + * @since 4.9.8 + * + * @param array $filters The list of filters to apply, in order. + * @param mixed $default The default value to return. + * + * @return mixed The first valid value found or the default value. + */ + public function filter( array $filters, $default ) { + foreach ( $filters as $filter ) { + $the_value = apply_filters( $filter, $default ); + if ( $the_value !== $default ) { + return $the_value; + } + } + + return $default; + } + + /** + * Reads (gets) the value reading it from a query var parsed from the global `$wp` object. + * + * @since 4.9.8 + * + * @param array $vars The list of variables to read, in order. + * @param mixed $default The default value to return if no variable was parsed. + * + * @return mixed The first valid value found or the default value. + */ + public function wp_parsed( array $vars, $default ) { + /** @var WP $wp */ + global $wp; + + if ( ! $wp instanceof WP || empty($wp->query_vars) ) { + return $default; + } + + return Arr::get_first_set( (array) $wp->query_vars, $vars, $default ); + } + + /** + * Reads (gets) the value reading it from a query var parsed from the query matched by the global `$wp` object. + * + * @since 4.9.8 + * + * @param array $vars The list of variables to read, in order. + * @param mixed $default The default value to return if no variable was parsed. + * + * @return mixed The first valid value found or the default value. + */ + public function wp_matched_query( array $vars, $default ) { + /** @var WP $wp */ + global $wp; + + if ( ! $wp instanceof WP || empty( $wp->matched_query ) ) { + return $default; + } + + parse_str( $wp->matched_query, $query_vars ); + + return Arr::get_first_set( (array) $query_vars, $vars, $default ); + } + + /** + * Maps an input array to the corresponding read locations. + * + * The resulting array can be used as input for the `alter_values` method. + * The main use of this method is to leverage the Context knowledge of the read locations, and their types, to + * "translate" an array of values to an array of valid read sources. As an example this is useful to "translate" + * the locations to an array of query vars: + * $input = [ 'event_display' => 'some-view', 'event_date' => '2018-01-03' ]; + * $query_args = tribe_context()->map_to_read( $input, Tribe__Context::REQUEST_VAR ); + * $url = add_query_arg( $query_args, home_url() ); + * + * @since 4.9.11 + * + * @param array $input An associative array of values in the shape `[ => ]`; + * where `location` is the name of the location registered in the Context + * locations. + * @param string|array|null $types A white-list of read location types to include in the mapped output; + * `null` + * means all types are allowed. + * @param bool $passthru Whether to pass unknown locations in the output or not; if `false` then + * any input key that's not a context location will not appear in the output; + * defaults to `false` to remove unknown locations from the output. + * + * @return array An associative array in the shape `[ => ]`. Since some read + * locations could have multiple sources the number of elements in this array will likely NOT be the + * same as the number of elements in the input array. When a read location as more than 1 source then + * the value will be duplicated, in the output array, to both sources. + */ + public function map_to_read( array $input, $types = null, $passthru = false ) { + $mapped = []; + $processed = []; + $types = null !== $types ? (array) $types : null; + + $locations = $this->get_locations(); + + // Take the current read locations + foreach ( $locations as $key => $location ) { + if ( ! isset( $location['read'], $input[ $key ] ) ) { + continue; + } + + $processed[] = $key; + + foreach ( $location['read'] as $type => $name ) { + if ( null !== $types && ! in_array( $type, $types, true ) ) { + continue; + } + + foreach ( (array) $name as $destination ) { + $mapped[ $destination ] = $input[ $key ]; + } + } + } + + if ( $passthru ) { + $mapped = array_merge( + $mapped, + array_diff_key( $input, array_keys( $locations ), array_combine( $processed, $processed ) ) + ); + } + + ksort( $mapped ); + + return $mapped; + } + + /** + * Translates sub-locations to their respective location key. + * + * This method leverages the inherent knowledge of aliases stored in the Context locations to "translate" a + * sub-location to its location key. + * E.g. assume the `car` location is `read` from the [ 'carriage', 'vehicle', 'transport_mean' ] query var; calling + * `$context->populate_aliases( [ 'vehicle' => 'hyunday' ], 'read', Context::QUERY_VAR )` would yield + * `[ 'car' => 'hyunday' ]`. + * + * @since 4.9.12 + * + * @param array $values An associative array of value to use as "masters" to populate the aliases. + * @param string $type The type of Context location to use, e.g. `Tribe__Context::QUERY_VAR`. + * @param string $direction The direction to use for the location, one of `read` or `write`. + * + * @return array The original array, merged with the populated values. + */ + public function translate_sub_locations( array $values, $type, $direction = 'read' ) { + if ( ! in_array( $direction, [ 'read', 'write' ], true ) ) { + throw new \InvalidArgumentException( + "Direction must be one of `read` or `write`; `{$direction}` is not valid." + ); + } + + $filled = []; + $locations = $this->get_locations(); + $matching_locations = array_filter( $locations, static function ( $location ) use ( $type, $direction ) { + return isset( $location[ $direction ][ $type ] ); + } ); + + foreach ( $matching_locations as $key => $location ) { + $entry = (array)$location[ $direction ][ $type ]; + $found = array_intersect( array_keys( $values ), array_merge( $entry, [ $key ] ) ); + if ( $found ) { + $filled[ $key ] = $values[ reset( $found ) ]; + } + } + + return $filled; + } + + /** + * Convenience method to get and check if a location has a truthy value or not. + * + * @since 4.9.18 + * + * @param string $flag_key The location to check. + * @param bool $default The default value to return if the location is not set. + * + * @return bool Whether the location has a truthy value or not. + */ + public function is( $flag_key, $default = false ) { + $val = $this->get( $flag_key, $default ); + + return ! empty( $val ) || tribe_is_truthy( $val ); + } + + /** + * Reads the value from one callback, passing it the value of another Context location. + * + * @since 4.9.18 + * + * @param array $location_and_callback An array of two elements: the location key and the callback to call on the + * location value. The callback will receive the location value as argument. + * + * @return mixed The return value of the callback, called on the location value. + */ + public function location_func( array $location_and_callback ) { + list( $location, $callback ) = $location_and_callback; + + return $callback( $this->get( $location ) ); + } + + /** + * Checks whether the current request is a REST API one or not. + * + * @since 4.9.20 + * + * @return bool Whether the current request is a REST API one or not. + */ + public function doing_rest() { + return defined( 'REST_REQUEST' ) && REST_REQUEST; + } + + /** + * Reads the value from one or more global WP_Query object methods. + * + * @since 4.9.20 + * + * @param array $query_vars The list of query methods to call, in order. + * @param mixed $default The default value to return if no method was defined on the global `WP_Query` object. + * + * @return mixed The first valid value found or the default value. + */ + public function query_method( $methods, $default ) { + global $wp_query; + $found = $default; + + foreach ( $methods as $method ) { + $this_value = $wp_query instanceof WP_Query && method_exists( $wp_query, $method ) + ? call_user_func( [ $wp_query, $method ] ) + : static::NOT_FOUND; + + if ( static::NOT_FOUND !== $this_value ) { + return $this_value; + } + } + + return $found; + } + + /** + * Whether the current request is for a PHP-rendered initial state or not. + * + * This method is a shortcut to make sure we're not doing an AJAX, REST or Cron request. + * + * @since 4.9.20 + * + * @return bool Whether the current request is for a PHP-rendered initial state or not. + */ + public function doing_php_initial_state() { + return ! $this->doing_rest() && ! $this->doing_ajax() && ! $this->doing_cron(); + } + + /** + * Returns the first key, if there are many, that will be used to read a location. + * + * The type ar + * + * @since 4.9.20 + * + * @param string $location The location to get the read key for. + * @param string|null $type The type of read location to return the key for; default to `static::REQUEST_VAR`. + * + * @return string Either the first key for the type of read location, or the input location if not found. + */ + public function get_read_key_for( $location, $type = null ) { + $type = $type ?: static::REQUEST_VAR; + $locations = $this->get_locations(); + if ( isset( $locations[ $location ]['read'][ $type ] ) ) { + $keys = (array) $locations[ $location ]['read'][ $type ]; + return reset( $keys ); + } + + return $location; + } + + /** + * Safely set the value of a group of locations. + * + * This method can only augment the context, without altering it; it can only add new values. + * + * @since 4.10.2 + * + * @param array|string $values The values to set, if not already set or the key of the value to set, requires + * the `$value` to be passed. + * @param mixed|null $value The value to set for the key, this parameter will be ignored if the `$values_or_key` + * parameter is not a string. + */ + public function safe_set( $values_or_key, $value = null ) { + $values = func_num_args() === 2 + ? [ $values_or_key => $value ] + : $values_or_key; + + foreach ( $values as $key => $val ) { + if ( static::NOT_FOUND !== $this->get( $key, static::NOT_FOUND ) ) { + continue; + } + $this->request_cache[ $key ] = $val; + } + } +} diff --git a/tribe-common/src/Tribe/Context/locations.php b/tribe-common/src/Tribe/Context/locations.php new file mode 100644 index 0000000000..0df3e81e23 --- /dev/null +++ b/tribe-common/src/Tribe/Context/locations.php @@ -0,0 +1,155 @@ + [ + 'read' => [ + Tribe__Context::FUNC => static function () { + return get_the_ID(); + } + ], + ], + 'permalink_structure' => [ + 'read' => [ + Tribe__Context::OPTION => [ 'permalink_structure' ], + ], + ], + 'plain_permalink' => [ + 'read' => [ + Tribe__Context::LOCATION_FUNC => [ + 'permalink_structure', + static function( $struct ){ + return empty( $struct ); + }, + ], + ], + ], + 'posts_per_page' => [ + 'read' => [ + Tribe__Context::REQUEST_VAR => 'posts_per_page', + Tribe__Context::OPTION => 'posts_per_page', + Tribe__Context::TRIBE_OPTION => [ 'posts_per_page', 'postsPerPage' ], + ], + 'write' => [ + Tribe__Context::REQUEST_VAR => 'posts_per_page', + ], + ], + 'is_main_query' => [ + 'read' => [ + Tribe__Context::FUNC => static function () { + global $wp_query; + + return $wp_query->is_main_query(); + }, + ], + 'write' => [ + Tribe__Context::FUNC => static function () { + global $wp_query, $wp_the_query; + $wp_the_query = $wp_query; + }, + ], + ], + 'paged' => [ + 'read' => [ + Tribe__Context::REQUEST_VAR => [ 'paged', 'page' ], + Tribe__Context::QUERY_VAR => [ 'paged', 'page' ], + ], + 'write' => [ + Tribe__Context::REQUEST_VAR => 'paged', + Tribe__Context::QUERY_VAR => 'paged', + ], + ], + 'page' => [ + 'read' => [ + Tribe__Context::REQUEST_VAR => [ 'page', 'paged' ], + Tribe__Context::QUERY_VAR => [ 'page', 'paged' ], + ], + 'write' => [ + Tribe__Context::REQUEST_VAR => 'page', + Tribe__Context::QUERY_VAR => 'page', + ], + ], + 'name' => [ + 'read' => [ + Tribe__Context::REQUEST_VAR => [ 'name', 'post_name' ], + Tribe__Context::WP_PARSED => [ 'name', 'post_name' ], + Tribe__Context::QUERY_VAR => [ 'name', 'post_name' ], + ], + 'write' => [ + Tribe__Context::REQUEST_VAR => [ 'name', 'post_name' ], + Tribe__Context::QUERY_VAR => [ 'name', 'post_name' ], + ], + ], + 'post_type' => [ + 'read' => [ + Tribe__Context::FUNC => static function() { + $post_type_objs = get_post_types( + [ + 'public' => true, + '_builtin' => false, + ], + 'objects' + ); + + foreach( $post_type_objs as $post_type ) { + if ( empty( $post_type->query_var ) ) { + continue; + } + + $url_value = tribe_get_request_var( $post_type->query_var, false ); + if ( empty( $url_value ) ) { + continue; + } + + return $post_type->name; + } + + return Tribe__Context::NOT_FOUND; + }, + Tribe__Context::QUERY_PROP => 'post_type', + Tribe__Context::QUERY_VAR => 'post_type', + Tribe__Context::REQUEST_VAR => 'post_type', + ], + ], + 'single' => [ + 'read' => [ Tribe__Context::QUERY_METHOD => 'is_single' ] + ], + 'taxonomy' => [ + 'read' => [ + Tribe__Context::QUERY_PROP => [ 'taxonomy' ], + Tribe__Context::QUERY_VAR => [ 'taxonomy' ], + Tribe__Context::REQUEST_VAR => [ 'taxonomy' ], + ], + ], + 'post_tag' => [ + 'read' => [ + Tribe__Context::QUERY_PROP => [ 'post_tag', 'tag' ], + Tribe__Context::QUERY_VAR => [ 'post_tag', 'tag' ], + Tribe__Context::REQUEST_VAR => [ 'post_tag', 'tag' ], + ], + ], + 'bulk_edit' => [ + 'read' => [ + Tribe__Context::REQUEST_VAR => [ 'bulk_edit' ], + ], + ], + 'inline_save' => [ + 'read' => [ + Tribe__Context::FUNC => [ + static function () { + return tribe_get_request_var( 'action', false ) === 'inline-save' + ? true + : Tribe__Context::NOT_FOUND; + } + ], + ], + ], +]; diff --git a/tribe-common/src/Tribe/Cost_Utils.php b/tribe-common/src/Tribe/Cost_Utils.php new file mode 100644 index 0000000000..8e0aec0520 --- /dev/null +++ b/tribe-common/src/Tribe/Cost_Utils.php @@ -0,0 +1,542 @@ +get_cost_regex(), trim( $cost ) ); + } + + /** + * Returns the regular expression that shold be used to identify a valid + * cost string. + * + * @return string + */ + public function get_cost_regex() { + $separators = '[\\' . implode( '\\', $this->get_separators() ) . ']?'; + $cost_regex = '(' . $separators . '([\d]+)' . $separators . '([\d]*))'; + + /** + * Filters the regular expression that will be used to identify a valid cost + * string. + * + * @param string $cost_regex + * + * @deprecated 4.3 Use `tribe_cost_regex` instead + */ + $cost_regex = apply_filters( + 'tribe_events_cost_regex', $cost_regex + ); + + /** + * Filters the regular expression that will be used to identify a valid cost + * string. + * + * @param string $cost_regex + */ + $cost_regex = apply_filters( 'tribe_cost_regex', $cost_regex ); + + return $cost_regex; + } + + /** + * Fetch the possible separators + * + * @return array + */ + public function get_separators() { + $separators = [ ',', '.' ]; + + /** + * Filters the cost string possible separators, those must be only 1 char. + * + * @param array $separators Defaults to comma (",") and period (".") + */ + return apply_filters( 'tribe_events_cost_separators', $separators ); + } + + /** + * If the cost is "0", call it "Free" + * + * @param int|float|string $cost Cost to analyze + * + * @return int|float|string + */ + public function maybe_replace_cost_with_free( $cost ) { + + $cost_with_period = $this->convert_decimal_separator( $cost ); + + if ( + is_numeric( $cost_with_period ) + && '0.00' === number_format( $cost_with_period, 2, '.', ',' ) + ) { + return esc_html__( 'Free', 'the-events-calendar' ); + } + + return $cost; + } + + /** + * Formats a cost with a currency symbol + * + * @param int|float|string $cost Cost to format + * + * return string + * @param int|WP_Post $event An event post ID or post object. + * @param string $currency_symbol + * @param string $currency_position Either "prefix" or "posfix" + * + * @return float|int|string + */ + public function maybe_format_with_currency( $cost, $event = null, $currency_symbol = null, $currency_position = null ) { + // check if the currency symbol is desired, and it's just a number in the field + // be sure to account for european formats in decimals, and thousands separators + if ( is_numeric( str_replace( $this->get_separators(), '', $cost ) ) ) { + $reverse_position = null; + // currency_position often gets passed as null or an empty string. + if ( ! empty( $currency_position ) ) { + $reverse_position = 'prefix' === $currency_position ? false : true; + } + + $cost = tribe_format_currency( $cost, $event, $currency_symbol, $reverse_position ); + } + + return $cost; + } + + /** + * @param string $original_string_cost A string cost with or without currency symbol, + * e.g. `10 - 20`, `Free` or `2$ - 4$`. + * @param array|string $merging_cost A single string cost representation to merge or an array of + * string cost representations to merge, e.g. ['Free', 10, 20, + * 'Donation'] or `Donation`. + * @param bool $with_currency_symbol Whether the output should prepend the currency symbol to the + * numeric costs or not. + * @param array $sorted_mins An array of non numeric price minimums sorted smaller to larger, + * e.g. `['Really free', 'Somewhat free', 'Free with 3 friends']`. + * @param array $sorted_maxs An array of non numeric price maximums sorted smaller to larger, + * e.g. `['Donation min $10', 'Donation min $20', 'Donation min + * $100']`. + * + * @return string|array The merged cost range. + */ + public function merge_cost_ranges( $original_string_cost, $merging_cost, $with_currency_symbol, $sorted_mins = [], $sorted_maxs = [] ) { + if ( empty( $merging_cost ) || $original_string_cost === $merging_cost ) { + return $original_string_cost; + } + + $_merging_cost = array_map( + [ $this, 'convert_decimal_separator' ], (array) $merging_cost + ); + $_merging_cost = array_map( [ $this, 'numerize_numbers' ], $_merging_cost ); + $numeric_merging_cost_costs = array_filter( $_merging_cost, 'is_numeric' ); + + $matches = []; + preg_match_all( + '!\d+(?:([' . preg_quote( $this->_supported_decimal_separators ) . '])\d+)?!', $original_string_cost, + $matches + ); + $this->_current_original_cost_separator = empty( $matches[1][0] ) ? '.' : $matches[1][0]; + $matches[0] = empty( $matches[0] ) + ? $matches[0] + : array_map( + [ + $this, + 'convert_decimal_separator', + ], + $matches[0] + ); + + $numeric_orignal_costs = empty( $matches[0] ) ? $matches[0] : array_map( + 'floatval', $matches[0] + ); + + $all_numeric_costs = array_filter( array_merge( $numeric_merging_cost_costs, $numeric_orignal_costs ) ); + $cost_min = $cost_max = false; + + $merging_mins = array_intersect( $sorted_mins, (array) $merging_cost ); + $merging_has_min = array_search( reset( $merging_mins ), $sorted_mins ); + $original_has_min = array_search( $original_string_cost, $sorted_mins ); + $merging_has_min = false === $merging_has_min ? 999 : $merging_has_min; + $original_has_min = false === $original_has_min ? 999 : $original_has_min; + $string_min_key = min( $merging_has_min, $original_has_min ); + if ( array_key_exists( $string_min_key, $sorted_mins ) ) { + $cost_min = $sorted_mins[ $string_min_key ]; + } else { + $cost_min = empty( $all_numeric_costs ) ? '' : min( $all_numeric_costs ); + } + + $merging_maxs = array_intersect( $sorted_maxs, (array) $merging_cost ); + $merging_has_max = array_search( end( $merging_maxs ), $sorted_maxs ); + $original_has_max = array_search( $original_string_cost, $sorted_maxs ); + $merging_has_max = false === $merging_has_max ? - 1 : $merging_has_max; + $original_has_max = false === $original_has_max ? - 1 : $original_has_max; + $string_max_key = max( $merging_has_max, $original_has_max ); + if ( array_key_exists( $string_max_key, $sorted_maxs ) ) { + $cost_max = $sorted_maxs[ $string_max_key ]; + } else { + $cost_max = empty( $all_numeric_costs ) ? '' : max( $all_numeric_costs ); + } + + $cost = array_filter( [ $cost_min, $cost_max ] ); + + if ( $with_currency_symbol ) { + $formatted_cost = []; + foreach ( $cost as $c ) { + $formatted_cost[] = is_numeric( $c ) ? tribe_format_currency( $c ) : $c; + } + $cost = $formatted_cost; + } + + return empty( $cost ) ? $original_string_cost : array_map( + [ $this, 'restore_original_decimal_separator' ], + $cost + ); + } + + /** + * Returns a maximum cost in a list of costs. If an array of costs is not passed in, the array of costs is fetched + * via query. + * + * @param $costs mixed Cost(s) to review for max value + * + * @return float + */ + public function get_maximum_cost( $costs = null ) { + return $this->get_cost_by_func( $costs, 'max' ); + } + + /** + * Returns a particular cost within an array of costs + * + * @param $costs mixed Cost(s) to review for max value + * @param $function string Function to use to determine which cost to return from range. Valid values: max, min + * + * @return float + */ + protected function get_cost_by_func( $costs = null, $function = 'max' ) { + if ( null === $costs ) { + $costs = $this->get_all_costs(); + } else { + $costs = (array) $costs; + } + + $costs = $this->parse_cost_range( $costs ); + + // if there's only one item, we're looking at a single event. If the cost is non-numeric, let's + // return the non-numeric cost so that value is preserved + if ( 1 === count( $costs ) && ! is_numeric( current( $costs ) ) ) { + return current( $costs ); + } + + // make sure we are only trying to get numeric min/max values + $costs = array_filter( $costs, 'is_numeric' ); + + if ( empty( $costs ) ) { + return 0; + } + + switch ( $function ) { + case 'min': + $cost = $costs[ min( array_keys( $costs ) ) ]; + break; + case 'max': + default: + $cost = $costs[ max( array_keys( $costs ) ) ]; + break; + } + + // If there isn't anything on the cost just return 0 + if ( empty( $cost ) ) { + return 0; + } + + return $cost; + } + + /** + * Parses a cost into an array of ranges. + * + * If a range isn't provided, the resulting array will hold a single + * value. + * + * @param string|array $costs A cost string or an array of cost strings. + * @param null $max_decimals The maximum number of decimal values that should be returned in the range. + * @param bool $sort Whether the returned values should be sorted. + * + * @return array An associative array of parsed costs in [ => ] format. + */ + public function parse_cost_range( $costs, $max_decimals = null, $sort = true ) { + if ( ! is_array( $costs ) && ! is_string( $costs ) ) { + return []; + } + + // make sure costs is an array + $costs = (array) $costs; + + // If there aren't any costs, return a blank array + if ( 0 === count( $costs ) ) { + return []; + } + + // Build the regular expression + $price_regex = $this->get_cost_regex(); + $max = 0; + + foreach ( $costs as &$cost ) { + // Get the required parts + if ( preg_match_all( '/' . $price_regex . '/', $cost, $matches ) ) { + $cost = reset( $matches ); + } else { + $cost = [ $cost ]; + continue; + } + + // Get the max number of decimals for the range + if ( count( $matches ) === 4 ) { + $decimals = max( array_map( 'strlen', end( $matches ) ) ); + $max = max( $max, $decimals ); + } + } + + // If we passed max decimals + if ( ! is_null( $max_decimals ) ) { + $max = max( $max_decimals, $max ); + } + + $output_costs = []; + $costs = call_user_func_array( 'array_merge', $costs ); + + foreach ( $costs as $cost ) { + $numeric_cost = str_replace( $this->get_separators(), '.', $cost ); + + if ( is_numeric( $numeric_cost ) ) { + // Creates a Well Balanced Index that will perform good on a Key Sorting method + $index = str_replace( [ '.', ',' ], '', number_format( $numeric_cost, $max ) ); + } else { + // Makes sure that we have "index-safe" string + $index = sanitize_title( $numeric_cost ); + } + + // Keep the Costs in a organizable array by keys with the "numeric" value + $output_costs[ $index ] = $cost; + } + + // Filter keeping the Keys + if ( $sort ) { + ksort( $output_costs ); + } + + return (array) $output_costs; + } + + /** + * Returns a minimum cost in a list of costs. If an array of costs is not passed in, the array of costs is fetched + * via query. + * + * @param $costs mixed Cost(s) to review for min value + * + * @return float + */ + public function get_minimum_cost( $costs = null ) { + return $this->get_cost_by_func( $costs, 'min' ); + } + + /** + * Converts the original decimal separator to ".". + * + * @param string|int $value + * + * @return string + */ + protected function convert_decimal_separator( $value ) { + return preg_replace( '/[' . preg_quote( $this->_supported_decimal_separators ) . ']/', '.', $value ); + } + + /** + * Restores the decimal separator to its original symbol. + * + * @param string $value + * + * @return string + */ + protected function restore_original_decimal_separator( $value ) { + return str_replace( '.', $this->_current_original_cost_separator, $value ); + } + + /** + * Extracts int and floats from a numeric "dirty" string like strings that might contain other symbols. + * + * E.g. "$10" will yield "10"; "23.55$" will yield "23.55". + * + * @param string|int $value + * + * @return int|float + */ + protected function numerize_numbers( $value ) { + $matches = []; + + $pattern = '/(\\d{1,}([' . $this->_supported_decimal_separators . ']\\d{1,}))/'; + + return preg_match( $pattern, $value, $matches ) ? $matches[1] : $value; + } + + /** + * Parses the currency symbol part of a cost string. + * + * @param string|array $cost A string cost, a comma separated array of string costs or an array of costs. + * + * @return false|string Either the inferred currency symbol or `false` if the currency symbol is missing or not consistent. + */ + public function parse_currency_symbol( $cost ) { + if ( empty( $cost ) ) { + return false; + } + + $original_costs = is_array( $cost ) ? $cost : preg_split( '/\\s*,\\s*/', $cost ); + $costs = $this->parse_cost_range( $original_costs, null, false ); + + if ( empty( $costs ) ) { + return false; + } + + $currency_symbols = []; + $i = 0; + foreach ( $costs as $string => $value ) { + if ( is_numeric( $string ) ) { + $currency_symbols[] = trim( str_replace( $value, '', $original_costs[ $i ] ) ); + if ( end( $currency_symbols ) !== reset( $currency_symbols ) ) { + return false; + } + } + + $i ++; + } + + return ! empty( $currency_symbols ) ? reset( $currency_symbols ) : false; + } + + /** + * Parses the currency symbol position part of a cost string. + * + * @param string|array $cost A string cost, a comma separated array of string costs or an array of costs. + * + * @return false|string Either the inferred currency symbol position or `false` if not present or not consistent. + */ + public function parse_currency_position( $cost ) { + if ( empty( $cost ) ) { + return false; + } + + $original_costs = is_array( $cost ) ? $cost : preg_split( '/\\s*,\\s*/', $cost ); + $currency_symbol = $this->parse_currency_symbol( $original_costs ); + + if ( empty( $currency_symbol ) ) { + return false; + } + + $currency_positions = []; + foreach ( $original_costs as $original_cost ) { + $currency_symbol_position = strpos( trim( $original_cost ), $currency_symbol ); + if ( false === $currency_symbol_position ) { + continue; + } + + $currency_positions[] = 0 === $currency_symbol_position ? 'prefix' : 'postfix'; + if ( end( $currency_positions ) !== reset( $currency_positions ) ) { + return false; + } + } + + return ! empty( $currency_positions ) ? reset( $currency_positions ) : false; + } + + /** + * Parses the cost value and current locale to infer decimal and thousands separators. + * + * The cost values stored in the meta table might not use the same decimal and thousands separator as the current + * locale. + * To work around this we parse the value assuming the decimal separator will be the last non-numeric symbol, + * if any. + * + * @since 4.9.12 + * + * @param string|int|float $value The cost value to parse. + * + * @return array An array containing the parsed decimal and thousands separator symbols. + */ + public function parse_separators( $value ) { + global $wp_locale; + $locale_decimal_point = $wp_locale->number_format['decimal_point']; + $locale_thousands_sep = $wp_locale->number_format['thousands_sep']; + $decimal_sep = $locale_decimal_point; + $thousands_sep = $locale_thousands_sep; + + preg_match_all( '/[\\.,]+/', $value, $matches ); + + if ( ! empty( $matches[0] ) ) { + $matched_separators = $matches[0]; + if ( count( array_unique( $matched_separators ) ) > 1 ) { + // We have both, the decimal separator will be the last non-numeric symbol. + $decimal_sep = end( $matched_separators ); + $thousands_sep = reset( $matched_separators ); + } else { + /* + * We only have one, we can assume it's the decimal separator if it comes before a number of numeric + * symbols that is not exactly 3. If there are exactly 3 number after the symbols we fall back on the + * locale; we did our best and cannot guess any further. + */ + $frags = explode( end( $matched_separators ), $value ); + if ( strlen( end( $frags ) ) !== 3 ) { + $decimal_sep = end( $matched_separators ); + $thousands_sep = $decimal_sep === $locale_decimal_point ? + $locale_thousands_sep + : $locale_decimal_point; + } + } + } + + return [ $decimal_sep, $thousands_sep ]; + } +} diff --git a/tribe-common/src/Tribe/Credits.php b/tribe-common/src/Tribe/Credits.php new file mode 100755 index 0000000000..15ae9d6fd3 --- /dev/null +++ b/tribe-common/src/Tribe/Credits.php @@ -0,0 +1,102 @@ +hook(); + } + + /** + * Hook the functionality of this class into the world + */ + public function hook() { + add_filter( 'tribe_events_after_html', [ $this, 'html_comment_credit' ] ); + add_filter( 'admin_footer_text', [ $this, 'rating_nudge' ], 1, 2 ); + } + + /** + * Add credit in HTML page source + * + * @return void + **/ + public function html_comment_credit( $after_html ) { + + if ( ! class_exists( 'Tribe__Events__Main' ) ) { + return $after_html; + } + + $html_credit = "\n\n"; + $after_html .= apply_filters( 'tribe_html_credit', $html_credit ); + return $after_html; + } + + /** + * Add ratings nudge in admin footer + * + * @param $footer_text + * + * @return string + */ + public function rating_nudge( $footer_text ) { + $admin_helpers = Tribe__Admin__Helpers::instance(); + + add_filter( 'tribe_tickets_post_types', [ $this, 'tmp_return_tribe_events' ], 99 ); + + // only display custom text on Tribe Admin Pages + if ( $admin_helpers->is_screen() || $admin_helpers->is_post_type_screen() ) { + + if ( class_exists( 'Tribe__Events__Main' ) ) { + $review_url = 'https://wordpress.org/support/plugin/the-events-calendar/reviews/?filter=5'; + + $footer_text = sprintf( + esc_html__( 'Rate %1$sThe Events Calendar%2$s %3$s', 'tribe-common' ), + '', + '', + '★★★★★' + ); + } else { + $review_url = 'https://wordpress.org/support/plugin/event-tickets/reviews/?filter=5'; + + $footer_text = sprintf( + esc_html__( 'Rate %1$sEvent Tickets%2$s %3$s', 'tribe-common' ), + '', + '', + '★★★★★' + ); + } + } + + remove_filter( 'tribe_tickets_post_types', [ $this, 'tmp_return_tribe_events' ], 99 ); + + return $footer_text; + } + + /** + * temporary function to filter event types down to only tribe-specific types + * + * This will limit the request for ratings to only those post type pages + */ + public function tmp_return_tribe_events( $unused_post_types ) { + return [ 'tribe_events' ]; + } + + /** + * @var $instance + */ + private static $instance = null; + + /** + * @return self + */ + public static function instance() { + if ( empty( self::$instance ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + +} diff --git a/tribe-common/src/Tribe/Customizer.php b/tribe-common/src/Tribe/Customizer.php new file mode 100644 index 0000000000..7ce92b9399 --- /dev/null +++ b/tribe-common/src/Tribe/Customizer.php @@ -0,0 +1,831 @@ +is_active() ) { + return; + } + + /** + * Filters the Panel ID, which is also the `wp_option` name for the Customizer settings + * + * @since 4.4 + * + * @param string $ID + * @param self $customizer + */ + $this->ID = apply_filters( 'tribe_customizer_panel_id', 'tribe_customizer', $this ); + + // Hook the Registering methods + add_action( 'customize_register', [ $this, 'register' ], 15 ); + + add_action( 'wp_print_footer_scripts', [ $this, 'print_css_template' ], 15 ); + + // front end styles from customizer + add_action( 'tribe_events_pro_widget_render', [ $this, 'inline_style' ], 101 ); + add_action( 'wp_print_footer_scripts', [ $this, 'shortcode_inline_style' ], 10 ); + add_action( 'wp_print_footer_scripts', [ $this, 'widget_inline_style' ], 10 ); + + /** + * Allows filtering the action that will be used to trigger the printing of inline scripts. + * + * By default inline scripts will be printed on the `wp_enqueue_scripts` action, but other + * plugins or later iterations might require inline styles to be printed on other actions. + * + * @since 4.12.15 + * + * @param string $inline_script_action_handle The handle of the action that will be used to try + * and attempt to print inline scripts. + */ + $print_styles_action = apply_filters( 'tribe_customizer_print_styles_action', 'wp_enqueue_scripts' ); + + add_action( $print_styles_action, [ $this, 'inline_style' ], 15 ); + + add_filter( "default_option_{$this->ID}", [ $this, 'maybe_fallback_get_option' ] ); + } + + /** + * Backwards compatibility for the old Customizer Option Save + * + * @since 4.4 + * + * @param mixed $sections + * + * @return mixed + */ + public function maybe_fallback_get_option( $sections ) { + // Return if there is something there + if ( ! empty( $sections ) ) { + return $sections; + } + + return get_option( 'tribe_events_pro_customizer', [] ); + } + + /** + * Loads a Section to the Customizer on The Events Calendar's Panel + * + * @since 4.4 + * + * @param object $section An Object that extends the Abstract `Tribe__Customizer__Section` + * + * @return bool + */ + public function load_section( $section ) { + // You can only add a section if it extends the abstract Section + if ( ! is_object( $section ) || ! in_array( 'Tribe__Customizer__Section', class_parents( $section ) ) ) { + return false; + } + + // Add the Section + // Enforces the usage of `$instance->ID` + $this->sections_class[ $section->ID ] = $section; + + return true; + } + + /** + * Fetches all Section Classes + * + * @since 4.4 + * + * @return array + */ + public function get_loaded_sections() { + /** + * Allow developers to filter Classes from Customizer Sections + * + * @deprecated + * @since 4.0 + * + * @param array $selection_class + * @param self $customizer + */ + $this->sections_class = apply_filters( 'tribe_events_pro_customizer_sections_class', $this->sections_class, $this ); + + /** + * Allow developers to filter Classes from Customizer Sections + * + * @since 4.4 + * + * @param array $selection_class + * @param self $customizer + */ + $this->sections_class = apply_filters( 'tribe_customizer_sections_class', $this->sections_class, $this ); + + return $this->sections_class; + } + + /** + * A easy way to check if customize is active + * + * @since 4.2.2 + * + * @return boolean + */ + public function is_active() { + /** + * Allows Developers to completely deactivate Events Calendar Customizer + * + * @deprecated + * + * @param boolean $is_active + */ + $is_active = apply_filters( 'tribe_events_pro_customizer_is_active', true ); + + /** + * Allows Developers to completely deactivate Events Calendar Customizer + * + * @param boolean $is_active + */ + return apply_filters( 'tribe_customizer_is_active', true ); + } + + /** + * A method to easily search on an array + * + * @since 4.0 + * + * @param array $variable Variable to be searched + * @param array $indexes The index that the method will try to retrieve + * @param mixed $default If the variable doesn't exist, what is the default + * + * @return mixed Return the variable based on the index + */ + public static function search_var( $variable = null, $indexes = [], $default = null ) { + if ( is_object( $variable ) ) { + $variable = (array) $variable; + } + + if ( ! is_array( $variable ) ) { + return $variable; + } + + foreach ( (array) $indexes as $index ) { + if ( ! is_array( $variable ) || ! isset( $variable[ $index ] ) ) { + $variable = $default; + break; + } + + $variable = $variable[ $index ]; + } + + return $variable; + } + + /** + * Get an option from the database, using index search you can retrieve the full panel, a section or even a setting + * + * @param array $search Index search, array( 'section_name', 'setting_name' ) + * @param mixed $default The default, if the requested variable doesn't exits + * @return mixed The requested option or the default + */ + public function get_option( $search = null, $default = null ) { + $sections = get_option( $this->ID, $default ); + + foreach ( $this->get_loaded_sections() as $section ) { + /** + * Allow filtering the defaults for each settings to be filtered before the Ghost options to be set + * + * @deprecated + * @since 4.0 + * + * @param array $defaults + */ + $defaults[ $section->ID ] = apply_filters( "tribe_events_pro_customizer_section_{$section->ID}_defaults", [] ); + + /** + * Allow filtering the defaults for each settings to be filtered before the Ghost options to be set + * + * @since 4.4 + * + * @param array $defaults + */ + $settings = isset( $sections[ $section->ID ] ) ? $sections[ $section->ID ] : []; + $defaults[ $section->ID ] = apply_filters( "tribe_customizer_section_{$section->ID}_defaults", $settings ); + $sections[ $section->ID ] = wp_parse_args( $settings, $defaults[ $section->ID ] ); + } + + /** + * Allows Ghost Options to be inserted + * + * @deprecated + * @since 4.0 + * + * @param array $sections + * @param array $search + */ + $sections = apply_filters( 'tribe_events_pro_customizer_pre_get_option', $sections, $search ); + + /** + * Allows Ghost Options to be inserted + * + * @since 4.4 + * + * @param array $sections + * @param array $search + */ + $sections = apply_filters( 'tribe_customizer_pre_get_option', $sections, $search ); + + // Search on the Array + if ( ! is_null( $search ) ) { + $option = self::search_var( $sections, $search, $default ); + } else { + $option = $sections; + } + + /** + * Apply Filters After finding the variable + * + * @since 4.4 + * + * @param mixed $option + * @param array $search + * @param array $sections + */ + $option = apply_filters( 'tribe_customizer_get_option', $option, $search, $sections ); + + return $option; + } + + /** + * Check if the option exists, this method is used allow only sections that were saved to be applied. + * + * @param strings Using the following structure: self::has_option( 'section_name', 'setting_name' ); + * + * @return boolean Whether the option exists in the database + */ + public function has_option() { + $search = func_get_args(); + $option = self::get_option(); + $real_option = get_option( $this->ID, [] ); + + // Get section and Settings based on keys + $section = reset( $search ); + $setting = end( $search ); + + if ( empty( $real_option ) || empty( $real_option[ $section ] ) ) { + return false; + } + + // Search on the Array + if ( ! is_null( $search ) ) { + $option = self::search_var( $option, $search, null ); + } + + return ! empty( $option ); + } + + /** + * Print the CSS for the customizer on `wp_print_footer_scripts` + * + * @since 4.12.6 Moved the template building code to the `get_styles_scripts` method. + * + * @return void + */ + public function print_css_template() { + + //Only load in Customizer + if ( ! is_customize_preview() ) { + return false; + } + + echo $this->get_styles_scripts(); + } + + /** + * Print the CSS for the customizer for shortcodes. + * + * @since 4.12.6 + */ + public function shortcode_inline_style() { + /** + * Whether customizer styles should print for shortcodes or not. + * + * @since 4.12.6 + * + * @param boolean $should_print Whether the inline styles should be printed on screen. + */ + $should_print = apply_filters( 'tribe_customizer_should_print_shortcode_customizer_styles', false ); + + if ( empty( $should_print ) ) { + return; + } + + $this->inline_style(); + } + + /** + * Print the CSS for the customizer for widgets. + * + * @since 4.12.14 + */ + public function widget_inline_style() { + /** + * Whether customizer styles should print for widgets or not. + * + * @since 4.12.14 + * + * @param boolean $should_print Whether the inline styles should be printed on screen. + */ + $should_print = apply_filters( 'tribe_customizer_should_print_widget_customizer_styles', false ); + + if ( empty( $should_print ) ) { + return; + } + + $this->inline_style(); + } + + /** + * Print the CSS for the customizer using wp_add_inline_style + * + * @since 4.12.15 Added the `$force` parameter to force the print of the style inline. + * + * @param bool $force Whether to ignore the context to try and print the style inline, or not. + */ + public function inline_style( $force = false ) { + // Only load once on front-end. + if ( ! $force && ( is_customize_preview() || is_admin() || $this->inline_style ) ) { + return false; + } + + /** + * Use this filter to add more CSS, using Underscore Template style + * + * @since 4.4 + * + * @link http://underscorejs.org/#template + * + * @param string $template + */ + $css_template = trim( apply_filters( 'tribe_customizer_css_template', '' ) ); + + // If we don't have anything on the customizer don't print empty styles + if ( empty( $css_template ) ) { + return false; + } + + $sheets = [ + 'tribe-common-full-style', + ]; + + /** + * Allow plugins to add themselves to this list. + * + * @since 4.12.1 + * + * @param array $sheets An array of sheets to search for. + * @param string $css_template String containing the inline css to add. + */ + $sheets = apply_filters( 'tribe_customizer_inline_stylesheets', $sheets, $css_template ); + + if ( empty( $sheets ) ) { + return false; + } + + // Add customizer styles inline with the latest stylesheet that is enqueued. + foreach ( array_reverse( $sheets ) as $sheet ) { + if ( wp_style_is( $sheet ) ) { + $inline_style = wp_strip_all_tags( $this->parse_css_template( $css_template ) ); + + /** + * Fires before a style is, possibly, printed inline depending on the stylesheet. + * + * @since 4.12.15 + * + * @param string $sheet The handle of the stylesheet the style will be printed inline for. + * @param string $inline_style The inline style contents, as they will be printed on the page. + */ + do_action( 'tribe_customizer_before_inline_style', $sheet, $inline_style ); + + // Just print styles if doing 'wp_print_footer_scripts' action. + $just_print = (bool) doing_action( 'wp_print_footer_scripts' ); + + if ( $just_print ) { + printf( + "\n", + esc_attr( $sheet ), + $inline_style + ); + } else { + wp_add_inline_style( $sheet, $inline_style ); + } + + $this->inline_style = true; + + break; + } + } + } + + /** + * Replaces the Settings using the Underscore templating strings + * + * @param string $template The template variable, that we will look to replace the variables + * @return string A Valid css after replacing the variables + */ + private function parse_css_template( $template ) { + $css = $template; + $sections = $this->get_option(); + + $search = []; + $replace = []; + + foreach ( $sections as $section => $settings ) { + if ( ! is_array( $settings ) ) { + continue; + } + foreach ( $settings as $setting => $value ) { + $index = [ $section, $setting ]; + + // Add search based on Underscore template + $search[] = '<%= ' . implode( '.', $index ) . ' %>'; + + // Get the Replace value + $replace[] = $value; + } + } + + // Finally Str replace + return str_replace( $search, $replace, $css ); + } + + /** + * Method to start setting up the Customizer Section and Fields + * + * @since 4.0 + * + * @param WP_Customize_Manager $customizer WordPress Customizer variable + * @return void + */ + public function register( WP_Customize_Manager $customizer ) { + // Set the Cutomizer on a class variable + $this->manager = $customizer; + + /** + * Allow users to filter the Panel + * + * @since 4.4 + * + * @param WP_Customize_Panel $panel + * @param Tribe__Customizer $customizer + */ + $this->panel = apply_filters( 'tribe_customizer_panel', $this->register_panel(), $this ); + + /** + * Filter the Sections within our Panel before they are added to the Customize Manager + * + * @since 4.4 + * + * @param array $sections + * @param Tribe__Customizer $customizer + */ + $this->sections = apply_filters( 'tribe_customizer_pre_sections', $this->sections, $this ); + + foreach ( $this->sections as $id => $section ) { + $this->sections[ $id ] = $this->register_section( $id, $section ); + + /** + * Allows people to Register and de-register the method to register more Fields + * + * @since 4.4 + * @since 4.12.15 Add Customizer instance as a parameter. + * + * @param array $section + * @param WP_Customize_Manager $manager + * @param Tribe__Customizer $customizer The current customizer instance. + */ + do_action( "tribe_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager, $this ); + } + + /** + * Filter the Sections within our Panel, now using the actual WP_Customize_Section + * + * @since 4.4 + * + * @param array $sections + * @param Tribe__Customizer $customizer + */ + $this->sections = apply_filters( 'tribe_customizer_sections', $this->sections, $this ); + + // After everything is done, try to add Selective refresh + $this->maybe_selective_refresh(); + } + + /** + * Register the base Panel for Events Calendar Sections to be attached to + * + * @since 4.0 + * + * @return WP_Customize_Panel + */ + private function register_panel() { + $panel = $this->manager->get_panel( $this->ID ); + + // If the Panel already exists we leave returning it's instance + if ( ! empty( $panel ) ) { + return $panel; + } + + $panel_args = [ + 'title' => esc_html__( 'The Events Calendar', 'tribe-common' ), + 'description' => esc_html__( 'Use the following panel of your customizer to change the styling of your Calendar and Event pages.', 'tribe-common' ), + + // After `static_front_page` + 'priority' => 125, + ]; + + /** + * Filter the Panel Arguments for WP Customize + * + * @since 4.4 + * + * @param array $args + * @param string $ID + * @param Tribe__Customizer $customizer + */ + $panel_args = apply_filters( 'tribe_customizer_panel_args', $panel_args, $this->ID, $this ); + + // Actually Register the Panel + $this->manager->add_panel( $this->ID, $panel_args ); + + // Return the Panel instance + return $this->manager->get_panel( $this->ID ); + } + + /** + * Use a "alias" method to register sections to allow users to filter args and the ID + * + * @since 4.0 + * + * @param string $id The Unique section ID + * @param array $args Arguments to register the section + * + * @link https://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_section + * + * @return WP_Customize_Section + */ + public function register_section( $id, $args ) { + /** + * Filter the Section ID + * + * @since 4.4 + * + * @param string $section_id + * @param Tribe__Customizer $customizer + */ + $section_id = apply_filters( 'tribe_customizer_section_id', $id, $this ); + + // Tries to fetch the section + $section = $this->manager->get_section( $section_id ); + + // If the Panel already exists we leave returning it's instance + if ( ! empty( $section ) ) { + return $section; + } + + /** + * Filter the Section arguments, so that developers can filter arguments based on $section_id + * + * @since 4.4 + * + * @param array $args + * @param string $section_id + * @param Tribe__Customizer $customizer + */ + $section_args = apply_filters( 'tribe_customizer_section_args', $args, $section_id, $this ); + + // Don't allow sections outside of our panel + $section_args['panel'] = $this->panel->id; + + // Actually Register the Section + $this->manager->add_section( $section_id, $section_args ); + + // Return the Section instance + return $this->manager->get_section( $section_id ); + } + + /** + * Build the Setting name using the HTML format for Arrays + * + * @since 4.0 + * + * @param string $slug The actual Setting name + * @param string|WP_Customize_Section $section [description] + * + * @return string HTML name Attribute name o the setting + */ + public function get_setting_name( $slug, $section = null ) { + $name = $this->panel->id; + + // If there is a section set append it + if ( $section instanceof WP_Customize_Section ) { + $name .= '[' . $section->id . ']'; + } elseif ( is_string( $section ) ) { + $name .= '[' . $section . ']'; + } + + // Set the actual setting slug + $name .= '[' . esc_attr( $slug ) . ']'; + + return $name; + } + + + /** + * Adds a setting field name to the Array of Possible Selective refresh fields + * + * @since 4.2 + * + * @param string $name The actual Setting name + * + * @return array The list of existing Settings, the new one included + */ + public function add_setting_name( $name ) { + $this->settings[] = $name; + return $this->settings; + } + + + /** + * Using the Previously created CSS element, we not just re-create it every setting change + * + * @since 4.2 + * + * @return void + */ + public function maybe_selective_refresh() { + // Only try to apply selective refresh if it's active + if ( ! isset( $this->manager->selective_refresh ) ) { + return; + } + + foreach ( $this->settings as $name ) { + $setting = $this->manager->get_setting( $name ); + + // Skip if we don't have that setting then skip it + if ( is_null( $setting ) ) { + continue; + } + + // Skip if we already have that + if ( ! is_null( $this->manager->selective_refresh->get_partial( $name ) ) ) { + continue; + } + + // Remove the Setting + // We need this because settings are protected on the WP_Customize_Manager + $this->manager->remove_setting( $name ); + + // Change the Transport + $setting->transport = 'postMessage'; + + // Re-add the setting + // We need this because settings are protected on the WP_Customize_Manager + $this->manager->add_setting( $setting ); + + // Add the Partial + $this->manager->selective_refresh->add_partial( + $name, + [ + 'selector' => '#' . esc_attr( $this->ID . '_css' ), + 'render_callback' => [ $this, 'print_css_template' ], + ] + ); + } + } + + /** + * Builds and returns the Customizer CSS template contents. + * + * The method DOES NOT check if the current context is the one where the Customizer template should + * be printed or not; that care is left to the code calling this method. + * + * @since 4.12.6 Extracted this method from the `print_css_template` one. + * + * @return string The CSS template contents. + */ + public function get_styles_scripts() { + /** + * Use this filter to add more CSS, using Underscore Template style. + * + * @since 4.4 + * + * @param string $template The Customizer template. + * + * @link http://underscorejs.org/#template + */ + $css_template = trim( apply_filters( 'tribe_customizer_css_template', '' ) ); + + // If we don't have anything on the Customizer, then don't print empty styles. + if ( empty( $css_template ) ) { + return ''; + } + + // Prepare the customizer scripts. + $result = ''; + + // Prepare the customizer styles. + $result .= ''; + + return $result; + } +} diff --git a/tribe-common/src/Tribe/Customizer/Control.php b/tribe-common/src/Tribe/Customizer/Control.php new file mode 100644 index 0000000000..2a4dacf8e3 --- /dev/null +++ b/tribe-common/src/Tribe/Customizer/Control.php @@ -0,0 +1,20 @@ + + */ + public $settings = []; + + /** + * Render the control's content + * + * @since 4.12.14 + */ + public function render_content() { + ?> +

            + label ); ?> +

            + 10, + 'capability' => 'edit_theme_options', + 'title' => null, + 'description' => null, + ]; + + /** + * Overwrite this method to create the Fields/Settings for this section + * + * @param WP_Customize_Section $section The WordPress section instance + * @param WP_Customize_Manager $manager The WordPress Customizer Manager + * + * @return void + */ + public function register_settings( WP_Customize_Section $section, WP_Customize_Manager $manager ) { + + } + + /** + * Overwrite this method to be able to implement the CSS template related to this section + * + * @return string + */ + public function get_css_template( $template ) { + return $template; + } + + /** + * Overwrite this method to be able to creaty dynamic settings + * + * @param array $settings The actual options on the database + * @return array + */ + public function create_ghost_settings( $settings = [] ) { + return $settings; + } + + /** + * This method will be executed when the Class in Initialized + * Overwrite this method to be able to setup the arguments of your section + * + * @return void + */ + abstract public function setup(); + + /** + * Private variable holding the class Instance + * + * @since 4.0 + * + * @access private + * @var Tribe__Events__Pro__Customizer__Section + */ + private static $instances; + + /** + * Get the section slug based on the Class name + * + * @param string $class_name The name of this Class + * @return the slug for this class + */ + final public static function get_section_slug( $class_name ) { + $abstract_name = __CLASS__; + $reflection = new ReflectionClass( $class_name ); + + // Get the Slug without the Base name + $slug = str_replace( $abstract_name . '_', '', $reflection->getName() ); + + if ( false !== strpos( $slug, '__Customizer__' ) ) { + $slug = explode( '__Customizer__', $slug ); + $slug = end( $slug ); + } + + return strtolower( $slug ); + } + + /** + * Setup and Load hooks for this Section + * + * @since 4.0 + * + * @return Tribe__Customizer__Section + */ + final public function __construct() { + $slug = self::get_section_slug( get_class( $this ) ); + + // If for weird reason we don't have the Section name + if ( ! is_string( $this->ID ) ){ + $this->ID = $slug; + } + + // Allow child classes to setup the section + $this->setup(); + + // Hook the Register methods + add_action( "tribe_customizer_register_{$this->ID}_settings", [ $this, 'register_settings' ], 10, 2 ); + add_filter( 'tribe_customizer_pre_sections', [ $this, 'register' ], 10, 2 ); + + // Append this section CSS template + add_filter( 'tribe_customizer_css_template', [ $this, 'get_css_template' ], 15 ); + add_filter( "tribe_customizer_section_{$this->ID}_defaults", [ $this, 'get_defaults' ], 10 ); + + // Create the Ghost Options + add_filter( 'tribe_customizer_pre_get_option', [ $this, 'filter_settings' ], 10, 2 ); + + // By Default Invoking a new Section will load, unless `load` is set to false + if ( true === (bool) $this->load ) { + Tribe__Customizer::instance()->load_section( $this ); + } + } + + /** + * A way to apply filters when getting the Customizer options + * @return array + */ + public function get_defaults( $settings = [] ) { + // Create Ghost Options + return $this->create_ghost_settings( wp_parse_args( $settings, $this->defaults ) ); + } + + /** + * Get the Default Value requested + * @return mixed + */ + public function get_default( $key ) { + $defaults = $this->get_defaults(); + + if ( ! isset( $defaults[ $key ] ) ) { + return null; + } + + return $defaults[ $key ]; + } + + /** + * Hooks to the `tribe_customizer_pre_get_option`, this applies + * the `$this->create_ghost_settings()` method to the settings on the correct section + * + * @param array $settings Values from the Database from Customizer actions + * @param array $search Indexed search @see Tribe__Customizer::search_var() + * + * @return array + */ + public function filter_settings( $settings, $search ) { + // Exit early. + if ( null === $search ) { + return $settings; + } + + // Only Apply if getting the full options or Section + if ( is_array( $search ) && count( $search ) > 1 ) { + return $settings; + } + + if ( is_array( $search ) && count( $search ) === 1 ) { + $settings = $this->create_ghost_settings( $settings ); + } else { + $settings[ $this->ID ] = $this->create_ghost_settings( $settings[ $this->ID ] ); + } + + return $settings; + } + + /** + * Register this Section + * + * @param array $sections Array of Sections + * @param Tribe__Customizer $customizer Our internal Cutomizer Class Instance + * + * @return array Return the modified version of the Section array + */ + public function register( $sections, Tribe__Customizer $customizer ) { + $sections[ $this->ID ] = $this->arguments; + + return $sections; + } +} diff --git a/tribe-common/src/Tribe/DB_Lock.php b/tribe-common/src/Tribe/DB_Lock.php new file mode 100644 index 0000000000..cb9e1955b3 --- /dev/null +++ b/tribe-common/src/Tribe/DB_Lock.php @@ -0,0 +1,352 @@ + + */ + protected static $held_db_locks = []; + + /** + * Prunes the stale locks stored in the options table. + * + * @since 4.12.6 + * + * @return int|false The number of pruned locks, or `false` to indicate the query to prune the locks generated + * an error (logged). + */ + public static function prune_stale_db_locks() { + global $wpdb; + $prefix = static::$db_lock_option_prefix; + $affected_rows = $wpdb->query( + "DELETE FROM {$wpdb->options} + WHERE option_name LIKE '{$prefix}%' + AND option_value < ( UNIX_TIMESTAMP() - 86400 )" + ); + + if ( false === $affected_rows ) { + $log_data = [ + 'message' => 'Error while trying to prune stale db locks.', + 'error' => $wpdb->last_error + ]; + do_action( 'tribe_log', 'error', __CLASS__, $log_data ); + + return false; + } + + return (int) $affected_rows; + } + + /** + * Acquires a db lock. + * + * To ensure back-compatibility with MySQL 5.6, the lock will hash the lock key using SHA1. + * + * @since 4.12.6 + * + * @param string $lock_key The name of the db lock key to acquire. + * + * @return bool Whether the lock acquisition was successful or not. + */ + public function acquire_db_lock( $lock_key ) { + /** + * Filters the timeout, in seconds, of the database lock acquisition attempts. + * + * The timeout will not be used when locks are managed using queries in place of + * MySQL functions. + * + * @since 4.12.6 + * + * @param int $timeout The timeout, in seconds, of the lock acquisition attempt. + * @param string $lock_key The lock key the target of the acquisition attempt. + * @param static $this The object that's trying to acquire the lock by means of the trait. + */ + $timeout = apply_filters( 'tribe_db_lock_timeout', 3, $lock_key, $this ); + + if ( $this->manage_db_lock_w_mysql_functions() ) { + return $this->acquire_db_lock_w_mysql_functions( $lock_key, $timeout ); + } + + return $this->acquire_db_lock_w_queries( $lock_key ); + } + + /** + * Returns whether the traits should try to acquire and release locks using MySQL `GET_LOCK` and `RELEASE_LOCK` + * functions or not. + * + * If not, then the trait will manage the locks by means of direct SQL queries on the options table. + * + * @since 4.12.6 + * + * @return bool Whether the trait should use MySQL functions to manage the locks, or not. + */ + protected function manage_db_lock_w_mysql_functions() { + /** + * Filters whether the database lock should be acquired using the `GET_LOCK` and `RELEASE_LOCK` + * MySQL functions or not. + * + * If the filter returns a falsy value, then the trait will attempt to manage locks using `SELECT` + * and `UPDATE` queries on the options table. + * + * @since 4.12.6 + */ + return tribe_is_truthy( apply_filters( 'tribe_db_lock_use_msyql_functions', true ) ); + } + + /** + * Tries to acquire the database lock using MySQL functions (`GET_LOCK` and `IS_FREE_LOCK`). + * + * @since 4.12.6 + * + * @param string $lock_key The lock key to try and acquire the lock for. + * @param int $timeout The timeout, in seconds, to try and acquire the lock. + * + * @return bool Whether the lock was acquired or not. + */ + protected function acquire_db_lock_w_mysql_functions( $lock_key, $timeout ) { + /* + * On MySQL 5.6 if a session (a db connection) fires two requests of `GET_LOCK`, the lock is + * implicitly released and re-acquired. + * While this will not cause issues in the context of different db sessions (e.g. two diff. PHP + * processes competing for a lock), it would cause issues when the lock acquisition is attempted + * in the context of the same PHP process. + * To avoid a read-what-you-write issue in the context of the same request, we check if the lock is + * free, using `IS_FREE_LOCK` first. + */ + + global $wpdb; + + $free = $wpdb->get_var( + $wpdb->prepare( 'SELECT IS_FREE_LOCK( SHA1( %s ) )', $lock_key ) + ); + + if ( ! $free ) { + return false; + } + + $acquired = $wpdb->get_var( + $wpdb->prepare( 'SELECT GET_LOCK( SHA1( %s ),%d )', $lock_key, $timeout ) + + ); + + if ( false === $acquired ) { + // Only log errors, a failure to acquire lock is not an error. + $log_data = [ + 'message' => 'Error while trying to acquire lock.', + 'key' => $lock_key, + 'error' => $wpdb->last_error + ]; + do_action( 'tribe_log', 'error', __CLASS__, $log_data ); + + return false; + } + + return true; + } + + /** + * Tries to acquire the lock using SQL queries. + * + * This kind of lock does not support timeout to avoid sieging the MySQL server during processes + * that are most likely already stressing it. Either the lock is available the moment it's required or not. + * The method leverages `INSERT IGNORE` that it's available on MySQL 5.6 and is atomic provided one of the values + * we're trying to insert is UNIQUE or PRIMARY: `option_name` is UNIQUE in the `options` table. + * + * @since 4.12.6 + * + * @param string $lock_key The lock key to try and acquire the lock for. + * + * @return bool Whether the lock was acquired or not. + */ + protected function acquire_db_lock_w_queries( $lock_key ) { + global $wpdb; + $option_name = $this->get_db_lock_option_name( $lock_key ); + $lock_time = microtime( true ); + + //phpcs:disable + $rows_affected = $wpdb->query( + $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->options} + (option_name, option_value, autoload) + VALUES + (%s, %s, 'no')", + $option_name, + $lock_time + ) + ); + //phpcs:enable + + if ( false === $rows_affected ) { + $log_data = [ + 'message' => 'Error while trying to acquire lock with database.', + 'key' => $lock_key, + 'option_name' => $option_name, + 'error' => $wpdb->last_error, + ]; + do_action( 'tribe_log', 'error', __CLASS__, $log_data ); + + return false; + } + + /* + * The `wpdb::query()` method will return the number of affected rows when using `INSERT`. + * 1 row affected means we could INSERT and have the lock, 0 rows affected means we could not INSERT + * and have not the lock. + */ + + if ( $rows_affected ) { + self::$held_db_locks[ $lock_key ] = $lock_time; + } + + return (bool) $rows_affected; + } + + /** + * Returns the option name used to manage the lock for a key in the options table. + * + * @since 4.12.6 + * + * @param string $lock_key The lock key to build the option name for. + * + * @return string The name of the option that will be used to manage the lock for the specified key in the + * options table. + */ + public function get_db_lock_option_name( $lock_key ) { + return self::$db_lock_option_prefix . $lock_key; + } + + /** + * Releases the database lock of the record. + * + * Release a not held db lock will return `null`, not `false`. + * + * @since 4.12.6 + * + * @param string $lock_key The name of the lock to release. + * + * @return bool Whether the lock was correctly released or not. + */ + public function release_db_lock( $lock_key ) { + if ( $this->manage_db_lock_w_mysql_functions() ) { + return $this->release_db_lock_w_mysql_functions( $lock_key ); + } + + return $this->release_db_lock_w_queries( $lock_key ); + } + + /** + * Releases a DB lock held by the current database session (`$wpdb` instance) by + * using the MySQL `RELEASE_LOCK` function. + * + * @since 4.12.6 + * + * @param string $lock_key The lock key to release the lock for. + * + * @return bool Whether the lock was correctly released or not. + */ + protected function release_db_lock_w_mysql_functions( $lock_key ) { + global $wpdb; + + $released = $wpdb->query( + $wpdb->prepare( "SELECT RELEASE_LOCK( SHA1( %s ) )", $lock_key ) + ); + + if ( false === $released ) { + $log_data = [ + 'message' => 'Error while trying to release lock.', + 'key' => $lock_key, + 'error' => $wpdb->last_error + ]; + do_action( 'tribe_log', 'error', __CLASS__, $log_data ); + + return false; + } + + return true; + } + + /** + * Releases a lock using SQL queries. + * + * Note: differently from the `release_db_lock_w_mysql_functions`, this method will release the lock + * even if the current session is not the one holding the lock. + * To protect from this the trait uses a map of registered locks and when the locks where registered. + * + * @since 4.12.6 + * + * @param string $lock_key The lock key to release the lock for. + * + * @return bool Whether the lock was released or not, errors will be logged, a `false` value is returned if + * the lock was not held to begin with. + */ + protected function release_db_lock_w_queries( $lock_key ) { + if ( ! isset( self::$held_db_locks[ $lock_key ] ) ) { + // Avoid sessions that do nothold the lock to release it. + return false; + } + + global $wpdb; + $option_name = $this->get_db_lock_option_name( $lock_key ); + //phpcs:disable + $rows_affected = $wpdb->delete( + $wpdb->options, + [ 'option_name' => $option_name ], + [ '%s' ] + ); + //phpcs:enable + + if ( false === $rows_affected ) { + $log_data = [ + 'message' => 'Error while trying to release lock with database.', + 'key' => $lock_key, + 'option_name' => $option_name, + 'error' => $wpdb->last_error, + ]; + do_action( 'tribe_log', 'error', __CLASS__, $log_data ); + + return false; + } + + if ( $rows_affected ) { + // Lock successfully released. + unset( self::$held_db_locks[ $lock_key ] ); + } + + return (bool) $rows_affected; + } +} diff --git a/tribe-common/src/Tribe/Data.php b/tribe-common/src/Tribe/Data.php new file mode 100644 index 0000000000..7679fa9438 --- /dev/null +++ b/tribe-common/src/Tribe/Data.php @@ -0,0 +1,235 @@ + 'dolor' ); + * + * // by default return 'nope' when a value is not set in the data + * $data = new Tribe__Data( $my_data, 'nope' ); + * + * // set some values in the data + * $data['foo'] = 'bar'; + * $data['bar'] = 23; + * + * // fetch some values + * $var_1 = $data['foo']; // "bar" + * $var_2 = $data['bar']; // 23 + * $var_3 = $data['lorem']; // "dolor" + * $var_4 = $data['woo']; // "nope" + * + * $data->set_default( 'not found' ); + * + * $var_4 = $data['woo']; // "not found" + * + */ +class Tribe__Data implements ArrayAccess, Iterator { + /** + * @var int + */ + protected $index = 0; + + /** + * @var array The data managed by this object. + */ + protected $data; + + /** + * @var mixed The default value that will be returned when trying to get the value + * of a non set key. + */ + protected $default; + + /** + * Tribe__Data constructor. + * + * @param array|object $data An array or object of data. + * @param mixed $default The default value that should be returned if a key is not set + */ + public function __construct( $data = [], $default = false ) { + $this->data = (array) $data; + $this->default = $default; + } + + /** + * Whether a offset exists + * + * @link http://php.net/manual/en/arrayaccess.offsetexists.php + * @param mixed $offset

            + * An offset to check for. + *

            + * @return boolean true on success or false on failure. + *

            + *

            + * The return value will be casted to boolean if non-boolean was returned. + * @since 4.11.0 + */ + public function offsetExists( $offset ) { + return isset( $this->data[ $offset ] ); + } + + /** + * Offset to retrieve + * + * @link http://php.net/manual/en/arrayaccess.offsetget.php + * @param mixed $offset

            + * The offset to retrieve. + *

            + * @return mixed Can return all value types. + * @since 4.11.0 + */ + public function offsetGet( $offset ) { + return isset( $this->data[ $offset ] ) + ? $this->data[ $offset ] + : $this->default; + } + + /** + * Offset to set + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php + * @param mixed $offset

            + * The offset to assign the value to. + *

            + * @param mixed $value

            + * The value to set. + *

            + * @return void + * @since 4.11.0 + */ + public function offsetSet( $offset, $value ) { + $this->data[ $offset ] = $value; + } + + /** + * Offset to unset + * + * @link http://php.net/manual/en/arrayaccess.offsetunset.php + * @param mixed $offset

            + * The offset to unset. + *

            + * @return void + * @since 4.11.0 + */ + public function offsetUnset( $offset ) { + unset( $this->data[ $offset ] ); + } + + /** + * Gets the data this object manages. + * + * @return array + */ + public function get_data() { + return $this->data; + } + + /** + * Sets the data this object will manage. + * + * @param array $data + */ + public function set_data( array $data ) { + $this->data = $data; + } + + /** + * Gets the default value that will be returned when a key is not set. + * + * @return mixed + */ + public function get_default() { + return $this->default; + } + + /** + * Sets the default value that should be returned when a key is not set. + * + * @param mixed $default + */ + public function set_default( $default ) { + $this->default = $default; + } + + /** + * Return the current element + * + * @link http://php.net/manual/en/iterator.current.php + * @return mixed Can return any type. + * @since 4.11.0 + */ + public function current() { + $keys = array_keys( $this->data ); + + return $this->data[ $keys[ $this->index ] ]; + } + + /** + * Move forward to next element + * + * @link http://php.net/manual/en/iterator.next.php + * @return void Any returned value is ignored. + * @since 4.11.0 + */ + public function next() { + $keys = array_keys( $this->data ); + + if ( isset( $keys[ ++ $this->index ] ) ) { + return $this->data[ $keys[ $this->index ] ]; + } + + return false; + } + + /** + * Return the key of the current element + * + * @link http://php.net/manual/en/iterator.key.php + * @return mixed scalar on success, or null on failure. + * @since 4.11.0 + */ + public function key() { + $keys = array_keys( $this->data ); + + return $keys[ $this->index ]; + } + + /** + * Checks if current position is valid + * + * @link http://php.net/manual/en/iterator.valid.php + * @return boolean The return value will be casted to boolean and then evaluated. + * Returns true on success or false on failure. + * @since 4.11.0 + */ + public function valid() { + $keys = array_keys( $this->data ); + + return isset( $keys[ $this->index ] ); + } + + /** + * Rewind the Iterator to the first element + * + * @link http://php.net/manual/en/iterator.rewind.php + * @return void Any returned value is ignored. + * @since 4.11.0 + */ + public function rewind() { + $this->index = 0; + } + + /** + * Converts the data object in an array. + * + * @return array + * + * @since 4.6 + */ + public function to_array() { + return $this->get_data(); + } +} diff --git a/tribe-common/src/Tribe/Date_Utils.php b/tribe-common/src/Tribe/Date_Utils.php new file mode 100755 index 0000000000..ec5880a2b1 --- /dev/null +++ b/tribe-common/src/Tribe/Date_Utils.php @@ -0,0 +1,1598 @@ + 'Y-m-d', + 1 => 'n/j/Y', + 2 => 'm/d/Y', + 3 => 'j/n/Y', + 4 => 'd/m/Y', + 5 => 'n-j-Y', + 6 => 'm-d-Y', + 7 => 'j-n-Y', + 8 => 'd-m-Y', + 9 => 'Y.m.d', + 10 => 'm.d.Y', + 11 => 'd.m.Y', + 'm0' => 'Y-m', + 'm1' => 'n/Y', + 'm2' => 'm/Y', + 'm3' => 'n/Y', + 'm4' => 'm/Y', + 'm5' => 'n-Y', + 'm6' => 'm-Y', + 'm7' => 'n-Y', + 'm8' => 'm-Y', + 'm9' => 'Y.m', + 'm10' => 'm.Y', + 'm11' => 'm.Y', + ]; + + if ( is_null( $translate ) ) { + return $formats; + } + + return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[ static::get_datepicker_format_index() ]; + } + + /** + * As PHP 5.2 doesn't have a good version of `date_parse_from_format`, this is how we deal with + * possible weird datepicker formats not working + * + * @param string $format The weird format you are using + * @param string $date The date string to parse + * + * @return string A DB formated Date, includes time if possible + */ + public static function datetime_from_format( $format, $date ) { + // Reverse engineer the relevant date formats + $keys = [ + // Year with 4 Digits + 'Y' => [ 'year', '\d{4}' ], + + // Year with 2 Digits + 'y' => [ 'year', '\d{2}' ], + + // Month with leading 0 + 'm' => [ 'month', '\d{2}' ], + + // Month without the leading 0 + 'n' => [ 'month', '\d{1,2}' ], + + // Month ABBR 3 letters + 'M' => [ 'month', '[A-Z][a-z]{2}' ], + + // Month Name + 'F' => [ 'month', '[A-Z][a-z]{2,8}' ], + + // Day with leading 0 + 'd' => [ 'day', '\d{2}' ], + + // Day without leading 0 + 'j' => [ 'day', '\d{1,2}' ], + + // Day ABBR 3 Letters + 'D' => [ 'day', '[A-Z][a-z]{2}' ], + + // Day Name + 'l' => [ 'day', '[A-Z][a-z]{5,8}' ], + + // Hour 12h formatted, with leading 0 + 'h' => [ 'hour', '\d{2}' ], + + // Hour 24h formatted, with leading 0 + 'H' => [ 'hour', '\d{2}' ], + + // Hour 12h formatted, without leading 0 + 'g' => [ 'hour', '\d{1,2}' ], + + // Hour 24h formatted, without leading 0 + 'G' => [ 'hour', '\d{1,2}' ], + + // Minutes with leading 0 + 'i' => [ 'minute', '\d{2}' ], + + // Seconds with leading 0 + 's' => [ 'second', '\d{2}' ], + ]; + + $date_regex = "/{$keys['Y'][1]}-{$keys['m'][1]}-{$keys['d'][1]}( {$keys['H'][1]}:{$keys['i'][1]}:{$keys['s'][1]})?$/"; + + // if the date is already in Y-m-d or Y-m-d H:i:s, just return it + if ( preg_match( $date_regex, $date ) ) { + return $date; + } + + + // Convert format string to regex + $regex = ''; + $chars = str_split( $format ); + foreach ( $chars as $n => $char ) { + $last_char = isset( $chars[ $n - 1 ] ) ? $chars[ $n - 1 ] : ''; + $skip_current = '\\' == $last_char; + if ( ! $skip_current && isset( $keys[ $char ] ) ) { + $regex .= '(?P<' . $keys[ $char ][0] . '>' . $keys[ $char ][1] . ')'; + } elseif ( '\\' == $char ) { + $regex .= $char; + } else { + $regex .= preg_quote( $char ); + } + } + + $dt = []; + + // Now try to match it + if ( preg_match( '#^' . $regex . '$#', $date, $dt ) ) { + // Remove unwanted Indexes + foreach ( $dt as $k => $v ) { + if ( is_int( $k ) ) { + unset( $dt[ $k ] ); + } + } + + // We need at least Month + Day + Year to work with + if ( ! checkdate( $dt['month'], $dt['day'], $dt['year'] ) ) { + return false; + } + } else { + return false; + } + + $dt['month'] = str_pad( $dt['month'], 2, '0', STR_PAD_LEFT ); + $dt['day'] = str_pad( $dt['day'], 2, '0', STR_PAD_LEFT ); + + $formatted = '{year}-{month}-{day}' . ( isset( $dt['hour'], $dt['minute'], $dt['second'] ) ? ' {hour}:{minute}:{second}' : '' ); + foreach ( $dt as $key => $value ) { + $formatted = str_replace( '{' . $key . '}', $value, $formatted ); + } + + return $formatted; + } + + /** + * Returns the date only. + * + * @param int|string $date The date (timestamp or string). + * @param bool $isTimestamp Is $date in timestamp format? + * @param string|null $format The format used + * + * @return string The date only in DB format. + */ + public static function date_only( $date, $isTimestamp = false, $format = null ) { + $date = $isTimestamp ? $date : strtotime( $date ); + + if ( is_null( $format ) ) { + $format = self::DBDATEFORMAT; + } + + return date( $format, $date ); + } + + /** + * Returns as string the nearest half a hour for a given valid string datetime. + * + * @since 4.10.2 + * + * @param string $date Valid DateTime string. + * + * @return string Rounded datetime string + */ + public static function round_nearest_half_hour( $date ) { + $date_object = static::build_date_object( $date ); + $rounded_minutes = floor( $date_object->format( 'i' ) / 30 ) * 30; + + return $date_object->format( 'Y-m-d H:' ) . $rounded_minutes . ':00'; + } + + /** + * Returns the time only. + * + * @param string $date The date. + * + * @return string The time only in DB format. + */ + public static function time_only( $date ) { + $date = is_numeric( $date ) ? $date : strtotime( $date ); + return date( self::DBTIMEFORMAT, $date ); + } + + /** + * Returns the hour only. + * + * @param string $date The date. + * + * @return string The hour only. + */ + public static function hour_only( $date ) { + $date = is_numeric( $date ) ? $date : strtotime( $date ); + return date( self::HOURFORMAT, $date ); + } + + /** + * Returns the minute only. + * + * @param string $date The date. + * + * @return string The minute only. + */ + public static function minutes_only( $date ) { + $date = is_numeric( $date ) ? $date : strtotime( $date ); + return date( self::MINUTEFORMAT, $date ); + } + + /** + * Returns the meridian (am or pm) only. + * + * @param string $date The date. + * + * @return string The meridian only in DB format. + */ + public static function meridian_only( $date ) { + $date = is_numeric( $date ) ? $date : strtotime( $date ); + return date( self::MERIDIANFORMAT, $date ); + } + + /** + * Returns the number of seconds (absolute value) between two dates/times. + * + * @param string $date1 The first date. + * @param string $date2 The second date. + * + * @return int The number of seconds between the dates. + */ + public static function time_between( $date1, $date2 ) { + return abs( strtotime( $date1 ) - strtotime( $date2 ) ); + } + + /** + * The number of days between two arbitrary dates. + * + * @param string $date1 The first date. + * @param string $date2 The second date. + * + * @return int The number of days between two dates. + */ + public static function date_diff( $date1, $date2 ) { + // Get number of days between by finding seconds between and dividing by # of seconds in a day + $days = self::time_between( $date1, $date2 ) / ( 60 * 60 * 24 ); + + return $days; + } + + /** + * Returns the last day of the month given a php date. + * + * @param int $timestamp THe timestamp. + * + * @return string The last day of the month. + */ + public static function get_last_day_of_month( $timestamp ) { + $curmonth = date( 'n', $timestamp ); + $curYear = date( 'Y', $timestamp ); + $nextmonth = mktime( 0, 0, 0, $curmonth + 1, 1, $curYear ); + $lastDay = strtotime( date( self::DBDATETIMEFORMAT, $nextmonth ) . ' - 1 day' ); + + return date( 'j', $lastDay ); + } + + /** + * Returns true if the timestamp is a weekday. + * + * @param int $curDate A timestamp. + * + * @return bool If the timestamp is a weekday. + */ + public static function is_weekday( $curdate ) { + return in_array( date( 'N', $curdate ), [ 1, 2, 3, 4, 5 ] ); + } + + /** + * Returns true if the timestamp is a weekend. + * + * @param int $curDate A timestamp. + * + * @return bool If the timestamp is a weekend. + */ + public static function is_weekend( $curdate ) { + return in_array( date( 'N', $curdate ), [ 6, 7 ] ); + } + + /** + * Gets the last day of the week in a month (ie the last Tuesday). Passing in -1 gives you the last day in the month. + * + * @param int $curdate A timestamp. + * @param int $day_of_week The index of the day of the week. + * + * @return int The timestamp of the date that fits the qualifications. + */ + public static function get_last_day_of_week_in_month( $curdate, $day_of_week ) { + $nextdate = mktime( date( 'H', $curdate ), date( 'i', $curdate ), date( 's', $curdate ), date( 'n', $curdate ), self::get_last_day_of_month( $curdate ), date( 'Y', $curdate ) );; + + while ( date( 'N', $nextdate ) != $day_of_week && $day_of_week != - 1 ) { + $nextdate = strtotime( date( self::DBDATETIMEFORMAT, $nextdate ) . ' - 1 day' ); + } + + return $nextdate; + } + + /** + * Gets the first day of the week in a month (ie the first Tuesday). + * + * @param int $curdate A timestamp. + * @param int $day_of_week The index of the day of the week. + * + * @return int The timestamp of the date that fits the qualifications. + */ + public static function get_first_day_of_week_in_month( $curdate, $day_of_week ) { + $nextdate = mktime( 0, 0, 0, date( 'n', $curdate ), 1, date( 'Y', $curdate ) ); + + while ( ! ( $day_of_week > 0 && date( 'N', $nextdate ) == $day_of_week ) && + ! ( $day_of_week == - 1 && self::is_weekday( $nextdate ) ) && + ! ( $day_of_week == - 2 && self::is_weekend( $nextdate ) ) ) { + $nextdate = strtotime( date( self::DBDATETIMEFORMAT, $nextdate ) . ' + 1 day' ); + } + + return $nextdate; + } + + /** + * From http://php.net/manual/en/function.date.php + * + * @param int $number A number. + * + * @return string The ordinal for that number. + */ + public static function number_to_ordinal( $number ) { + $output = $number . ( ( ( strlen( $number ) > 1 ) && ( substr( $number, - 2, 1 ) == '1' ) ) ? + 'th' : date( 'S', mktime( 0, 0, 0, 0, substr( $number, - 1 ), 0 ) ) ); + + return apply_filters( 'tribe_events_number_to_ordinal', $output, $number ); + } + + /** + * check if a given string is a timestamp + * + * @param $timestamp + * + * @return bool + */ + public static function is_timestamp( $timestamp ) { + if ( is_numeric( $timestamp ) && (int) $timestamp == $timestamp && date( 'U', $timestamp ) == $timestamp ) { + return true; + } + + return false; + } + + /** + * Accepts a string representing a date/time and attempts to convert it to + * the specified format, returning an empty string if this is not possible. + * + * @param $dt_string + * @param $new_format + * + * @return string + */ + public static function reformat( $dt_string, $new_format ) { + $timestamp = self::is_timestamp( $dt_string ) ? $dt_string : strtotime( $dt_string ); + $revised = date( $new_format, $timestamp ); + + return $revised ? $revised : ''; + } + + /** + * Accepts a numeric offset (such as "4" or "-6" as stored in the gmt_offset + * option) and converts it to a strtotime() style modifier that can be used + * to adjust a DateTime object, etc. + * + * @param $offset + * + * @return string + */ + public static function get_modifier_from_offset( $offset ) { + $modifier = ''; + $offset = (float) $offset; + + // Separate out hours, minutes, polarity + $hours = (int) $offset; + $minutes = (int) ( ( $offset - $hours ) * 60 ); + $polarity = ( $offset >= 0 ) ? '+' : '-'; + + // Correct hours and minutes to positive values + if ( $hours < 0 ) $hours *= -1; + if ( $minutes < 0 ) $minutes *= -1; + + // Form the modifier string + if ( $hours >= 0 ) $modifier = "$polarity $hours hours "; + if ( $minutes > 0 ) $modifier .= "$minutes minutes"; + + return $modifier; + } + + /** + * Returns the weekday of the 1st day of the month in + * "w" format (ie, Sunday is 0 and Saturday is 6) or + * false if this cannot be established. + * + * @param mixed $month + * @return int|bool + */ + public static function first_day_in_month( $month ) { + try { + $date = new DateTime( $month ); + $day_1 = new DateTime( $date->format( 'Y-m-01 ' ) ); + return $day_1->format( 'w' ); + } + catch ( Exception $e ) { + return false; + } + } + + /** + * Returns the weekday of the last day of the month in + * "w" format (ie, Sunday is 0 and Saturday is 6) or + * false if this cannot be established. + * + * @param mixed $month + * @return int|bool + */ + public static function last_day_in_month( $month ) { + try { + $date = new DateTime( $month ); + $day_1 = new DateTime( $date->format( 'Y-m-t' ) ); + return $day_1->format( 'w' ); + } + catch ( Exception $e ) { + return false; + } + } + + /** + * Returns the day of the week the week ends on, expressed as a "w" value + * (ie, Sunday is 0 and Saturday is 6). + * + * @param int $week_starts_on + * + * @return int + */ + public static function week_ends_on( $week_starts_on ) { + if ( --$week_starts_on < 0 ) $week_starts_on = 6; + return $week_starts_on; + } + + /** + * Helper method to convert EventAllDay values to a boolean + * + * @param mixed $all_day_value Value to check for "all day" status. All day values: (true, 'true', 'TRUE', 'yes') + * + * @return boolean Is value considered "All Day"? + */ + public static function is_all_day( $all_day_value ) { + $all_day_value = trim( $all_day_value ); + + return ( + 'true' === strtolower( $all_day_value ) + || 'yes' === strtolower( $all_day_value ) + || true === $all_day_value + || 1 == $all_day_value + ); + } + + /** + * Given 2 datetime ranges, return whether the 2nd one occurs during the 1st one + * Note: all params should be unix timestamps + * + * @param integer $range_1_start timestamp for start of the first range + * @param integer $range_1_end timestamp for end of the first range + * @param integer $range_2_start timestamp for start of the second range + * @param integer $range_2_end timestamp for end of the second range + * + * @return bool + */ + public static function range_coincides( $range_1_start, $range_1_end, $range_2_start, $range_2_end ) { + + // Initialize the return value + $range_coincides = false; + + /** + * conditions: + * range 2 starts during range 1 (range 2 start time is between start and end of range 1 ) + * range 2 ends during range 1 (range 2 end time is between start and end of range 1 ) + * range 2 encloses range 1 (range 2 starts before range 1 and ends after range 1) + */ + + $range_2_starts_during_range_1 = $range_2_start >= $range_1_start && $range_2_start < $range_1_end; + $range_2_ends_during_range_1 = $range_2_end > $range_1_start && $range_2_end <= $range_1_end; + $range_2_encloses_range_1 = $range_2_start < $range_1_start && $range_2_end > $range_1_end; + + if ( $range_2_starts_during_range_1 || $range_2_ends_during_range_1 || $range_2_encloses_range_1 ) { + $range_coincides = true; + } + + return $range_coincides; + + } + + /** + * Converts a locally-formatted date to a unix timestamp. This is a drop-in + * replacement for `strtotime()`, except that where strtotime assumes GMT, this + * assumes local time (as described below). If a timezone is specified, this + * function defers to strtotime(). + * + * If there is a timezone_string available, the date is assumed to be in that + * timezone, otherwise it simply subtracts the value of the 'gmt_offset' + * option. + * + * @see strtotime() + * @uses get_option() to retrieve the value of 'gmt_offset' + * + * @param string $string A date/time string. See `strtotime` for valid formats + * + * @return int UNIX timestamp. + */ + public static function wp_strtotime( $string ) { + // If there's a timezone specified, we shouldn't convert it + try { + $test_date = new DateTime( $string ); + if ( 'UTC' != $test_date->getTimezone()->getName() ) { + return strtotime( $string ); + } + } catch ( Exception $e ) { + return strtotime( $string ); + } + + $tz = get_option( 'timezone_string' ); + if ( ! empty( $tz ) ) { + $date = date_create( $string, new DateTimeZone( $tz ) ); + if ( ! $date ) { + return strtotime( $string ); + } + $date->setTimezone( new DateTimeZone( 'UTC' ) ); + return $date->format( 'U' ); + } else { + $offset = (float) get_option( 'gmt_offset' ); + $seconds = intval( $offset * HOUR_IN_SECONDS ); + $timestamp = strtotime( $string ) - $seconds; + return $timestamp; + } + } + + /** + * Returns an array of localized full month names. + * + * @return array + */ + public static function get_localized_months_full() { + global $wp_locale; + + if ( empty( self::$localized_months ) ) { + self::build_localized_months(); + } + + if ( empty( self::$localized_months_full ) ) { + self::$localized_months_full = [ + 'January' => self::$localized_months['full']['01'], + 'February' => self::$localized_months['full']['02'], + 'March' => self::$localized_months['full']['03'], + 'April' => self::$localized_months['full']['04'], + 'May' => self::$localized_months['full']['05'], + 'June' => self::$localized_months['full']['06'], + 'July' => self::$localized_months['full']['07'], + 'August' => self::$localized_months['full']['08'], + 'September' => self::$localized_months['full']['09'], + 'October' => self::$localized_months['full']['10'], + 'November' => self::$localized_months['full']['11'], + 'December' => self::$localized_months['full']['12'], + ]; + } + + return self::$localized_months_full; + } + + /** + * Returns an array of localized short month names. + * + * @return array + */ + public static function get_localized_months_short() { + global $wp_locale; + + if ( empty( self::$localized_months ) ) { + self::build_localized_months(); + } + + if ( empty( self::$localized_months_short ) ) { + self::$localized_months_short = [ + 'Jan' => self::$localized_months['short']['01'], + 'Feb' => self::$localized_months['short']['02'], + 'Mar' => self::$localized_months['short']['03'], + 'Apr' => self::$localized_months['short']['04'], + 'May' => self::$localized_months['short']['05'], + 'Jun' => self::$localized_months['short']['06'], + 'Jul' => self::$localized_months['short']['07'], + 'Aug' => self::$localized_months['short']['08'], + 'Sep' => self::$localized_months['short']['09'], + 'Oct' => self::$localized_months['short']['10'], + 'Nov' => self::$localized_months['short']['11'], + 'Dec' => self::$localized_months['short']['12'], + ]; + } + + return self::$localized_months_short; + } + + /** + * Returns an array of localized full week day names. + * + * @return array + */ + public static function get_localized_weekdays_full() { + if ( empty( self::$localized_weekdays ) ) { + self::build_localized_weekdays(); + } + + return self::$localized_weekdays['full']; + } + + /** + * Returns an array of localized short week day names. + * + * @return array + */ + public static function get_localized_weekdays_short() { + if ( empty( self::$localized_weekdays ) ) { + self::build_localized_weekdays(); + } + + return self::$localized_weekdays['short']; + } + + /** + * Returns an array of localized week day initials. + * + * @return array + */ + public static function get_localized_weekdays_initial() { + if ( empty( self::$localized_weekdays ) ) { + self::build_localized_weekdays(); + } + + return self::$localized_weekdays['initial']; + } + + /** + * Builds arrays of localized full, short and initialized weekdays. + */ + private static function build_localized_weekdays() { + global $wp_locale; + + for ( $i = 0; $i <= 6; $i++ ) { + $day = $wp_locale->get_weekday( $i ); + self::$localized_weekdays['full'][ $i ] = $day; + self::$localized_weekdays['short'][ $i ] = $wp_locale->get_weekday_abbrev( $day ); + self::$localized_weekdays['initial'][ $i ] = $wp_locale->get_weekday_initial( $day ); + } + } + + /** + * Builds arrays of localized full and short months. + * + * @since 4.4.3 + */ + private static function build_localized_months() { + global $wp_locale; + + for ( $i = 1; $i <= 12; $i++ ) { + $month_number = str_pad( $i, 2, '0', STR_PAD_LEFT ); + $month = $wp_locale->get_month( $month_number ); + self::$localized_months['full'][ $month_number ] = $month; + self::$localized_months['short'][ $month_number ] = $wp_locale->get_month_abbrev( $month ); + } + } + + /** + * Return a WP Locale weekday in the specified format + * + * @since 4.4.3 + * + * @param int|string $weekday Day of week + * @param string $format Weekday format: full, weekday, initial, abbreviation, abbrev, abbr, short + * + * @return string + */ + public static function wp_locale_weekday( $weekday, $format = 'weekday' ) { + $weekday = trim( $weekday ); + + $valid_formats = [ + 'full', + 'weekday', + 'initial', + 'abbreviation', + 'abbrev', + 'abbr', + 'short', + ]; + + // if there isn't a valid format, bail without providing a localized string + if ( ! in_array( $format, $valid_formats ) ) { + return $weekday; + } + + if ( empty( self::$localized_weekdays ) ) { + self::build_localized_weekdays(); + } + + // if the weekday isn't numeric, we need to convert to numeric in order to + // leverage self::localized_weekdays + if ( ! is_numeric( $weekday ) ) { + $days_of_week = [ + 'Sun', + 'Mon', + 'Tue', + 'Wed', + 'Thu', + 'Fri', + 'Sat', + ]; + + $day_index = array_search( ucwords( substr( $weekday, 0, 3 ) ), $days_of_week ); + + if ( false === $day_index ) { + return $weekday; + } + + $weekday = $day_index; + } + + switch ( $format ) { + case 'initial': + $type = 'initial'; + break; + case 'abbreviation': + case 'abbrev': + case 'abbr': + case 'short': + $type = 'short'; + break; + case 'weekday': + case 'full': + default: + $type = 'full'; + break; + } + + return self::$localized_weekdays[ $type ][ $weekday ]; + } + + /** + * Return a WP Locale month in the specified format + * + * @since 4.4.3 + * + * @param int|string $month Month of year + * @param string $format Month format: full, month, abbreviation, abbrev, abbr, short + * + * @return string + */ + public static function wp_locale_month( $month, $format = 'month' ) { + $month = trim( $month ); + + $valid_formats = [ + 'full', + 'month', + 'abbreviation', + 'abbrev', + 'abbr', + 'short', + ]; + + // if there isn't a valid format, bail without providing a localized string + if ( ! in_array( $format, $valid_formats ) ) { + return $month; + } + + if ( empty( self::$localized_months ) ) { + self::build_localized_months(); + } + + // make sure numeric months are valid + if ( is_numeric( $month ) ) { + $month_num = (int) $month; + + // if the month num falls out of range, bail without localizing + if ( 0 > $month_num || 12 < $month_num ) { + return $month; + } + } else { + $months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + ]; + + // convert the provided month to a 3-character month and find it in the months array so we + // can build an appropriate month number + $month_num = array_search( ucwords( substr( $month, 0, 3 ) ), $months ); + + // if we can't find the provided month in our month list, bail without localizing + if ( false === $month_num ) { + return $month; + } + + // let's increment the num because months start at 01 rather than 00 + $month_num++; + } + + $month_num = str_pad( $month_num, 2, '0', STR_PAD_LEFT ); + + $type = ( 'full' === $format || 'month' === $format ) ? 'full' : 'short'; + + return self::$localized_months[ $type ][ $month_num ]; + } + + // DEPRECATED METHODS + // @codingStandardsIgnoreStart + /** + * Deprecated camelCase version of self::date_only + * + * @param int|string $date The date (timestamp or string). + * @param bool $isTimestamp Is $date in timestamp format? + * + * @return string The date only in DB format. + */ + public static function dateOnly( $date, $isTimestamp = false ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_only' ); + return self::date_only( $date, $isTimestamp ); + } + + /** + * Deprecated camelCase version of self::time_only + * + * @param string $date The date. + * + * @return string The time only in DB format. + */ + public static function timeOnly( $date ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_only' ); + return self::time_only( $date ); + } + + /** + * Deprecated camelCase version of self::hour_only + * + * @param string $date The date. + * + * @return string The hour only. + */ + public static function hourOnly( $date ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::hour_only' ); + return self::hour_only( $date ); + } + + /** + * Deprecated camelCase version of self::minutes_only + * + * @param string $date The date. + * + * @return string The minute only. + */ + public static function minutesOnly( $date ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::minutes_only' ); + return self::minutes_only( $date ); + } + + /** + * Deprecated camelCase version of self::meridian_only + * + * @param string $date The date. + * + * @return string The meridian only in DB format. + */ + public static function meridianOnly( $date ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::meridian_only' ); + return self::meridian_only( $date ); + } + + /** + * Returns the end of a given day. + * + * @deprecated since 3.10 - use tribe_event_end_of_day() + * @todo remove in 4.1 + * + * @param int|string $date The date (timestamp or string). + * @param bool $isTimestamp Is $date in timestamp format? + * + * @return string The date and time of the end of a given day + */ + public static function endOfDay( $date, $isTimestamp = false ) { + _deprecated_function( __METHOD__, '3.10', 'tribe_event_end_of_day' ); + + if ( $isTimestamp ) { + $date = date( self::DBDATEFORMAT, $date ); + } + + return tribe_event_end_of_day( $date, self::DBDATETIMEFORMAT ); + } + + /** + * Returns the beginning of a given day. + * + * @deprecated since 3.10 + * @todo remove in 4.1 + * + * @param int|string $date The date (timestamp or string). + * @param bool $isTimestamp Is $date in timestamp format? + * + * @return string The date and time of the beginning of a given day. + */ + public static function beginningOfDay( $date, $isTimestamp = false ) { + _deprecated_function( __METHOD__, '3.10', 'tribe_event_beginning_of_day' ); + + if ( $isTimestamp ) { + $date = date( self::DBDATEFORMAT, $date ); + } + + return tribe_event_beginning_of_day( $date, self::DBDATETIMEFORMAT ); + } + + /** + * Deprecated camelCase version of self::time_between + * + * @param string $date1 The first date. + * @param string $date2 The second date. + * + * @return int The number of seconds between the dates. + */ + public static function timeBetween( $date1, $date2 ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::time_between' ); + return self::time_between( $date1, $date2 ); + } + + /** + * Deprecated camelCase version of self::date_diff + * + * @param string $date1 The first date. + * @param string $date2 The second date. + * + * @return int The number of days between two dates. + */ + public static function dateDiff( $date1, $date2 ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::date_diff' ); + return self::date_diff( $date1, $date2 ); + } + + /** + * Deprecated camelCase version of self::get_last_day_of_month + * + * @param int $timestamp THe timestamp. + * + * @return string The last day of the month. + */ + public static function getLastDayOfMonth( $timestamp ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_month' ); + return self::get_last_day_of_month( $timestamp ); + } + + /** + * Deprecated camelCase version of self::is_weekday + * + * @param int $curDate A timestamp. + * + * @return bool If the timestamp is a weekday. + */ + public static function isWeekday( $curdate ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekday' ); + return self::is_weekday( $curdate ); + } + + /** + * Deprecated camelCase version of self::is_weekend + * + * @param int $curDate A timestamp. + * + * @return bool If the timestamp is a weekend. + */ + public static function isWeekend( $curdate ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_weekend' ); + return self::is_weekend( $curdate ); + } + + /** + * Deprecated camelCase version of self::get_last_day_of_week_in_month + * + * @param int $curdate A timestamp. + * @param int $day_of_week The index of the day of the week. + * + * @return int The timestamp of the date that fits the qualifications. + */ + public static function getLastDayOfWeekInMonth( $curdate, $day_of_week ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_last_day_of_week_in_month' ); + return self::get_last_day_of_week_in_month( $curdate, $day_of_week ); + } + + /** + * Deprecated camelCase version of self::get_first_day_of_week_in_month + * + * @param int $curdate A timestamp. + * @param int $day_of_week The index of the day of the week. + * + * @return int The timestamp of the date that fits the qualifications. + */ + public static function getFirstDayOfWeekInMonth( $curdate, $day_of_week ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::get_fist_day_of_week_in_month' ); + return self::get_first_day_of_week_in_month( $curdate, $day_of_week ); + } + + /** + * Deprecated camelCase version of self::number_to_ordinal + * + * @param int $number A number. + * + * @return string The ordinal for that number. + */ + public static function numberToOrdinal( $number ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::number_to_ordinal' ); + return self::number_to_ordinal( $number ); + } + + /** + * Deprecated camelCase version of self::is_timestamp + * + * @param $timestamp + * + * @return bool + */ + public static function isTimestamp( $timestamp ) { + _deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_timestamp' ); + return self::is_timestamp( $timestamp ); + } + + /** + * Gets the timestamp of a day in week, month and year context. + * + * Kudos to [icedwater StackOverflow user](http://stackoverflow.com/users/1091386/icedwater) in + * [his answer](http://stackoverflow.com/questions/924246/get-the-first-or-last-friday-in-a-month). + * + * Usage examples: + * "The second Wednesday of March 2015" - `get_day_timestamp( 3, 2, 3, 2015, 1)` + * "The last Friday of December 2015" - `get_day_timestamp( 5, 1, 12, 2015, -1)` + * "The first Monday of April 2016 - `get_day_timestamp( 1, 1, 4, 2016, 1)` + * "The penultimate Thursday of January 2012" - `get_day_timestamp( 4, 2, 1, 2012, -1)` + * + * @param int $day_of_week The day representing the number in the week, Monday is `1`, Tuesday is `2`, Sunday is `7` + * @param int $week_in_month The week number in the month; first week is `1`, second week is `2`; when direction is reverse + * then `1` is last week of the month, `2` is penultimate week of the month and so on. + * @param int $month The month number in the year, January is `1` + * @param int $year The year number, e.g. "2015" + * @param int $week_direction Either `1` or `-1`; the direction for the search referring to the week, defaults to `1` + * to specify weeks in natural order so: + * $week_direction `1` and $week_in_month `1` means "first week of the month" + * $week_direction `1` and $week_in_month `3` means "third week of the month" + * $week_direction `-1` and $week_in_month `1` means "last week of the month" + * $week_direction `-1` and $week_in_month `2` means "penultimmate week of the month" + * + * @return int The day timestamp + */ + public static function get_weekday_timestamp( $day_of_week, $week_in_month, $month, $year, $week_direction = 1 ) { + if ( + ! ( + is_numeric( $day_of_week ) + && is_numeric( $week_in_month ) + && is_numeric( $month ) + && is_numeric( $year ) + && is_numeric( $week_direction ) + && in_array( $week_direction, [ -1, 1 ] ) + ) + ) { + return false; + } + + if ( $week_direction > 0 ) { + $startday = 1; + } else { + $startday = date( 't', mktime( 0, 0, 0, $month, 1, $year ) ); + } + + $start = mktime( 0, 0, 0, $month, $startday, $year ); + $weekday = date( 'N', $start ); + + if ( $week_direction * $day_of_week >= $week_direction * $weekday ) { + $offset = - $week_direction * 7; + } else { + $offset = 0; + } + + $offset += $week_direction * ( $week_in_month * 7 ) + ( $day_of_week - $weekday ); + + return mktime( 0, 0, 0, $month, $startday + $offset, $year ); + } + + /** + * Unescapes date format strings to be used in functions like `date`. + * + * Double escaping happens when storing a date format in the database. + * + * @param mixed $date_format A date format string. + * + * @return mixed Either the original input or an unescaped date format string. + */ + public static function unescape_date_format( $date_format ) { + if ( ! is_string( $date_format ) ) { + return $date_format; + } + + // Why so simple? Let's handle other cases as those come up. We have tests in place! + return str_replace( '\\\\', '\\', $date_format ); + } + + /** + * Builds a date object from a given datetime and timezone. + * + * @since 4.9.5 + * + * @param string|DateTime|int $datetime A `strtotime` parse-able string, a DateTime object or + * a timestamp; defaults to `now`. + * @param string|DateTimeZone|null $timezone A timezone string, UTC offset or DateTimeZone object; + * defaults to the site timezone; this parameter is ignored + * if the `$datetime` parameter is a DatTime object. + * @param bool $with_fallback Whether to return a DateTime object even when the date data is + * invalid or not; defaults to `true`. + * + * @return DateTime|false A DateTime object built using the specified date, time and timezone; if `$with_fallback` + * is set to `false` then `false` will be returned if a DateTime object could not be built. + */ + public static function build_date_object( $datetime = 'now', $timezone = null, $with_fallback = true ) { + if ( $datetime instanceof DateTime ) { + return clone $datetime; + } + + if ( class_exists( 'DateTimeImmutable' ) && $datetime instanceof DateTimeImmutable ) { + // Return the mutable version of the date. + return Date_I18n::createFromImmutable( $datetime ); + } + + $timezone_object = null; + $datetime = empty( $datetime ) ? 'now' : $datetime; + + try { + // PHP 5.2 will not throw an exception but will generate an error. + $utc = new DateTimeZone( 'UTC' ); + $timezone_object = Tribe__Timezones::build_timezone_object( $timezone ); + + if ( self::is_timestamp( $datetime ) ) { + $timestamp_timezone = $timezone ? $timezone_object : $utc; + + return new Date_I18n( '@' . $datetime, $timestamp_timezone ); + } + + set_error_handler( 'tribe_catch_and_throw' ); + $date = new Date_I18n( $datetime, $timezone_object ); + restore_error_handler(); + } catch ( Exception $e ) { + // If we encounter an error, we need to restore after catching. + restore_error_handler(); + + if ( $timezone_object === null ) { + $timezone_object = Tribe__Timezones::build_timezone_object( $timezone ); + } + + return $with_fallback + ? new Date_I18n( 'now', $timezone_object ) + : false; + } + + return $date; + } + + /** + * Validates a date string to make sure it can be used to build DateTime objects. + * + * @since 4.9.5 + * + * @param string $date The date string that should validated. + * + * @return bool Whether the date string can be used to build DateTime objects, and is thus parse-able by functions + * like `strtotime`, or not. + */ + public static function is_valid_date( $date ) { + static $cache_var_name = __FUNCTION__; + + $cache_date_check = tribe_get_var( $cache_var_name, [] ); + + if ( isset( $cache_date_check[ $date ] ) ) { + return $cache_date_check[ $date ]; + } + + $cache_date_check[ $date ] = self::build_date_object( $date, null, false ) instanceof DateTimeInterface; + + tribe_set_var( $cache_var_name, $cache_date_check ); + + return $cache_date_check[ $date ]; + } + + /** + * Returns the DateTime object representing the start of the week for a date. + * + * @since 4.9.21 + * + * @throws Exception + * + * @param string|int|\DateTime $date The date string, timestamp or object. + * @param int|null $start_of_week The number representing the start of week day as handled by + * WordPress: `0` (for Sunday) through `6` (for Saturday). + * + * @return array An array of objects representing the week start and end days, or `false` if the + * supplied date is invalid. The timezone of the returned object is set to the site one. + * The week start has its time set to `00:00:00`, the week end will have its time set + * `23:59:59`. + */ + public static function get_week_start_end( $date, $start_of_week = null ) { + static $cache_var_name = __FUNCTION__; + + $cache_week_start_end = tribe_get_var( $cache_var_name, [] ); + + $date_obj = static::build_date_object( $date ); + $date_obj->setTime( 0, 0, 0 ); + + $date_string = $date_obj->format( static::DBDATEFORMAT ); + + // `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option. + $week_start_day = null !== $start_of_week + ? (int) $start_of_week + : (int) get_option( 'start_of_week', 0 ); + + $memory_cache_key = "{$date_string}:{$week_start_day}"; + + if ( isset( $cache_week_start_end[ $memory_cache_key ] ) ) { + return $cache_week_start_end[ $memory_cache_key ]; + } + + $cache_key = md5( + __METHOD__ . serialize( [ $date_obj->format( static::DBDATEFORMAT ), $week_start_day ] ) + ); + $cache = tribe( 'cache' ); + + if ( false !== $cached = $cache[ $cache_key ] ) { + return $cached; + } + + // `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option. + $date_day = (int) $date_obj->format( 'w' ); + + $week_offset = 0; + if ( 0 === $date_day && 0 !== $week_start_day ) { + $week_offset = 0; + } elseif ( $date_day < $week_start_day ) { + // If the current date of the week is before the start of the week, move back a week. + $week_offset = -1; + } elseif ( 0 === $date_day ) { + // When start of the week is on a sunday we add a week. + $week_offset = 1; + } + + $week_start = clone $date_obj; + + /* + * From the PHP docs, the `W` format stands for: + * - ISO-8601 week number of year, weeks starting on Monday + */ + $week_start->setISODate( + (int) $week_start->format( 'o' ), + (int) $week_start->format( 'W' ) + $week_offset, + $week_start_day + ); + + $week_end = clone $week_start; + // Add 6 days, then move at the end of the day. + $week_end->add( new DateInterval( 'P6D' ) ); + $week_end->setTime( 23, 59, 59 ); + + $week_start = static::immutable( $week_start ); + $week_end = static::immutable( $week_end ); + + $cache[ $cache_key ] = [ $week_start, $week_end ]; + $cache_week_start_end[ $memory_cache_key ] = [ $week_start, $week_end ]; + + tribe_set_var( $cache_var_name, $cache_week_start_end ); + + return [ $week_start, $week_end ]; + } + + /** + * Given a specific DateTime we determine the end of that day based on our Internal End of Day Cut-off. + * + * @since 4.11.2 + * + * @param string|DateTimeInterface $date Date that we are getting the end of day from. + * @param null|string $cutoff Which cutoff to use. + * + * @return DateTimeInterface|false Returns a DateTimeInterface when a valid date is given or false. + */ + public static function get_shifted_end_of_day( $date, $cutoff = null ) { + $date_obj = static::build_date_object( $date ); + + if ( ! $date_obj ) { + return false; + } + + $start_of_day = clone $date_obj; + $end_of_day = clone $date_obj; + + if ( empty( $cutoff ) || ! is_string( $cutoff ) || false === strpos( $cutoff, ':' ) ) { + $cutoff = tribe_get_option( 'multiDayCutoff', '00:00' ); + } + + list( $hours_to_add, $minutes_to_add ) = array_map( 'absint', explode( ':', $cutoff ) ); + + $seconds_to_add = ( $hours_to_add * HOUR_IN_SECONDS ) + ( $minutes_to_add * MINUTE_IN_SECONDS ); + if ( 0 !== $seconds_to_add ) { + $interval = static::interval( "PT{$seconds_to_add}S" ); + } + + $start_of_day->setTime( '0', '0', '0' ); + $end_of_day->setTime( '23', '59', '59' ); + + if ( 0 !== $seconds_to_add ) { + $start_of_day->add( $interval ); + $end_of_day->add( $interval ); + } + + if ( $end_of_day >= $date_obj && $date_obj >= $start_of_day ) { + return $end_of_day; + } + + $start_of_day->sub( static::interval( 'P1D' ) ); + + if ( $start_of_day < $date_obj ) { + $end_of_day->sub( static::interval( 'P1D' ) ); + } + + return $end_of_day; + } + + /** + * Given a specific DateTime we determine the start of that day based on our Internal End of Day Cut-off. + * + * @since 4.11.2 + * + * @param string|DateTimeInterface $date Date that we are getting the start of day from. + * @param null|string $cutoff Which cutoff to use. + * + * @return DateTimeInterface|false Returns a DateTimeInterface when a valid date is given or false. + */ + public static function get_shifted_start_of_day( $date, $cutoff = null ) { + $date_obj = static::build_date_object( $date ); + + if ( ! $date_obj ) { + return false; + } + + $start_of_day = clone $date_obj; + $end_of_day = clone $date_obj; + + if ( empty( $cutoff ) || ! is_string( $cutoff ) || false === strpos( $cutoff, ':' ) ) { + $cutoff = tribe_get_option( 'multiDayCutoff', '00:00' ); + } + + list( $hours_to_add, $minutes_to_add ) = array_map( 'absint', explode( ':', $cutoff ) ); + + $seconds_to_add = ( $hours_to_add * HOUR_IN_SECONDS ) + ( $minutes_to_add * MINUTE_IN_SECONDS ); + if ( 0 !== $seconds_to_add ) { + $interval = static::interval( "PT{$seconds_to_add}S" ); + } + + $start_of_day->setTime( '0', '0', '0' ); + $end_of_day->setTime( '23', '59', '59' ); + + if ( 0 !== $seconds_to_add ) { + $start_of_day->add( $interval ); + $end_of_day->add( $interval ); + } + + if ( $end_of_day <= $date_obj && $date_obj >= $start_of_day ) { + return $start_of_day; + } + + $end_of_day->sub( static::interval( 'P1D' ) ); + + if ( $end_of_day > $date_obj ) { + $start_of_day->sub( static::interval( 'P1D' ) ); + } + + return $start_of_day; + } + + /** + * Builds and returns a `DateInterval` object from the interval specification. + * + * For performance purposes the use of `DateInterval` specifications is preferred, so `P1D` is better than + * `1 day`. + * + * @since 4.10.2 + * + * @return DateInterval The built date interval object. + */ + public static function interval( $interval_spec ) { + try { + $interval = new \DateInterval( $interval_spec ); + } catch ( \Exception $e ) { + $interval = DateInterval::createFromDateString( $interval_spec ); + } + + return $interval; + } + + /** + * Builds the immutable version of a date from a string, integer (timestamp) or \DateTime object. + * + * It's the immutable version of the `Tribe__Date_Utils::build_date_object` method. + * + * @since 4.10.2 + * + * @param string|DateTime|int $datetime A `strtotime` parse-able string, a DateTime object or + * a timestamp; defaults to `now`. + * @param string|DateTimeZone|null $timezone A timezone string, UTC offset or DateTimeZone object; + * defaults to the site timezone; this parameter is ignored + * if the `$datetime` parameter is a DatTime object. + * @param bool $with_fallback Whether to return a DateTime object even when the date data is + * invalid or not; defaults to `true`. + * + * @return DateTimeImmutable|false A DateTime object built using the specified date, time and timezone; if + * `$with_fallback` is set to `false` then `false` will be returned if a + * DateTime object could not be built. + */ + static function immutable( $datetime = 'now', $timezone = null, $with_fallback = true ) { + if ( $datetime instanceof DateTimeImmutable ) { + return $datetime; + } + + if ( $datetime instanceof DateTime ) { + return Date_I18n_Immutable::createFromMutable( $datetime ); + } + + $mutable = static::build_date_object( $datetime, $timezone, $with_fallback ); + + if ( false === $mutable ) { + return false; + } + + $cache_key = md5( ( __METHOD__ . $mutable->getTimezone()->getName() . $mutable->getTimestamp() ) ); + $cache = tribe( 'cache' ); + + if ( false !== $cached = $cache[ $cache_key ] ) { + return $cached; + } + + $immutable = Date_I18n_Immutable::createFromMutable( $mutable ); + + $cache[ $cache_key ] = $immutable; + + return $immutable; + } + + /** + * Builds a date object from a given datetime and timezone. + * + * An alias of the `Tribe__Date_Utils::build_date_object` function. + * + * @since 4.10.2 + * + * @param string|DateTime|int $datetime A `strtotime` parse-able string, a DateTime object or + * a timestamp; defaults to `now`. + * @param string|DateTimeZone|null $timezone A timezone string, UTC offset or DateTimeZone object; + * defaults to the site timezone; this parameter is ignored + * if the `$datetime` parameter is a DatTime object. + * @param bool $with_fallback Whether to return a DateTime object even when the date data is + * invalid or not; defaults to `true`. + * + * @return DateTime|false A DateTime object built using the specified date, time and timezone; if `$with_fallback` + * is set to `false` then `false` will be returned if a DateTime object could not be built. + */ + public static function mutable( $datetime = 'now', $timezone = null, $with_fallback = true ) { + return static::build_date_object( $datetime, $timezone, $with_fallback ); + } + } +} diff --git a/tribe-common/src/Tribe/Db.php b/tribe-common/src/Tribe/Db.php new file mode 100644 index 0000000000..de92149ff9 --- /dev/null +++ b/tribe-common/src/Tribe/Db.php @@ -0,0 +1,38 @@ +get_results( "SHOW VARIABLES LIKE 'max_allowed_packet';", ARRAY_A ); + // default the size to 1MB + $max_size = ! empty( $max_size[0]['Value'] ) ? $max_size[0]['Value'] : 1048576; + + /** + * Filters the size of the `max_allowed_packet` setting in bytes. + * + * @since 4.7.12 + * + * @param int $max_size By default the `max_allowed_packet` from the database. + */ + $max_size = apply_filters( 'tribe_db_max_allowed_packet', $max_size ); + + return $max_size; + } +} diff --git a/tribe-common/src/Tribe/Debug.php b/tribe-common/src/Tribe/Debug.php new file mode 100644 index 0000000000..65d5579470 --- /dev/null +++ b/tribe-common/src/Tribe/Debug.php @@ -0,0 +1,59 @@ +get_option( 'debugEvents' ) ) { + $plugin = basename( dirname( Tribe__Main::instance()->plugin_path ) ); + error_log( "$plugin/common - $format: $title" ); + if ( $data && $data != '' ) { + error_log( "$plugin/common - $format: " . print_r( $data, true ) ); + } + } + } + + /** + * Static Singleton Factory Method + * + * @return Tribe__Debug + */ + public static function instance() { + static $instance; + + if ( ! $instance ) { + $class_name = __CLASS__; + $instance = new $class_name; + } + + return $instance; + } +} diff --git a/tribe-common/src/Tribe/Debug_Bar/Panels/Context.php b/tribe-common/src/Tribe/Debug_Bar/Panels/Context.php new file mode 100644 index 0000000000..162aa17407 --- /dev/null +++ b/tribe-common/src/Tribe/Debug_Bar/Panels/Context.php @@ -0,0 +1,99 @@ + + #mt-debug-bar .mt-debug-bar-title { + margin-bottom: 1em; + } + #mt-debug-bar .mt-debug-bar-context-table { + width: 100%; + font-size: 120%; + } + #mt-debug-bar .mt-debug-bar-context-table td { + padding: .5em .5em .5em 1em; + border: black solid 1px; + } + #mt-debug-bar .mt-debug-bar-context-table th { + padding: 1em; + border: black solid 1px; + } + '; + $html .= '
            '; + + $html .= '

            ' . esc_html__( 'The Events Calendar Context', 'tribe-common' ) . '

            '; + + $html .= '
            '; + $html .= '

            ' . esc_html__( 'PHP Render Context', 'tribe-common' ) . '

            '; + $html .= '
            '; + + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + + $locations = tribe_context()->get_locations(); + $context = tribe_context()->to_array(); + $orm_args = tribe_context()->get_orm_args(); + + foreach ( $locations as $key => $rw_data ) { + $orm_arg_key = Arr::get( $locations, [ $key, 'orm_arg' ], $key ); + $orm_arg_value = Arr::get( $orm_args, $orm_arg_key, null ); + + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + } + + $html .= '
            ' . __( 'Key', 'tribe-common' ) . '' . __( 'Value', 'tribe-common' ) . '' . __( 'ORM arg', 'tribe-common' ) . '' . __( 'Reads', 'tribe-common' ) . '' . __( 'Writes', 'tribe-common' ) . '
            ' . $key . '' . ( isset( $context[ $key ] ) ? print_r( $context[ $key ], true ) : 'undefined' ) . '' . ( false !== $orm_arg_key ? '' . print_r( $orm_arg_key, true ) . ' => ' . print_r( $orm_arg_value, true ) . '' : '' ) . '' . ( isset( $locations[ $key ]['read'] ) ? 'yes' : 'no' ) . '' . ( isset( $locations[ $key ]['write'] ) ? 'yes' : 'no' ) . '
            '; + $html .= ''; + $html .= '
            '; + + $state = tribe_context()->get_state(); + $html .= '

            ' . esc_attr__( 'State', + 'tribe-common' ) . '

            '; + $html .= '' . json_encode( $state, JSON_PRETTY_PRINT ) . '
            '; + + $html .= '
          '; + + echo $html; + } +} diff --git a/tribe-common/src/Tribe/Debug_Bar/Panels/Json_Ld.php b/tribe-common/src/Tribe/Debug_Bar/Panels/Json_Ld.php new file mode 100644 index 0000000000..5886ec1c67 --- /dev/null +++ b/tribe-common/src/Tribe/Debug_Bar/Panels/Json_Ld.php @@ -0,0 +1,84 @@ + + #mt-debug-bar .mt-debug-bar-title { + margin-bottom: 1em; + } + #mt-debug-bar .mt-debug-bar-section { + padding: .5em .5em .5em 1em; + } + '; + $html .= '
          '; + + $html .= '

          ' . esc_html__( 'The Events Calendar JSON-LD Data', + 'tribe-common' ) . '

          '; + + + $json_ld_data = array_filter( (array) tribe_cache()['json-ld-data'] ); + + if ( ! empty( $json_ld_data ) ) { + $html .= '
          '; + $html .= sprintf( + '
          The request produced %d JSON-LD data %s.

          ', + count( $json_ld_data ), + count( $json_ld_data ) > 1 ? 'scripts' : 'script' + ); + + $html .= '

          Copy the code below and paste it into ' . + '' . + 'Google\'s Structured Data Testing Tool' . + '' . + ' to test it using the Code Snippet option.


          '; + + foreach ( $json_ld_data as $full_entry ) { + preg_match( + '/(?^\\s*]*?>\\s*)(?.*)(?\\s<\\/script>)$/uism', + $full_entry, + $frags + ); + + if ( isset( $frags['open'], $frags['json'], $frags['close'] ) ) { + // Let's try and format it if we've got all the pieces. + $full_entry = $frags['open'] + . json_encode( json_decode( $frags['json'], true ), JSON_PRETTY_PRINT ) + . $frags['close']; + } + + $html .= sprintf( '
          %s
          ', esc_html( $full_entry ) ); + } + + $html .= '
          '; + } + + $html .= '
          '; + + echo $html; + } +} diff --git a/tribe-common/src/Tribe/Dependency.php b/tribe-common/src/Tribe/Dependency.php new file mode 100644 index 0000000000..f94079a197 --- /dev/null +++ b/tribe-common/src/Tribe/Dependency.php @@ -0,0 +1,553 @@ + 'main class name', + * 'version' => 'version num', (optional) + * 'path' => 'Path to the main plugin/bootstrap file' (optional) + * ] + */ + protected $active_plugins = []; + + /** + * A multidimensional array of active tribe plugins in the following format + * + * [ + * 'class' => 'main class name', + * 'path' => 'Path to the main plugin/bootstrap file' + * 'version' => 'version num', (optional) + * 'dependencies' => 'A multidimensional of dependencies' (optional) + * ] + */ + protected $registered_plugins = []; + + /** + * An array of class Tribe__Admin__Notice__Plugin_Download per plugin + * + * @since 4.9 + * + */ + protected $admin_messages = []; + + /** + * Adds a plugin to the active list + * + * @since 4.9 + * + * @param string $main_class Main/base class for this plugin + * @param null|string $version Version number of plugin + * @param null|string $path Path to the main plugin/bootstrap file + * @param array $dependencies An array of dependencies for a plugin + */ + public function add_registered_plugin( $main_class, $version = null, $path = null, $dependencies = [] ) { + $plugin = [ + 'class' => $main_class, + 'version' => $version, + 'path' => $path, + 'dependencies' => $dependencies, + ]; + + $this->registered_plugins[ $main_class ] = $plugin; + + if ( $path ) { + $this->admin_messages[ $main_class ] = new Tribe__Admin__Notice__Plugin_Download( $path ); + } + } + + /** + * Retrieves registered plugin array + * + * @since 4.9 + * + * @return array + */ + public function get_registered_plugins() { + return $this->registered_plugins; + } + + /** + * Adds a plugin to the active list + * + * @param string $main_class Main/base class for this plugin + * @param string $version Version number of plugin + * @param string $path Path to the main plugin/bootstrap file + */ + public function add_active_plugin( $main_class, $version = null, $path = null ) { + $plugin = [ + 'class' => $main_class, + 'version' => $version, + 'path' => $path, + ]; + + $this->active_plugins[ $main_class ] = $plugin; + } + + /** + * Retrieves active plugin array + * + * @return array + */ + public function get_active_plugins() { + return $this->active_plugins; + } + + /** + * Searches the plugin list for key/value pair and return the full details for that plugin + * + * @param string $search_key The array key this value will appear in + * @param string $search_val The value itself + * + * @return array|null + */ + public function get_plugin_by_key( $search_key, $search_val ) { + foreach ( $this->get_active_plugins() as $plugin ) { + if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) { + return $plugin; + } + } + + return null; + } + + /** + * Retrieves the plugins details by class name + * + * @param string $main_class Main/base class for this plugin + * + * @return array|null + */ + public function get_plugin_by_class( $main_class ) { + return $this->get_plugin_by_key( 'class', $main_class ); + } + + /** + * Retrieves the version of the plugin + * + * @param string $main_class Main/base class for this plugin + * + * @return string|null Version + */ + public function get_plugin_version( $main_class ) { + $plugin = $this->get_plugin_by_class( $main_class ); + + return ( isset( $plugin['version'] ) ? $plugin['version'] : null ); + } + + /** + * Checks if the plugin is active + * + * @param string $main_class Main/base class for this plugin + * + * @return bool + */ + public function is_plugin_active( $main_class ) { + return ( $this->get_plugin_by_class( $main_class ) !== null ); + } + + /** + * Searches the registered plugin list for key/value pair and return the full details for that plugin + * + * @since 4.9 + * + * @param string $search_key The array key this value will appear in + * @param string $search_val The value itself + * + * @return array|null + */ + public function get_registered_plugin_by_key( $search_key, $search_val ) { + foreach ( $this->get_registered_plugins() as $plugin ) { + if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) { + return $plugin; + } + } + + return null; + } + + /** + * Retrieves the registered plugins details by class name + * + * @since 4.9 + * + * @param string $main_class Main/base class for this plugin + * + * @return array|null + */ + public function get_registered_plugin_by_class( $main_class ) { + return $this->get_registered_plugin_by_key( 'class', $main_class ); + } + + /** + * Retrieves the version of the registered plugin + * + * @since 4.9 + * + * @param string $main_class Main/base class for this plugin + * + * @return string|null Version + */ + public function get_registered_plugin_version( $main_class ) { + $plugin = $this->get_registered_plugin_by_class( $main_class ); + + return ( isset( $plugin['version'] ) ? $plugin['version'] : null ); + } + + /** + * Checks if the plugin is active + * + * @since 4.9 + * + * @param string $main_class Main/base class for this plugin + * + * @return bool + */ + public function is_plugin_registered( $main_class ) { + return ( $this->get_registered_plugin_by_class( $main_class ) !== null ); + } + + + /** + * Checks if a plugin is active and has the specified version + * + * @since 4.9 + * + * @param string $main_class Main/base class for this plugin + * @param string $version Version to do a compare against + * @param string $compare Version compare string, defaults to >= + * + * @return bool + */ + public function is_plugin_version( $main_class, $version, $compare = '>=' ) { + //active plugin check to see if the correct version is active + if ( ! $this->is_plugin_active( $main_class ) ) { + return false; + } elseif ( version_compare( $this->get_plugin_version( $main_class ), $version, $compare ) ) { + return true; + } + + return false; + } + + /** + * Is the plugin registered with at least the minimum version + * + * @since 4.9 + * + * @param string $main_class Main/base class for this plugin + * @param string $version Version to do a compare against + * @param string $compare Version compare string, defaults to >= + * + * @return bool + */ + public function is_plugin_version_registered( $main_class, $version, $compare = '>=' ) { + //registered plugin check if addon as it tests if it might load + if ( ! $this->is_plugin_registered( $main_class ) ) { + return false; + } elseif ( version_compare( $this->get_registered_plugin_version( $main_class ), $version, $compare ) ) { + return true; + } + + return false; + } + + /** + * Checks if each plugin is active and exceeds the specified version number + * + * @param array $plugins_required Each item is a 'class_name' => 'min version' pair. Min ver can be null. + * + * @return bool + */ + public function has_requisite_plugins( $plugins_required = [] ) { + foreach ( $plugins_required as $class => $version ) { + // Return false if the plugin is not set or is a lesser version + if ( ! $this->is_plugin_active( $class ) ) { + return false; + } + + if ( null !== $version && ! $this->is_plugin_version( $class, $version ) ) { + return false; + } + } + + return true; + } + + /** + * Retrieves Registered Plugin by Class Name from Array + * + * @since 4.9 + * + * @return array|boolean + */ + public function get_registered_plugin( $class ) { + $plugins = $this->registered_plugins; + + return isset( $plugins[ $class ] ) ? $plugins[ $class ] : false; + } + + /** + * Gets all dependencies or single class requirements if parent, co, add does not exist use array as is if they + * do exist check each one in turn. + * + * @since 4.9 + * + * @param array $plugin An array of data for given registered plugin., + * @param array $dependencies An array of dependencies for a plugin. + * @param bool $addon Indicates if the plugin is an add-on for The Events Calendar or Event Tickets. + * + * @return true|int The number of failed dependency checks; `true` or `0` to indicate no checks failed. + */ + public function has_valid_dependencies( $plugin, $dependencies = [], $addon = false ) { + if ( empty( $dependencies ) ) { + return true; + } + + $failed_dependency = 0; + + $tribe_plugins = new Tribe__Plugins(); + + foreach ( $dependencies as $class => $version ) { + + // if no class for add-on + $checked_plugin = $this->get_registered_plugin( $class ); + if ( $addon && empty( $checked_plugin ) ) { + continue; + } + + $is_registered = $this->is_plugin_version_registered( $class, $version ); + if ( ! empty( $is_registered ) ) { + continue; + } + + $dependent_plugin = $tribe_plugins->get_plugin_by_class( $class ); + + $pue = $this->get_pue_from_class( $dependent_plugin['class'] ); + $has_pue_notice = $pue ? tribe( 'pue.notices' )->has_notice( $pue->pue_install_key ) : false; + + $this->admin_messages[ $plugin['class'] ]->add_required_plugin( + $dependent_plugin['short_name'], + $dependent_plugin['thickbox_url'], + $is_registered, + $version, + $addon, + $has_pue_notice + ); + $failed_dependency++; + } + + return $failed_dependency; + } + + /** + * Gets the Tribe__PUE__Checker instance of a given plugin based on the class. + * + * @since 4.9.12 + * + * @param string $class Which plugin main class we are looking for. + * + * @return Tribe__PUE__Checker + */ + public function get_pue_from_class( $class ) { + if ( ! is_string( $class ) ) { + return false; + } + + // If class doesn't exist the plugin doesn't exist. + if ( ! class_exists( $class ) ) { + return false; + } + + /** + * These callbacks are only required to prevent fatals. + * Only happen for plugin that use PUE. + */ + $callback_map = [ + 'Tribe__Events__Pro__Main' => function() { + $pue_reflection = new ReflectionClass( Tribe__Events__Pro__PUE::class ); + $values = $pue_reflection->getStaticProperties(); + $values['plugin_file'] = EVENTS_CALENDAR_PRO_FILE; + return $values; + }, + 'Tribe__Events__Filterbar__View' => function() { + $pue_reflection = new ReflectionClass( Tribe__Events__Filterbar__PUE::class ); + $values = $pue_reflection->getStaticProperties(); + $values['plugin_file'] = TRIBE_EVENTS_FILTERBAR_FILE; + return $values; + }, + 'Tribe__Events__Tickets__Eventbrite__Main' => function() { + $pue_reflection = new ReflectionClass( Tribe__Events__Tickets__Eventbrite__PUE::class ); + $values = $pue_reflection->getStaticProperties(); + $values['plugin_file'] = EVENTBRITE_PLUGIN_FILE; + return $values; + }, + ]; + + // Bail when class is not mapped. + if ( ! isset( $callback_map[ $class ] ) ) { + return false; + } + + // Use the callback to get the returns without fatals + $values = $callback_map[ $class ](); + $pue_instance = new Tribe__PUE__Checker( $values['update_url'], $values['pue_slug'], [], plugin_basename( $values['plugin_file'] ) ); + + return $pue_instance; + } + + /** + * Register a Plugin + * + * @since 4.9 + * + * @param string $file_path Full file path to the base plugin file. + * @param string $main_class The Main/base class for this plugin. + * @param string $version The plugin version. + * @param array $classes_req Any Main class files/tribe plugins required for this to run. + * @param array $dependencies an array of dependencies to check. + */ + public function register_plugin( $file_path, $main_class, $version, $classes_req = [], $dependencies = [] ) { + /** + * Filters the version string for a plugin. + * + * @since 4.9 + * + * @param string $version The plugin version number, e.g. "4.0.4". + * @param array $dependencies An array of dependencies for the plugins. These can include parent, add-on and other dependencies. + * @param string $file_path The absolute path to the plugin main file. + * @param array $classes_req Any Main class files/tribe plugins required for this to run. + */ + $version = apply_filters( "tribe_register_{$main_class}_plugin_version", $version, $dependencies, $file_path, $classes_req ); + /** + * Filters the dependencies array for a plugin. + * + * @since 4.9 + * + * @param array $dependencies An array of dependencies for the plugins. These can include parent, add-on and other dependencies. + * @param string $version The plugin version number, e.g. "4.0.4". + * @param string $file_path The absolute path to the plugin main file. + * @param array $classes_req Any Main class files/tribe plugins required for this to run. + */ + $dependencies = apply_filters( "tribe_register_{$main_class}_plugin_dependencies", $dependencies, $version, $file_path, $classes_req ); + + //add all plugins to registered_plugins + $this->add_registered_plugin( $main_class, $version, $file_path, $dependencies ); + + // Checks to see if the plugins are active for extensions + if ( ! empty( $classes_req ) && ! $this->has_requisite_plugins( $classes_req ) ) { + $tribe_plugins = new Tribe__Plugins(); + foreach ( $classes_req as $class => $plugin_version ) { + $plugin = $tribe_plugins->get_plugin_by_class( $class ); + + $is_active = $this->is_plugin_version( $class, $plugin_version ); + $pue = $this->get_pue_from_class( $plugin['class'] ); + $has_pue_notice = $pue ? tribe( 'pue.notices' )->has_notice( $pue->pue_install_key ) : false; + + $this->admin_messages[ $main_class ]->add_required_plugin( + $plugin['short_name'], + $plugin['thickbox_url'], + $is_active, + $plugin_version, + false, + $has_pue_notice + ); + } + } + + // only set The Events Calendar and Event Tickets to Active when registering + if ( 'Tribe__Events__Main' === $main_class || 'Tribe__Tickets__Main' === $main_class ) { + $this->add_active_plugin( $main_class, $version, $file_path ); + } + + } + + /** + * Checks if this plugin has permission to run, if not it notifies the admin + * + * @since 4.9 + * + * @param string $main_class The Main/base class for this plugin + * + * @return bool Indicates if plugin should continue initialization + */ + public function check_plugin( $main_class ) { + + $parent_dependencies = $co_dependencies = $addon_dependencies = 0; + + // Check if plugin is registered, if not return false. + $plugin = $this->get_registered_plugin( $main_class ); + if ( empty( $plugin ) ) { + return false; + } + + // Check parent dependencies in add-on. + if ( ! empty( $plugin['dependencies']['parent-dependencies'] ) ) { + $parent_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['parent-dependencies'] ); + } + // Check co-dependencies in add-on. + if ( ! empty( $plugin['dependencies']['co-dependencies'] ) ) { + $co_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['co-dependencies'] ); + } + + // Check add-on dependencies from parent. + $addon_dependencies = $this->check_addon_dependencies( $main_class ); + + // If good then we set as active plugin and continue to load. + if ( ! $parent_dependencies && ! $co_dependencies && ! $addon_dependencies ) { + $this->add_active_plugin( $main_class, $plugin['version'], $plugin['path'] ); + + return true; + } + + return false; + } + + /** + * Check an add-on dependencies for its parent + * + * @since 4.9 + * + * @param string $main_class A string of the main class for the plugin being checked. + * + * @return bool Returns false if any dependency is invalid. + */ + protected function check_addon_dependencies( $main_class ) { + foreach ( $this->registered_plugins as $registered ) { + if ( empty( $registered['dependencies']['addon-dependencies'][ $main_class ] ) ) { + continue; + } + + $dependencies = [ $main_class => $registered['dependencies']['addon-dependencies'][ $main_class ] ]; + $check = $this->has_valid_dependencies( $registered, $dependencies, true ); + + // A value of `true` or `0` indicates there are no failing checks. So here we check for ints gt 0. + if ( is_int( $check ) && $check > 0 ) { + return true; + } + } + + return false; + } + + /** + * Static Singleton Factory Method + * + * @deprecated 4.9.12 We shouldn't be handling singletons internally. + * + * @return self + */ + public static function instance() { + return tribe( self::class ); + } + } + +} diff --git a/tribe-common/src/Tribe/Deprecation.php b/tribe-common/src/Tribe/Deprecation.php new file mode 100644 index 0000000000..04ad0a2553 --- /dev/null +++ b/tribe-common/src/Tribe/Deprecation.php @@ -0,0 +1,194 @@ + => array(, )`. + * e.g. `'tribe_current' => array ('4.3', 'tribe_deprecated')` + * + * For performance reasons this array is manually set and **not** + * dynamically populated. + * + * @var array + */ + protected $deprecated_filters = [ + 'tribe_cost_regex' => [ '4.3', 'tribe_events_cost_regex' ], + 'tribe_rewrite_prepared_slug' => [ '4.3', 'tribe_events_rewrite_prepared_slug' ], + ]; + + /** + * An array specifying the tag, version and optional replacements + * for deprecated actions. + * + * Use the format ` => array(, )`. + * e.g. `'tribe_current' => array ('4.3', 'tribe_deprecated')` + * + * For performance reasons this array is manually set and **not** + * dynamically populated. + * + * @var array + */ + protected $deprecated_actions = [ + 'tribe_pre_rewrite' => [ '4.3', 'tribe_events_pre_rewrite' ], + ]; + + /** + * @return Tribe__Deprecation + */ + public static function instance() { + if ( empty( self::$instance ) ) { + $instance = new self(); + + $instance->deprecate_actions(); + $instance->deprecate_filters(); + + self::$instance = $instance; + } + + return self::$instance; + } + + /** + * Hooks the deprecation notices for actions. + * + * @internal + */ + public function deprecate_actions() { + foreach ( array_keys( $this->deprecated_actions ) as $new_action_tag ) { + add_action( $new_action_tag, [ $this, 'deprecated_action_message' ] ); + add_filter( + $this->deprecated_actions[ $new_action_tag ][1], [ $this, 'deprecated_action_message' ] + ); + } + } + + /** + * Hooks the deprecation notices for filters. + * + * @internal + */ + public function deprecate_filters() { + foreach ( array_keys( $this->deprecated_filters ) as $new_filter_tag ) { + add_filter( $new_filter_tag, [ $this, 'deprecated_filter_message' ] ); + add_filter( + $this->deprecated_filters[ $new_filter_tag ][1], [ $this, 'deprecated_filter_message' ] + ); + } + } + + /** + * Triggers a deprecation notice if there is any callback hooked on a deprecated action. + */ + public function deprecated_action_message() { + $action = current_action(); + if ( isset( $this->deprecated_actions[ $action ] ) ) { + $deprecated_tag = $this->deprecated_actions[ $action ][1]; + } else { + $deprecated_tag = $action; + $action = $this->get_action_for_deprecated_tag( $action ); + } + + remove_action( $deprecated_tag, [ $this, 'deprecated_action_message' ] ); + + if ( doing_action( $deprecated_tag ) || has_filter( $deprecated_tag ) ) { + _deprecated_function( + 'The ' . $deprecated_tag . ' action', $this->deprecated_actions[ $action ][0], $action + ); + } + + add_action( $deprecated_tag, [ $this, 'deprecated_action_message' ] ); + } + + /** + * Triggers a deprecation notice if there is any callback hooked on a deprecated filter. + * + * @since 4.5.13 the filtered value is passed through unchanged + * + * @param mixed $value + * + * @return mixed + */ + public function deprecated_filter_message( $value = null ) { + $filter = current_filter(); + if ( isset( $this->deprecated_filters[ $filter ] ) ) { + $deprecated_tag = $this->deprecated_filters[ $filter ][1]; + } else { + $deprecated_tag = $filter; + $filter = $this->get_filter_for_deprecated_tag( $filter ); + } + + remove_filter( $deprecated_tag, [ $this, 'deprecated_filter_message' ] ); + + if ( has_filter( $deprecated_tag ) || doing_filter( $deprecated_tag ) ) { + $version = Tribe__Utils__Array::get( $this->deprecated_filters, [ $filter, 0 ], null ); + + _deprecated_function( + 'The ' . $deprecated_tag . ' filter', $version, $filter + ); + } + + add_filter( $deprecated_tag, [ $this, 'deprecated_filter_message' ] ); + + return $value; + } + + /** + * @param array $deprecated_filters + * + * @internal + */ + public function set_deprecated_filters( $deprecated_filters ) { + $this->deprecated_filters = $deprecated_filters; + } + + /** + * @param array $deprecated_actions + * + * @internal + */ + public function set_deprecated_actions( $deprecated_actions ) { + $this->deprecated_actions = $deprecated_actions; + } + + /** + * @param string $deprecated_tag + * + * @return int|string + */ + protected function get_action_for_deprecated_tag( $deprecated_tag ) { + foreach ( $this->deprecated_actions as $new_tag => $args ) { + if ( $args[1] === $deprecated_tag ) { + return $new_tag; + } + } + } + + /** + * @param string $deprecated_tag + * + * @return int|string + */ + protected function get_filter_for_deprecated_tag( $deprecated_tag ) { + foreach ( $this->deprecated_filters as $new_tag => $args ) { + if ( $args[1] === $deprecated_tag ) { + return $new_tag; + } + } + } +} diff --git a/tribe-common/src/Tribe/Dialog/View.php b/tribe-common/src/Tribe/Dialog/View.php new file mode 100644 index 0000000000..9ae15ca673 --- /dev/null +++ b/tribe-common/src/Tribe/Dialog/View.php @@ -0,0 +1,538 @@ +set_template_origin( \Tribe__Main::instance() ); + $this->set_template_folder( 'src/views/dialog' ); + + // Configures this templating class to extract variables. + $this->set_template_context_extract( true ); + + // Uses the public folders. + $this->set_template_folder_lookup( true ); + } + + /** + * Public wrapper for build method. + * Contains all the logic/validation checks. + * + * @since 4.10.0 + * + * @param string $content Content as an HTML string. + * @param array $args { + * List of arguments to override dialog template. + * + * @type string $button_id The ID for the trigger button (optional). + * @type array $button_classes Any desired classes for the trigger button (optional). + * @type array $button_attributes Any desired attributes for the trigger button (optional). + * @type boolean $button_disabled Should the button be disabled (optional). + * @type string $button_text The text for the dialog trigger button ("Open the dialog window"). + * @type string $button_type The type for the trigger button (optional). + * @type string $button_value The value for the trigger button (optional). + * @type boolean $button_display If the dialog button should be displayed or not (optional). + * @type string $close_event The dialog close event hook name (`tribe_dialog_close_dialog`). + * @type string $content_classes The dialog content classes ("tribe-dialog__content"). + * @type array $context Any additional context data you need to expose to this file (optional). + * @type string $id The unique ID for this dialog (`uniqid()`). + * @type string $show_event The dialog event show hook name (`tribe_dialog_show_dialog`). + * @type string $template The dialog template name (dialog). + * @type string $title The dialog title (optional). + * @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger"). + * + * Dialog script option overrides. + * + * @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional). + * @type boolean $body_lock Whether to lock the body while dialog open (false). + * @type string $close_button_aria_label Aria label for the close button ("Close this dialog window"). + * @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button"). + * @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper"). + * @type string $effect CSS effect on open. none or fade (optional). + * @type string $effect_easing A css easing string to apply ("ease-in-out"). + * @type int $effect_speed CSS effect speed in milliseconds (optional). + * @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay"). + * @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false). + * @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog"). + * } + * @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`). + * @param boolean $echo Whether to echo the script or to return it (default: true). + * + * @return string An HTML string of the dialog. + */ + public function render_dialog( $content, $args = [], $id = null, $echo = true ) { + // Check for content to be passed. + if ( empty( $content ) ) { + return ''; + } + + // Generate an ID if we weren't passed one. + if ( is_null( $id ) ) { + $id = \uniqid(); + } + + /** @var \Tribe__Assets $assets */ + $assets = tribe( 'assets' ); + $assets->enqueue_group( 'tribe-dialog' ); + + $html = $this->build_dialog( $content, $id, $args ); + + if ( ! $echo ) { + return $html; + } + + echo $html; + } + + /** + * Syntactic sugar for `render_dialog()` to make creating modals easier. + * Adds sensible defaults for modals. + * + * @since 4.10.0 + * + * @param string $content Content as an HTML string. + * @param array $args { + * List of arguments to override dialog template. + * + * @type string $button_id The ID for the trigger button (optional). + * @type array $button_classes Any desired classes for the trigger button (optional). + * @type array $button_attributes Any desired attributes for the trigger button (optional). + * @type boolean $button_disabled Should the button be disabled (optional). + * @type string $button_text The text for the dialog trigger button ("Open the modal window"). + * @type string $button_type The type for the trigger button (optional). + * @type string $button_value The value for the trigger button (optional). + * @type boolean $button_display If the dialog button should be displayed or not (optional). + * @type string $close_event The dialog close event hook name (`tribe_dialog_close_modal`). + * @type string $content_classes The dialog content classes ("tribe-dialog__content tribe-modal__content"). + * @type string $title_classes The dialog title classes ("tribe-dialog__title tribe-modal__title"). + * @type array $context Any additional context data you need to expose to this file (optional). + * @type string $id The unique ID for this dialog (`uniqid()`). + * @type string $show_event The dialog event hook name (`tribe_dialog_show_modal`). + * @type string $template The dialog template name (modal). + * @type string $title The dialog title (optional). + * @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger"). + * + * Dialog script option overrides. + * + * @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override ("body"). + * @type boolean $body_lock Whether to lock the body while dialog open (true). + * @type string $close_button_aria_label Aria label for the close button ("Close this modal window"). + * @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button tribe-modal__close-button"). + * @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper tribe-modal__wrapper"). + * @type string $effect CSS effect on open. none or fade ("fade"). + * @type string $effect_easing A css easing string to apply ("ease-in-out"). + * @type int $effect_speed CSS effect speed in milliseconds (300). + * @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay tribe-modal__overlay"). + * @type boolean $overlay_click_closes If clicking the overlay closes the dialog (true). + * @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog"). + * } + * @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`). + * @param boolean $echo Whether to echo the script or to return it (default: true). + * + * @return string An HTML string of the dialog. + */ + public function render_modal( $content, $args = [], $id = null, $echo = true ) { + $default_args = [ + 'append_target' => '', + 'body_lock' => true, + 'button_text' => __( 'Open the modal window', 'tribe-common' ), + 'close_button_aria_label' => __( 'Close this modal window', 'tribe-common' ), + 'close_button_classes' => 'tribe-dialog__close-button tribe-modal__close-button', + 'close_event' => 'tribe_dialog_close_modal', + 'content_classes' => 'tribe-dialog__content tribe-modal__content', + 'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-modal__wrapper', + 'effect' => 'fade', + 'effect_speed' => 300, + 'overlay_classes' => 'tribe-dialog__overlay tribe-modal__overlay', + 'overlay_click_closes' => true, + 'show_event' => 'tribe_dialog_show_modal', + 'template' => 'modal', + 'title_classes' => [ 'tribe-dialog__title', 'tribe-modal__title' ], + ]; + + $args = wp_parse_args( $args, $default_args ); + + $this->render_dialog( $content, $args, $id, $echo ); + } + + /** + * Syntactic sugar for `render_dialog()` to make creating custom confirmation dialogs easier. + * Adds sensible defaults for confirmation dialogs. + * + * @since 4.10.0 + * + * @param string $content Content as an HTML string. + * @param array $args { + * List of arguments to override dialog template. + * + * @type string $button_id The ID for the trigger button (optional). + * @type array $button_classes Any desired classes for the trigger button (optional). + * @type array $button_attributes Any desired attributes for the trigger button (optional). + * @type boolean $button_disabled Should the button be disabled (optional). + * @type string $button_text The text for the dialog trigger button ("Open the dialog window"). + * @type string $button_type The type for the trigger button (optional). + * @type string $button_value The value for the trigger button (optional). + * @type boolean $button_display If the dialog button should be displayed or not (optional). + * @type string $cancel_button_text Text for the "Cancel" button ("Cancel"). + * @type string $content_classes The dialog content classes ("tribe-dialog__content tribe-confirm__content"). + * @type string $continue_button_text Text for the "Continue" button ("Confirm"). + * @type array $context Any additional context data you need to expose to this file (optional). + * @type string $id The unique ID for this dialog (`uniqid()`). + * @type string $template The dialog template name (confirm). + * @type string $title The dialog title (optional). + * @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger"). + * + * Dialog script option overrides. + * + * @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional). + * @type boolean $body_lock Whether to lock the body while dialog open (true). + * @type string $close_button_aria_label Aria label for the close button (optional). + * @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button--hidden"). + * @type string $close_event The dialog close event hook name (`tribe_dialog_close_confirm`). + * @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper tribe-confirm__wrapper"). + * @type string $effect CSS effect on open. none or fade (optional). + * @type string $effect_easing A css easing string to apply ("ease-in-out"). + * @type int $effect_speed CSS effect speed in milliseconds (optional). + * @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay tribe-confirm__overlay"). + * @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false). + * @type string $show_event The dialog event hook name (`tribe_dialog_show_confirm`). + * @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog"). + * } + * @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`). + * @param boolean $echo Whether to echo the script or to return it (default: true). + * + * @return string An HTML string of the dialog. + */ + public function render_confirm( $content, $args = [], $id = null, $echo = true ) { + $default_args = [ + 'body_lock' => true, + 'cancel_button_text' => __( 'Cancel', 'tribe-common' ), + 'continue_button_text' => __( 'Confirm', 'tribe-common' ), + 'close_button_aria_label' => '', + 'close_button_classes' => 'tribe-dialog__close-button--hidden', + 'close_event' => 'tribe_dialog_close_confirm', + 'content_classes' => 'tribe-dialog__content tribe-confirm__content', + 'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-confirm__wrapper', + 'overlay_classes' => 'tribe-dialog__overlay tribe-confirm__overlay', + 'show_event' => 'tribe_dialog_show_confirm', + 'template' => 'confirm', + 'title_classes' => [ 'tribe-dialog__title', 'tribe-confirm__title' ], + ]; + + $args = wp_parse_args( $args, $default_args ); + + $this->render_dialog( $content, $args, $id, $echo ); + } + + /** + * Syntactic sugar for `render_dialog()` to make creating custom alerts easier. + * Adds sensible defaults for alerts. + * + * @since 4.10.0 + * + * @param string $content Content as an HTML string. + * @param array $args { + * List of arguments to override dialog template. + * + * @type string $alert_button_text Text for the "OK" button ("OK"). + * @type string $button_id The ID for the trigger button (optional). + * @type array $button_classes Any desired classes for the trigger button (optional). + * @type array $button_attributes Any desired attributes for the trigger button (optional). + * @type boolean $button_disabled Should the button be disabled (optional). + * @type string $button_text The text for the dialog trigger button ("Open the dialog window"). + * @type string $button_type The type for the trigger button (optional). + * @type string $button_value The value for the trigger button (optional). + * @type boolean $button_display If the dialog button should be displayed or not (optional). + * @type string $content_classes The dialog content classes ("tribe-dialog__content tribe-alert__content"). + * @type string $title_classes The dialog title classes ("tribe-dialog__title tribe-alert__title"). + * @type array $context Any additional context data you need to expose to this file (optional). + * @type string $id The unique ID for this dialog (`uniqid()`). + * @type string $template The dialog template name (alert). + * @type string $title The dialog title (optional). + * @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger"). + * + * Dialog script option overrides. + * + * @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional). + * @type boolean $body_lock Whether to lock the body while dialog open (true). + * @type string $close_button_aria_label Aria label for the close button (optional). + * @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button--hidden"). + * @type string $close_event The dialog close event hook name (`tribe_dialog_close_alert`). + * @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper tribe-alert__wrapper"). + * @type string $effect CSS effect on open. none or fade (optional). + * @type string $effect_easing A css easing string to apply ("ease-in-out"). + * @type int $effect_speed CSS effect speed in milliseconds (optional). + * @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay tribe-alert__overlay"). + * @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false). + * @type string $show_event The dialog event hook name (`tribe_dialog_show_alert`). + * @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog"). + * } + * @param string $id The unique ID for this dialog. Gets prepended to the data attributes. Generated if not passed (`uniqid()`). + * @param boolean $echo Whether to echo the script or to return it (default: true). + * + * @return string An HTML string of the dialog. + */ + public function render_alert( $content, $args = [], $id = null, $echo = true ) { + $default_args = [ + 'alert_button_text' => __( 'OK', 'tribe-common' ), + 'body_lock' => true, + 'close_button_aria_label' => '', + 'close_button_classes' => 'tribe-dialog__close-button--hidden', + 'close_event' => 'tribe_dialog_close_alert', + 'content_classes' => 'tribe-dialog__content tribe-alert__content', + 'content_wrapper_classes' => 'tribe-dialog__wrapper tribe-alert__wrapper', + 'overlay_classes' => 'tribe-dialog__overlay tribe-alert__overlay', + 'show_event' => 'tribe_dialog_show_alert', + 'template' => 'alert', + 'title_classes' => [ 'tribe-dialog__title', 'tribe-alert__title' ], + ]; + + $args = wp_parse_args( $args, $default_args ); + + $this->render_dialog( $content, $args, $id, $echo ); + } + + /** + * Factory method for dialog HTML + * + * @since 4.10.0 + * + * @param string $content HTML dialog content. + * @param string $id The unique ID for this dialog (`uniqid()`) Gets prepended to the data attributes. + * @param array $args { + * List of arguments to override dialog template. + * + * @type string $button_id The ID for the trigger button (optional). + * @type array $button_classes Any desired classes for the trigger button (optional). + * @type array $button_attributes Any desired attributes for the trigger button (optional). + * @type boolean $button_disabled Should the button be disabled (optional). + * @type string $button_text The text for the dialog trigger button ("Open the dialog window"). + * @type string $button_type The type for the trigger button (optional). + * @type string $button_value The value for the trigger button (optional). + * @type boolean $button_display If the dialog button should be displayed or not (optional). + * @type string $close_event The dialog event hook name (`tribe_dialog_close_dialog`). + * @type string $content_classes The dialog content classes ("tribe-dialog__content"). + * @type string $title_classes The dialog title classes ("tribe-dialog__title"). + * @type array $context Any additional context data you need to expose to this file (optional). + * @type string $id The unique ID for this dialog (`uniqid()`). + * @type string $show_event The dialog event hook name (`tribe_dialog_show_dialog`). + * @type string $template The dialog template name (dialog). + * @type string $title The dialog title (optional). + * @type string $trigger_classes Classes for the dialog trigger ("tribe_dialog_trigger"). + * + * Dialog script option overrides. + * + * @type string $append_target The dialog will be inserted after the button, you could supply a selector string here to override (optional). + * @type boolean $body_lock Whether to lock the body while dialog open (false). + * @type string $close_button_aria_label Aria label for the close button ("Close this dialog window"). + * @type string $close_button_classes Classes for the close button ("tribe-dialog__close-button"). + * @type string $content_wrapper_classes Dialog content wrapper classes. This wrapper includes the close button ("tribe-dialog__wrapper"). + * @type string $effect CSS effect on open. none or fade (optional). + * @type string $effect_easing A css easing string to apply ("ease-in-out"). + * @type int $effect_speed CSS effect speed in milliseconds (optional). + * @type string $overlay_classes The dialog overlay classes ("tribe-dialog__overlay"). + * @type boolean $overlay_click_closes If clicking the overlay closes the dialog (false). + * @type string $wrapper_classes The wrapper class for the dialog ("tribe-dialog"). + * } + * + * @return string An HTML string of the dialog. + */ + private function build_dialog( $content, $id, $args ) { + $default_args = [ + 'button_classes' => '', + 'button_attributes' => [], + 'button_disabled' => false, + 'button_id' => '', + 'button_name' => '', + 'button_text' => __( 'Open the dialog window', 'tribe-common' ), + 'button_type' => '', + 'button_value' => '', + 'button_display' => true, + 'close_event' => 'tribe_dialog_close_dialog', + 'content_classes' => 'tribe-dialog__content', + 'context' => '', + 'show_event' => 'tribe_dialog_show_dialog', + 'template' => 'dialog', + 'title_classes' => 'tribe-dialog__title', + 'title' => '', + 'trigger_classes' => 'tribe_dialog_trigger', + // Dialog script options. + 'append_target' => '', // The dialog will be inserted after the button, you could supply a selector string here to override. + 'body_lock' => false, // Lock the body while dialog open? + 'close_button_aria_label' => __( 'Close this dialog window', 'tribe-common' ), // Aria label for close button. + 'close_button_classes' => 'tribe-dialog__close-button', // Classes for close button. + 'content_wrapper_classes' => 'tribe-dialog__wrapper', // Dialog content classes. + 'effect' => 'none', // None or fade (for now). + 'effect_speed' => 0, // Effect speed in milliseconds. + 'effect_easing' => 'ease-in-out', // A css easing string. + 'overlay_classes' => 'tribe-dialog__overlay', // Overlay classes. + 'overlay_click_closes' => false, // Clicking overlay closes dialog. + 'wrapper_classes' => 'tribe-dialog', // The wrapper class for the dialog. + ]; + + $args = wp_parse_args( $args, $default_args ); + + $args[ 'content' ] = $content; + $args[ 'id' ] = $id; + + /** + * Allow us to filter the dialog arguments. + * + * @since 4.10.0 + * + * @param array $args The dialog arguments. + * @param string $content HTML content string. + */ + $args = apply_filters( 'tribe_dialog_args', $args, $content ); + + $template = $args[ 'template' ]; + /** + * Allow us to filter the dialog template name. + * + * @since 4.10.0 + * + * @param string $template The dialog template name. + * @param array $args The dialog arguments. + */ + $template_name = apply_filters( 'tribe_dialog_template', $template, $args ); + + ob_start(); + + $this->template( $template_name, $args, true ); + + $this->get_dialog_script( $args ); + + $html = ob_get_clean(); + + /** + * Allow us to filter the dialog output (HTML string). + * + * @since 4.10.0 + * + * @param string $html The dialog HTML string. + * @param array $args The dialog arguments. + */ + return apply_filters( 'tribe_dialog_html', $html, $args ); + } + + /** + * Get dialog + build_dialog(). + */ + $html = apply_filters( 'tribe_dialog_script_html', $html ); + + if ( $echo ) { + echo $html; + return; + } + + return $html; + } +} diff --git a/tribe-common/src/Tribe/Documentation/Swagger/Builder_Interface.php b/tribe-common/src/Tribe/Documentation/Swagger/Builder_Interface.php new file mode 100644 index 0000000000..1b757f2209 --- /dev/null +++ b/tribe-common/src/Tribe/Documentation/Swagger/Builder_Interface.php @@ -0,0 +1,29 @@ + 'object', + 'properties' => [ + 'currency_symbol' => [ + 'type' => 'string', + 'description' => __( 'The cost currency symbol', 'tribe-common' ), + ], + 'currency_position ' => [ + 'type' => 'string', + 'description' => __( 'The position of the currency symbol in the cost string', 'tribe-common' ), + 'enum' => [ 'prefix', 'postfix' ], + ], + 'values' => [ + 'type' => 'array', + 'items' => [ 'type' => 'integer' ], + 'description' => __( 'A sorted array of all the numeric values for the cost', 'tribe-common' ), + ], + ], + ]; + + /** + * Filters the Swagger documentation generated for a cost details in the TEC REST API. + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'tribe_rest_swagger_cost_details_documentation', $documentation ); + + return $documentation; + } +} diff --git a/tribe-common/src/Tribe/Documentation/Swagger/Date_Details_Definition_Provider.php b/tribe-common/src/Tribe/Documentation/Swagger/Date_Details_Definition_Provider.php new file mode 100644 index 0000000000..c76f15db7a --- /dev/null +++ b/tribe-common/src/Tribe/Documentation/Swagger/Date_Details_Definition_Provider.php @@ -0,0 +1,60 @@ + 'object', + 'properties' => [ + 'year' => [ + 'type' => 'integer', + 'description' => __( 'The date year', 'tribe-common' ), + ], + 'month' => [ + 'type' => 'integer', + 'description' => __( 'The date month', 'tribe-common' ), + ], + 'day' => [ + 'type' => 'integer', + 'description' => __( 'The date day', 'tribe-common' ), + ], + 'hour' => [ + 'type' => 'integer', + 'description' => __( 'The date hour', 'tribe-common' ), + ], + 'minutes' => [ + 'type' => 'integer', + 'description' => __( 'The date minutes', 'tribe-common' ), + ], + 'seconds' => [ + 'type' => 'integer', + 'description' => __( 'The date seconds', 'tribe-common' ), + ], + ], + ]; + + /** + * Filters the Swagger documentation generated for an date details in the TEC REST API. + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'tribe_rest_swagger_date_details_documentation', $documentation ); + + return $documentation; + } +} diff --git a/tribe-common/src/Tribe/Documentation/Swagger/Image_Definition_Provider.php b/tribe-common/src/Tribe/Documentation/Swagger/Image_Definition_Provider.php new file mode 100644 index 0000000000..3633af9d88 --- /dev/null +++ b/tribe-common/src/Tribe/Documentation/Swagger/Image_Definition_Provider.php @@ -0,0 +1,64 @@ + 'object', + 'properties' => [ + 'url' => [ + 'type' => 'string', + 'format' => 'uri', + 'description' => __( 'The URL to the full size version of the image', 'tribe-common' ), + ], + 'id' => [ + 'type' => 'integer', + 'description' => __( 'The image WordPress post ID', 'tribe-common' ), + ], + 'extension' => [ + 'type' => 'string', + 'description' => __( 'The image file extension', 'tribe-common' ), + ], + 'width' => [ + 'type' => 'integer', + 'description' => __( 'The image natural width in pixels', 'tribe-common' ), + ], + 'height' => [ + 'type' => 'integer', + 'description' => __( 'The image natural height in pixels', 'tribe-common' ), + ], + 'sizes' => [ + 'type' => 'array', + 'description' => __( 'The details about each size available for the image', 'tribe-common' ), + 'items' => [ + '$ref' => '#/components/schemas/ImageSize', + ], + ], + ], + ]; + + /** + * Filters the Swagger documentation generated for an image deatails in the TEC REST API. + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'tribe_rest_swagger_image_details_documentation', $documentation ); + + return $documentation; + } +} diff --git a/tribe-common/src/Tribe/Documentation/Swagger/Image_Size_Definition_Provider.php b/tribe-common/src/Tribe/Documentation/Swagger/Image_Size_Definition_Provider.php new file mode 100644 index 0000000000..91921b57b0 --- /dev/null +++ b/tribe-common/src/Tribe/Documentation/Swagger/Image_Size_Definition_Provider.php @@ -0,0 +1,53 @@ + 'object', + 'properties' => [ + 'width' => [ + 'type' => 'integer', + 'description' => __( 'The image width in pixels in the specified size', 'tribe-common' ), + ], + 'height' => [ + 'type' => 'integer', + 'description' => __( 'The image height in pixels in the specified size', 'tribe-common' ), + ], + 'mime-type' => [ + 'type' => 'string', + 'description' => __( 'The image mime-type', 'tribe-common' ), + ], + 'url' => [ + 'type' => 'string', + 'format' => 'uri', + 'description' => __( 'The link to the image in the specified size on the site', 'tribe-common' ), + ], + ], + ]; + + /** + * Filters the Swagger documentation generated for an image size in the TEC REST API. + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'tribe_rest_swagger_image_size_documentation', $documentation ); + + return $documentation; + } +} diff --git a/tribe-common/src/Tribe/Documentation/Swagger/Provider_Interface.php b/tribe-common/src/Tribe/Documentation/Swagger/Provider_Interface.php new file mode 100644 index 0000000000..c57448f877 --- /dev/null +++ b/tribe-common/src/Tribe/Documentation/Swagger/Provider_Interface.php @@ -0,0 +1,17 @@ + 'object', + 'properties' => [ + 'id' => [ + 'type' => 'integer', + 'description' => __( 'The WordPress term ID', 'tribe-common' ), + ], + 'name' => [ + 'type' => 'string', + 'description' => __( 'The term name', 'tribe-common' ), + ], + 'slug' => [ + 'type' => 'string', + 'description' => __( 'The term slug', 'tribe-common' ), + ], + 'taxonomy' => [ + 'type' => 'string', + 'description' => __( 'The taxonomy the term belongs to', 'tribe-common' ), + ], + 'description' => [ + 'type' => 'string', + 'description' => __( 'The term description', 'tribe-common' ), + ], + 'parent' => [ + 'type' => 'integer', + 'description' => __( 'The term parent term if any', 'tribe-common' ), + ], + 'count' => [ + 'type' => 'integer', + 'description' => __( 'The number of posts associated with the term', 'tribe-common' ), + ], + 'url' => [ + 'type' => 'string', + 'description' => __( 'The URL to the term archive page', 'tribe-common' ), + ], + 'urls' => [ + 'type' => 'array', + 'items' => [ 'type' => 'string' ], + 'description' => __( 'A list of links to the term own, archive and parent REST URL', 'tribe-common' ), + ], + ], + ]; + + /** + * Filters the Swagger documentation generated for an term in the TEC REST API. + * + * @param array $documentation An associative PHP array in the format supported by Swagger. + * + * @link http://swagger.io/ + */ + $documentation = apply_filters( 'tribe_rest_swagger_term_documentation', $documentation ); + + return $documentation; + } +} diff --git a/tribe-common/src/Tribe/Duplicate/Post.php b/tribe-common/src/Tribe/Duplicate/Post.php new file mode 100644 index 0000000000..ab1a489c09 --- /dev/null +++ b/tribe-common/src/Tribe/Duplicate/Post.php @@ -0,0 +1,443 @@ +factory = null !== $factory ? $factory : tribe( 'post-duplicate.strategy-factory' ); + } + + /** + * Sets the post fields that should be used to find a duplicate in the database. + * + * Each entry should be in the [ => [ 'match' => ]] format. + * If not the strategy will be set to the default one. + * + * @param array $post_fields + * + * @since 4.6 + */ + public function use_post_fields( array $post_fields ) { + if ( empty( $post_fields ) ) { + $this->post_fields = []; + + return; + } + + $cast = $this->cast_to_strategy( $post_fields ); + $this->post_fields = array_intersect_key( $cast, array_combine( self::$post_table_columns, self::$post_table_columns ) ); + } + + /** + * Converts an array of fields to the format required by the class. + * + * @param array $fields + * + * @return array + * + * @since 4.6 + */ + protected function cast_to_strategy( array $fields ) { + $cast = []; + + foreach ( $fields as $key => $value ) { + if ( is_numeric( $key ) ) { + $cast[ $value ] = [ 'match' => 'same' ]; + } elseif ( is_array( $value ) ) { + if ( ! empty( $value['match'] ) ) { + $cast[ $key ] = $value; + } else { + $cast[ $key ] = array_merge( $value, [ 'match' => 'same' ] ); + } + } + } + + return $cast; + } + + /** + * Finds a duplicate with the data provided. + * + * The more post and custom fields are used to find a match the less likely it is to find one and the more + * likely it is for a duplicate to be a good match. + * + * @param array $postarr An array of post data, post fields and custom fields, that should be used to find the + * duplicate. + * + * @return bool|int `false` if a duplicate was not found, the post ID of the duplicate if found. + * + * @since 4.6 + */ + public function find_for( array $postarr ) { + if ( empty( $this->post_fields ) && empty( $this->custom_fields ) ) { + return false; + } + + $prepared = $this->prepare_queries( $postarr ); + + if ( false === $prepared ) { + return false; + } + + $id = false; + + /** @var wpdb $wpdb */ + global $wpdb; + foreach ( $prepared as $query ) { + $this_id = $wpdb->get_var( $query ); + + if ( self::AND_OPERATOR === $this->where_operator ) { + if ( empty( $this_id ) ) { + return false; + } + + $id = empty( $id ) + ? $this_id + : $this_id == $id; + + if ( empty( $id ) ) { + return false; + } + } else { + if ( ! empty( $this_id ) ) { + return $this_id; + } + } + } + + return $id; + } + + /** + * Finds all the duplicates with the data provided. + * + * The more post and custom fields are used to find a match the less likely it is to find one and the more + * likely it is for a duplicate to be a good match. + * + * @param array $postarr An array of post data, post fields and custom fields, that should be used to find the + * duplicate. + * + * @return bool|array `false` if a duplicate was not found, an array of the duplicate post IDs if any were found. + * + * @since 4.6 + */ + public function find_all_for( array $postarr ) { + if ( empty( $this->post_fields ) && empty( $this->custom_fields ) ) { + return false; + } + + $prepared = $this->prepare_queries( $postarr ); + + if ( false === $prepared ) { + return false; + } + + $ids = false; + + /** @var wpdb $wpdb */ + global $wpdb; + foreach ( $prepared as $query ) { + $this_ids = $wpdb->get_results( $query ); + $this_ids = ! empty( $this_ids ) + ? array_map( 'intval', wp_list_pluck( $this_ids, 'ID' ) ) + : false; + + if ( self::AND_OPERATOR === $this->where_operator ) { + if ( empty( $this_ids ) ) { + return false; + } + + $ids = empty( $ids ) + ? $this_ids + : array_intersect( (array) $ids, (array) $this_ids ); + + if ( empty( $ids ) ) { + return false; + } + } else { + $ids = empty( $ids ) + ? $this_ids + : array_unique( array_merge( (array) $ids, array_filter( (array) $this_ids ) ) ); + } + } + + return $ids; + } + + /** + * Sets the custom fields that should be used to find a duplicate in the database. + * + * Each entry should be in the [ => [ 'match' => ]] format. + * If not the strategy will be set to the default one. + * + * @param array $custom_fields + * + * @since 4.6 + */ + public function use_custom_fields( array $custom_fields ) { + $cast = $this->cast_to_strategy( $custom_fields ); + $this->custom_fields = $cast; + } + + /** + * Gets the SQL logic operator that will be used to join the WHERE queries frags. + * + * @return string + * + * @since 4.6 + */ + public function get_where_operator() { + return $this->where_operator; + } + + /** + * Sets the SQL logic operator that should be used to join the WHERE queries frags. + * + * @param string $where_operator + * + * @since 4.6 + */ + public function set_where_operator( $where_operator ) { + $this->where_operator = self::AND_OPERATOR === strtoupper( $where_operator ) + ? self::AND_OPERATOR + : self::OR_OPERATOR; + } + + /** + * Prepares the query that should be used to query for duplicates according + * to the current post and custom fields. + * + * @param array $postarr + * + * @return bool|array An array of prepared queries or `false` on failure. + * + * @since 4.6 + */ + protected function prepare_queries( array $postarr ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $where_frags = []; + $custom_fields_where_frags = []; + $join = []; + + if ( ! empty( $this->post_fields ) ) { + $queryable_post_fields = array_intersect_key( $postarr, $this->post_fields ); + if ( empty( $queryable_post_fields ) ) { + return false; + } + foreach ( $queryable_post_fields as $key => $value ) { + $match_strategy = $this->factory->make( $this->post_fields[ $key ]['match'] ); + $where_frags[] = $match_strategy->where( $key, $postarr[ $key ] ); + } + } + + if ( ! empty( $this->custom_fields ) ) { + // we had post fields and found a match + $queryable_custom_fields = array_intersect_key( $postarr, $this->custom_fields ); + $i = 0; + foreach ( $queryable_custom_fields as $key => $value ) { + $match_strategy = $this->factory->make( $this->custom_fields[ $key ]['match'] ); + $meta_value = is_array( $value ) ? reset( $value ) : $value; + $custom_fields_where_frags[] = $match_strategy->where_custom_field( $key, $meta_value, "pm{$i}" ); + $i ++; + } + $count = count( $custom_fields_where_frags ); + for ( $i = 0; $i < $count; $i ++ ) { + $join[] = " \nLEFT JOIN {$wpdb->postmeta} pm{$i} ON pm{$i}.post_id = {$wpdb->posts}.ID "; + } + } + + /** + * Filters the JOIN limit. + * + * @param int $join_limit How many joins will be made per query at most. + * @param array $where_frags The WHERE components for this duplicate search query + * @param string $post_type The post type that's being used for this duplicate search query. + * + * @since 4.6 + */ + $join_limit = apply_filters( 'tribe_duplicate_post_join_limit', $this->join_limit, $where_frags, $this->post_type ); + + $excluded_status = [ + 'trash', + 'autodraft', + ]; + + /** + * Filters the excluded status. + * + * @param array $excluded_status The list of post_status to exclude from the query. + * @param string $post_type The post type that's being used for this duplicate search query. + * + * @since 4.6 + */ + $excluded_status = apply_filters( 'tribe_duplicate_post_excluded_status', $excluded_status, $where_frags, $this->post_type ); + + $post_type_conditional = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $this->post_type ); + + $post_status_conditional = ''; + + if ( $excluded_status ) { + $in_string = array_fill( 0, count( $excluded_status ), '%s' ); + $in_string = implode( ', ', $in_string ); + + // @codingStandardsIgnoreLine + $post_status_conditional = $wpdb->prepare( "{$wpdb->posts}.post_status NOT IN ( {$in_string} )", $excluded_status ); + } + + $queries = []; + + if ( ! empty( $join_limit ) && ! empty( $join ) ) { + while ( count( $join ) ) { + $current_wheres = array_splice( $custom_fields_where_frags, 0, $join_limit ); + $current_joins = array_splice( $join, 0, $join_limit ); + + $this_join = implode( "\n", $current_joins ); + + $this_where = "\n" . implode( " \n{$this->where_operator} ", array_merge( $where_frags, $current_wheres ) ); + $this_where = sprintf( '%s AND (%s)', $post_type_conditional, $this_where ); + + if ( '' !== $post_status_conditional ) { + $this_where = sprintf( '%s AND %s', $post_status_conditional, $this_where ); + } + + $queries[] = "SELECT DISTINCT {$wpdb->posts}.ID from {$wpdb->posts} {$this_join} \nWHERE {$this_where}"; + } + } else { + $where = implode( " \n{$this->where_operator} ", $where_frags ); + $where = sprintf( '%s AND (%s)', $post_type_conditional, $where ); + + if ( '' !== $post_status_conditional ) { + $where = sprintf( '%s AND %s', $post_status_conditional, $where ); + } + + $queries[] = "SELECT DISTINCT {$wpdb->posts}.ID from {$wpdb->posts} \nWHERE {$where}"; + } + + + return $queries; + } + + /** + * Gets the post type that will be used to find duplicates. + * + * @return string + * + * @since 4.6 + */ + public function get_post_type() { + return $this->post_type; + } + + /** + * Sets the post type that should be used to find duplicates. + * + * @param string $post_type + * + * @since 4.6 + */ + public function set_post_type( $post_type ) { + $this->post_type = $post_type; + } + + /** + * Sets the limit that should be applied to the number of JOIN in a single query. + * + * Setting the limit to an empty value will remove the limit (very bad idea). + * + * @param int $join_limit + * + * @since 4.6 + */ + public function set_join_limit( $join_limit ) { + $this->join_limit = empty( $join_limit ) + ? 999 + : intval( $join_limit ); + } + + /** + * Returns the limit that will be applied to the number of JOIN in a single query. + * + * @return int + * + * @since 4.6 + */ + public function get_join_limit() { + return $this->join_limit; + } +} diff --git a/tribe-common/src/Tribe/Duplicate/Strategy/Base.php b/tribe-common/src/Tribe/Duplicate/Strategy/Base.php new file mode 100644 index 0000000000..ebe5e955b7 --- /dev/null +++ b/tribe-common/src/Tribe/Duplicate/Strategy/Base.php @@ -0,0 +1,24 @@ +is_a_numeric_post_field( $key ) ) { + return $wpdb->prepare( "{$key} = %d", $value ); + } + + $frags = $this->get_where_frags( $value ); + + $where_frags = []; + foreach ( $frags as $frag ) { + $formatted_frag = '%' . $wpdb->esc_like( strtolower( trim( $frag ) ) ) . '%'; + $where_frags[] = $wpdb->prepare( "{$key} LIKE %s", $formatted_frag ); + } + + return sprintf( '(%s)', implode( ' AND ', $where_frags ) ); + } + + /** + * Removes anything that's not letters, numbers, hypens and underscores from the string and returns its frags. + * + * @param string $value + * + * @return array + * + * @since 4.6 + */ + protected function get_where_frags( $value ) { + $snaked = preg_replace( '/[^a-z\d-]+/i', '_', $value ); + $frags = array_filter( explode( '_', $snaked ) ); + + return $frags; + } + + /** + * Returns a string suitable to be used as a WHERE clause in a SQL query for a custom field JOIN. + * + * @param string $key + * @param mixed $value + * @param string $table_alias + * + * @return string + * + * @since 4.6 + */ + public function where_custom_field( $key, $value, $table_alias ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $frags = $this->get_where_frags( $value ); + + $where_frags = [ $wpdb->prepare( "{$table_alias}.meta_key = %s", $key ) ]; + foreach ( $frags as $frag ) { + $formatted_frag = '%' . $wpdb->esc_like( strtolower( trim( $frag ) ) ) . '%'; + $query = "{$table_alias}.meta_value LIKE %s"; + $where_frags[] = $wpdb->prepare( $query, $formatted_frag ); + } + + return sprintf( '(%s)', implode( " \n\tAND ", $where_frags ) ); + } +} diff --git a/tribe-common/src/Tribe/Duplicate/Strategy/Same.php b/tribe-common/src/Tribe/Duplicate/Strategy/Same.php new file mode 100644 index 0000000000..b91e52c5ce --- /dev/null +++ b/tribe-common/src/Tribe/Duplicate/Strategy/Same.php @@ -0,0 +1,51 @@ +is_a_numeric_post_field( $key ) ) { + return $wpdb->prepare( "{$key} = %d", $value ); + } + + return $wpdb->prepare( "{$key} = %s", $value ); + } + + /** + * Returns a string suitable to be used as a WHERE clause in a SQL query for a custom field JOIN. + * + * @param string $key + * @param mixed $value + * @param string $table_alias + * + * @return string + * + * @since 4.6 + */ + public function where_custom_field( $key, $value, $table_alias ) { + /** @var wpdb $wpdb */ + global $wpdb; + + return $wpdb->prepare( "{$table_alias}.meta_key = %s AND {$table_alias}.meta_value = %s", $key, $value ); + } +} diff --git a/tribe-common/src/Tribe/Duplicate/Strategy_Factory.php b/tribe-common/src/Tribe/Duplicate/Strategy_Factory.php new file mode 100644 index 0000000000..ebfde02192 --- /dev/null +++ b/tribe-common/src/Tribe/Duplicate/Strategy_Factory.php @@ -0,0 +1,108 @@ + 'Tribe__Duplicate__Strategy__Same', + 'same' => 'Tribe__Duplicate__Strategy__Same', + 'like' => 'Tribe__Duplicate__Strategy__Like', + ]; + + /** + * Filters the strategies managed by the strategy factory. + * + * If a 'default' slug is not provided the first strategy class in the map will be used as default. + * + * @param array $strategy_map An array that maps strategy slugs to strategy classes. + * @param Tribe__Duplicate__Strategy_Factory $this This factory object. + * + * @since 4.6 + */ + $this->strategy_map = apply_filters( 'tribe_duplicate_post_strategies', $strategy_map, $this ); + } + + /** + * Builds a strategy provided a strategy slug. + * + * @param string $strategy The slug for the strategy that should be built. + * + * @return Tribe__Duplicate__Strategy__Interface|bool A built strategy or `false` if the strategy could not be built. + * + * @since 4.6 + */ + public function make( $strategy ) { + /** + * Filters the strategy built by the factory. + * + * Returning a non `null` value here will override the factory operations. + * + * @param Tribe__Duplicate__Strategy__Interface $built_strategy The strategy that should be built + * for the slug. + * @param string $strategy The requested strategy slug. + * @param Tribe__Duplicate__Strategy_Factory $this This factory object. + * + * @since 4.6 + */ + $built_strategy = apply_filters( 'tribe_duplicate_post_strategy', null, $strategy, $this ); + + /** + * Filters the strategy built by the factory for a specific strategy. + * + * Returning a non `null` value here will override the factory operations. + * + * @param Tribe__Duplicate__Strategy__Interface $built_strategy The strategy that should be built + * for the slug. + * @param Tribe__Duplicate__Strategy_Factory $this This factory object. + * + * @since 4.6 + */ + $built_strategy = apply_filters( "tribe_duplicate_post_{$strategy}_strategy", $built_strategy, $this ); + + if ( null !== $built_strategy ) { + return $built_strategy; + } + + if ( isset( $this->strategy_map[ $strategy ] ) ) { + $strategy_class = $this->strategy_map[ $strategy ]; + } else { + $strategy_class = ! empty( $this->strategy_map['default'] ) + ? $this->strategy_map['default'] + : reset( $this->strategy_map ); + } + + return class_exists( $strategy_class ) + ? new $strategy_class + : false; + } + + /** + * Gets the unfiltered slug to strategy class map used by the factory. + * + * @return array + * + * @since 4.6 + */ + public function get_strategy_map() { + return $this->strategy_map; + } + + /** + * Sets the unfiltered slug to strategy class map used by the factory. + * + * @param array $strategy_map + * + * @since 4.6 + */ + public function set_strategy_map( array $strategy_map ) { + $this->strategy_map = $strategy_map; + } +} diff --git a/tribe-common/src/Tribe/Editor.php b/tribe-common/src/Tribe/Editor.php new file mode 100644 index 0000000000..81d6f13073 --- /dev/null +++ b/tribe-common/src/Tribe/Editor.php @@ -0,0 +1,258 @@ +is_gutenberg_active() || $this->is_wp_version(); + $blocks = $this->is_blocks_editor_active(); + $classic = $this->is_classic_plugin_active() || $this->is_classic_option_active(); + + $should_load_blocks = $gutenberg && $blocks && ! $classic; + + /** + * Filters whether the Blocks Editor should be activated or not. + * + * @since 4.12.0 + * + * @param bool $should_load_blocks Whether the blocks editor should be activated or not. + */ + $should_load_blocks = (bool) apply_filters( 'tribe_editor_should_load_blocks', $should_load_blocks ); + + return $should_load_blocks; + } + + /** + * Checks if we are on version 5.0-alpha or higher where we no longer have + * Gutenberg Project, but the Blocks Editor + * + * @since 4.8 + * + * @return boolean + */ + public function is_wp_version() { + global $wp_version; + + return version_compare( $wp_version, '5.0-alpha', '>=' ); + } + + /** + * Checks if we have Gutenberg Project online, only useful while + * its a external plugin + * + * @since 4.8 + * + * @return boolean + */ + public function is_gutenberg_active() { + return function_exists( 'the_gutenberg_project' ); + } + + /** + * Checks if we have Editor Block active + * + * @since 4.8 + * + * @return boolean + */ + public function is_blocks_editor_active() { + return function_exists( 'register_block_type' ) && function_exists( 'unregister_block_type' ); + } + + /** + * Adds the required fields into the Events Post Type so that we can use Block Editor + * + * @since 4.8 + * + * @param array $args Arguments used to setup the Post Type + * + * @return array + */ + public function add_support( $args = [] ) { + // Make sure we have the Support argument and it's an array + if ( ! isset( $args['supports'] ) || ! is_array( $args['supports'] ) ) { + $args['supports'] = []; + } + + // Add Editor Support + if ( ! in_array( 'editor', $args['supports'] ) ) { + $args['supports'][] = 'editor'; + } + + return $args; + } + + /** + * Adds the required fields into the Post Type so that we can the Rest API to update it + * + * @since 4.8 + * + * @param array $args Arguments used to setup the Post Type + * + * @return array + */ + public function add_rest_support( $args = [] ) { + // Blocks Editor requires REST support + $args['show_in_rest'] = true; + + // Make sure we have the Support argument and it's an array + if ( ! isset( $args['supports'] ) || ! is_array( $args['supports'] ) ) { + $args['supports'] = []; + } + + if ( ! in_array( 'revisions', $args['supports'] ) ) { + $args['supports'][] = 'revisions'; + } + + // Add Custom Fields (meta) Support + if ( ! in_array( 'custom-fields', $args['supports'] ) ) { + $args['supports'][] = 'custom-fields'; + } + + // Add Post Title Support + if ( ! in_array( 'title', $args['supports'] ) ) { + $args['supports'][] = 'title'; + } + + // Add Post Excerpt Support + if ( ! in_array( 'excerpt', $args['supports'] ) ) { + $args['supports'][] = 'excerpt'; + } + + // Add Post Content Support + if ( ! in_array( 'editor', $args['supports'] ) ) { + $args['supports'][] = 'editor'; + } + + // Add Post Author Support + if ( ! in_array( 'author', $args['supports'] ) ) { + $args['supports'][] = 'author'; + } + + // Add Thumbnail Support + if ( ! in_array( 'thumbnail', $args['supports'] ) ) { + $args['supports'][] = 'thumbnail'; + } + + return $args; + } + + /** + * classic_editor_replace is function that is created by the plugin: + * + * @see https://wordpress.org/plugins/classic-editor/ + * + * prior 1.3 version the classic editor plugin was bundle inside of a unique function: + * `classic_editor_replace` now all is bundled inside of a class `Classic_Editor` + * + * @since 4.8 + * + * @return bool + */ + public function is_classic_plugin_active() { + $is_plugin_active = function_exists( 'classic_editor_replace' ) || class_exists( 'Classic_Editor' ); + /** + * Filter to change the output of calling: `is_classic_plugin_active` + * + * @since 4.9.12 + * + * @param $is_plugin_active bool Value that indicates if the plugin is active or not. + */ + return apply_filters( 'tribe_is_classic_editor_plugin_active', $is_plugin_active ); + } + + /** + * Check if the setting `'classic-editor-replace'` is set to `replace` that option means to + * replace the gutenberg editor with the classic editor. + * + * Prior to 1.3 on classic editor plugin the value to identify if is on classic the value + * was `replace`, now the value is `classic` + * + * @since 4.8 + * + * @return bool + */ + public function is_classic_option_active() { + $valid_values = [ 'replace', 'classic' ]; + + return in_array( (string) get_option( 'classic-editor-replace' ), $valid_values, true ); + } + + /** + * Detect if the classic editor is force-activated via plugin or if it comes from a request. + * + * @since 4.8 + * + * @return bool + */ + public function is_classic_editor() { + $disabled_by_plugin = $this->is_classic_plugin_active() && $this->is_classic_option_active(); + + /** + * Allow other addons to disable classic editor based on options. + * + * @since 4.8.5 + * + * @param bool $classic_is_active Whether the classic editor should be used. + */ + $disabled_by_filter = apply_filters( 'tribe_editor_classic_is_active', false ); + + $is_classic_editor_request = tribe_get_request_var( 'classic-editor', null ); + + return $is_classic_editor_request || $disabled_by_plugin || $disabled_by_filter; + } + + /** + * Whether the events are being served using Blocks or the Classical Editor. + * + * @since 4.12.0 + * + * @return bool True if using Blocks. False if using the Classical Editor. + */ + public function is_events_using_blocks() { + /** + * Whether the event is being served through blocks + * or the classical editor. + * + * @since 4.12.0 + * + * @param bool $is_using_blocks True if using blocks. False if using the classical editor. + */ + $is_using_blocks = apply_filters( 'tribe_is_using_blocks', null ); + + // Early bail: The filter was overridden to return either true or false. + if ( null !== $is_using_blocks ) { + return $is_using_blocks; + } + + // Early bail: The site itself is not using blocks. + if ( ! $this->should_load_blocks() ) { + return false; + } + + return tribe_is_truthy( tribe_get_option( 'toggle_blocks_editor' ) ); + } +} diff --git a/tribe-common/src/Tribe/Editor/Assets.php b/tribe-common/src/Tribe/Editor/Assets.php new file mode 100644 index 0000000000..8f4a363b27 --- /dev/null +++ b/tribe-common/src/Tribe/Editor/Assets.php @@ -0,0 +1,259 @@ + false, + 'localize' => [ + [ + 'name' => 'tribe_editor_config', + /** + * Array used to setup the FE with custom variables from the BE + * + * @since 4.8 + * + * @param array An array with the variables to be localized + */ + 'data' => tribe_callback( 'common.editor.configuration', 'localize' ), + ], + ], + 'priority' => 11, + ] + ); + + tribe_asset( + $plugin, + 'tribe-common-gutenberg-utils', + 'app/utils.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 12, + ] + ); + tribe_asset( + $plugin, + 'tribe-common-gutenberg-store', + 'app/store.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 13, + ] + ); + tribe_asset( + $plugin, + 'tribe-common-gutenberg-icons', + 'app/icons.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 14, + ] + ); + tribe_asset( + $plugin, + 'tribe-common-gutenberg-hoc', + 'app/hoc.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 15, + ] + ); + tribe_asset( + $plugin, + 'tribe-common-gutenberg-components', + 'app/components.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 16, + ] + ); + tribe_asset( + $plugin, + 'tribe-common-gutenberg-elements', + 'app/elements.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 17, + ] + ); + /** + * @todo: figure out why element styles are loading for tickets but not events. + */ + tribe_asset( + $plugin, + 'tribe-common-gutenberg-components', + 'app/components.js', + /** + * @todo revise this dependencies + */ + [ + 'react', + 'react-dom', + 'wp-components', + 'wp-api', + 'wp-api-request', + 'wp-blocks', + 'wp-i18n', + 'wp-element', + 'wp-editor', + ], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + 'localize' => [], + 'priority' => 17, + ] + ); + tribe_asset( + $plugin, + 'tribe-common-gutenberg-elements-styles', + 'app/elements.css', + [], + 'enqueue_block_editor_assets', + [ + 'in_footer' => false, + ] + ); + } +} diff --git a/tribe-common/src/Tribe/Editor/Blocks/Abstract.php b/tribe-common/src/Tribe/Editor/Blocks/Abstract.php new file mode 100644 index 0000000000..7474ce2f5e --- /dev/null +++ b/tribe-common/src/Tribe/Editor/Blocks/Abstract.php @@ -0,0 +1,237 @@ +slug(), $this->namespace . '/' ) ) { + return $this->namespace . '/' . $this->slug(); + } else { + return $this->slug(); + } + } + + /** + * Return the namespace to child or external sources + * + * @since 4.8 + * + * @return string + */ + public function get_namespace() { + return $this->namespace; + } + + /** + * Return the block attributes + * + * @since 4.8 + * + * @param array $attributes + * + * @return array + */ + public function attributes( $params = [] ) { + + // get the default attributes + $default_attributes = $this->default_attributes(); + + // parse the attributes with the default ones + $attributes = wp_parse_args( + $params, + $default_attributes + ); + + /** + * Filters the default attributes for the block + * + * @param array $attributes The attributes + * @param object $this The current object + */ + $attributes = apply_filters( 'tribe_block_attributes_defaults_' . $this->slug(), $attributes, $this ); + + return $attributes; + } + + /** + * Return the block default attributes + * + * @since 4.8 + * + * @param array $attributes + * + * @return array + */ + public function default_attributes() { + + $attributes = []; + + /** + * Filters the default attributes + * + * @param array $params The attributes + * @param object $this The current object + */ + $attributes = apply_filters( 'tribe_block_attributes_defaults', $attributes, $this ); + + return $attributes; + } + + /** + * Since we are dealing with a Dynamic type of Block we need a PHP method to render it + * + * @since 4.8 + * + * @param array $attributes + * + * @return string + */ + public function render( $attributes = [] ) { + $json_string = json_encode( $attributes, JSON_PRETTY_PRINT ); + + return + '
          ' .
          +			'Block Name: ' . $this->name() . "\n" .
          +			'Block Attributes: ' . "\n" . $json_string .
          +		'
          '; + } + + /** + * Sends a valid JSON response to the AJAX request for the block contents + * + * @since 4.8 + * + * @return void + */ + public function ajax() { + wp_send_json_error( esc_attr__( 'Problem loading the block, please remove this block to restart.', 'tribe-common' ) ); + } + + /** + * Does the registration for PHP rendering for the Block, important due to been + * an dynamic Block + * + * @since 4.8 + * + * @return void + */ + public function register() { + $block_args = [ + 'render_callback' => [ $this, 'render' ], + ]; + + register_block_type( $this->name(), $block_args ); + + add_action( 'wp_ajax_' . $this->get_ajax_action(), [ $this, 'ajax' ] ); + + $this->assets(); + $this->hook(); + } + + /** + * Determine whether a post or content string has this block. + * + * This test optimizes for performance rather than strict accuracy, detecting + * the pattern of a block but not validating its structure. For strict accuracy + * you should use the block parser on post content. + * + * @since 4.8 + * + * @see gutenberg_parse_blocks() + * + * @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post. + * + * @return bool Whether the post has this block. + */ + public function has_block( $post = null ) { + if ( ! is_numeric( $post ) ) { + $wp_post = get_post( $post ); + if ( $wp_post instanceof WP_Post ) { + $post = $wp_post->post_content; + } + } + + return false !== strpos( (string) $post, '\s*$/im'; + return $this->update_post_content( $post_id, $patttern, $replacement ); + } + + /** + * Function used to remove the inner blocks and the parent block as well inside of a post_content + * + * @since 4.8.2 + * + * @param $post_id + * @param $block_name The name of the block + * @param string $replacement The string used to replace the value of the searched block + * + * @return bool + */ + public function remove_inner_blocks( $post_id, $block_name, $replacement = '' ) { + $pattern = '/^\s*\s.*/ims'; + return $this->update_post_content( $post_id, $pattern, $replacement ); + } + + /** + * Update the content of a post using a pattern to search a specifc string, with a custom + * replacement + * + * @since 4.8.2 + * + * @param $post_id + * @param $pattern + * @param string $replacement The string used to replace the value of the searched block + * + * @return bool + */ + public function update_post_content( $post_id, $pattern, $replacement = '' ) { + $content = get_post_field( 'post_content', $post_id ); + + if ( empty( $content ) ) { + return false; + } + + $next_content = preg_replace( $pattern, $replacement, $content ); + + /** + * Don't update post content if preg_replace fails or content is the update_content + * is same as current content on the post to avoid a DB operation. + */ + if ( $next_content === null || $next_content === $content ) { + return false; + } + + return wp_update_post( [ + 'ID' => $post_id, + 'post_content' => $next_content, + ] ); + } + + /** + * Strip the dynamic blocks of the content + * + * @since 4.8.5 + * + * @param string $content The event content + * + * @return string + */ + public function strip_dynamic_blocks( $content = '' ) { + + if ( ! function_exists( 'strip_dynamic_blocks' ) ) { + return $content; + } + + return strip_dynamic_blocks( $content ); + + } + + /** + * Return the content without the tribe blocks + * + * @since 4.8.5 + * + * @param string $content The event content + * + * @return string + */ + public function exclude_tribe_blocks( $content = '' ) { + + $match_blocks_exp = '/\<\!\-\- \/?wp\:tribe.*\/?-->/i'; + + if ( ! preg_match( $match_blocks_exp, $content ) ) { + return $content; + } + + return preg_replace( $match_blocks_exp, '', $content ); + } +} diff --git a/tribe-common/src/Tribe/Error.php b/tribe-common/src/Tribe/Error.php new file mode 100644 index 0000000000..c91d0c0d5d --- /dev/null +++ b/tribe-common/src/Tribe/Error.php @@ -0,0 +1,200 @@ +register( 'unknown', esc_html__( 'An Unknown error occurred' ) ); + } + + /** + * Make a quickly usable method to transform code/indexes to WP_Errors + * + * @see tribe_error() + * + * @param string|array $indexes Which Error we are looking for + * @param array $context Gives the Error context + * @param array $sprintf Allows variables on the message + * + * @return WP_Error + */ + public function send( $indexes, $context = [], $sprintf = [] ) { + if ( ! $this->exists( $indexes ) ) { + $indexes = [ 'unknown' ]; + } + + // Fetches the Errors + $messages = (array) $this->get( $indexes ); + $error = new WP_Error; + + foreach ( $messages as $key => $message ) { + // Allows variables when sending the message + if ( ! empty( $sprintf ) ) { + $message = vsprintf( $message, $sprintf ); + } + // Add this Message to the WP_Error + $error->add( $key, $message, $context ); + } + + return $error; + } + + /** + * Register a new error based on a Namespace + * + * @param string|array $indexes A list of the namespaces and last item should be the error name + * @param string $message What is going to be the message associate with this indexes + * + * @return boolean + */ + public function register( $indexes, $message ) { + if ( is_string( $indexes ) ) { + // Each namespace should come with `:` + $indexes = (array) explode( ':', $indexes ); + } + + // Couldn't register the error + if ( empty( $indexes ) ) { + return false; + } + + $variable = &$this->items; + $count = count( $indexes ); + + // Will create the Indexes based on the $slug + foreach ( $indexes as $i => $index ) { + if ( $count === $i + 1 ) { + $variable[ $index ] = $message; + } else { + $variable = &$variable[ $index ]; + } + } + + // Allows Chain Reactions + return true; + } + + /** + * Removes an error from the items + * + * @param string|array $indexes A list of the namespaces and last item should be the error name + * + * @return boolean + */ + public function remove( $indexes ) { + if ( ! $this->exists( $indexes ) ) { + return false; + } + + if ( is_string( $indexes ) ) { + // Each namespace should come with `:` + $indexes = (array) explode( ':', $indexes ); + } + + // Ensures that we don't modify the original + $variable = &$this->items; + $count = count( $indexes ); + + foreach ( $indexes as $i => $index ) { + if ( $count === $i + 1 ) { + unset( $variable[ $index ] ); + } else { + $variable = &$variable[ $index ]; + } + } + + return true; + } + + /** + * Fetches the error or namespace + * + * @param string|array $indexes (optional) A list of the namespaces and last item should be the error name + * + * @return null|array|string + */ + public function get( $indexes = null ) { + if ( is_null( $indexes ) ) { + return $this->items; + } + + if ( is_string( $indexes ) ) { + // Each namespace should come with `:` + $indexes = (array) explode( ':', $indexes ); + } + + // Ensures that we don't modify the original + $variable = $this->items; + $count = count( $indexes ); + + foreach ( $indexes as $i => $index ) { + if ( ! isset( $variable[ $index ] ) ) { + // If we are on the last item and we don't have it set make it Null + if ( $count === $i + 1 ) { + return null; + } + continue; + } + + $variable = $variable[ $index ]; + } + + $return = []; + $was_namespace = is_array( $variable ); + + /** + * @todo Allow fetching bigger groups + * Right now you can only fetch the first group of messages + * Trying to fetch Namespaces that contain other namespaces will bug + */ + foreach ( (array) $variable as $key => $value ) { + $key = implode( ':', $indexes ) . ( $was_namespace ? ':' . $key : '' ); + $return[ $key ] = $value; + } + + return $return; + } + + /** + * Checks if a given error or namespace exists + * + * @param string|array $indexes A list of the namespaces and last item should be the error name + * + * @return boolean + */ + public function exists( $indexes ) { + $variable = $this->get( $indexes ); + return ! empty( $variable ) || is_array( $variable ) ? true : false; + } +} diff --git a/tribe-common/src/Tribe/Exception.php b/tribe-common/src/Tribe/Exception.php new file mode 100644 index 0000000000..48e6c86c79 --- /dev/null +++ b/tribe-common/src/Tribe/Exception.php @@ -0,0 +1,90 @@ +original_exception = $original_exception; + } + + /** + * Handles the exception throwing the original when debugging (`WP_DEBUG` defined and `true`) + * or quietly logging when `WP_DEBUG` is `false` or not set. + * + * @return bool `true` if the message was logged, `false` otherwise. + * + * @throws Exception + */ + public function handle() { + $debug = defined( 'WP_DEBUG' ) && WP_DEBUG; + + if ( $debug ) { + $this->throw_original_exception(); + } + + return $this->log_original_exception_message(); + } + + /** + * @return string + */ + private function get_log_type_for_exception_code( $code ) { + $map = array( + // @todo [BTRIA-583]: Let's add a decent exception code to log type map here. + ); + + return isset( $map[ $code ] ) ? $map[ $code ] : Tribe__Log::ERROR; + } + + /** + * Throws the original exception. + * + * Provided as a manual override over the default `WP_DEBUG` dependent behaviour. + * + * @see Tribe__Exception::handle() + * + * @throws Exception + */ + public function throw_original_exception() { + throw $this->original_exception; + } + + /** + * Logs the original exception message. + * + * Provided as a manual override over the default `WP_DEBUG` dependent behaviour. + * + * @see Tribe__Exception::handle() + * + * @return bool `true` if the message was logged, `false` otherwise. + */ + private function log_original_exception_message() { + if ( ! class_exists( 'Tribe__Log' ) ) { + return false; + } + + $logger = new Tribe__Log(); + $message = $this->original_exception->getMessage(); + $log_type = $this->get_log_type_for_exception_code( $this->original_exception->getCode() ); + $src = $this->original_exception->getFile() . ':' . $this->original_exception->getLine(); + + $logger->log( $message, $log_type, $src ); + + return true; + } +} diff --git a/tribe-common/src/Tribe/Extension.php b/tribe-common/src/Tribe/Extension.php new file mode 100644 index 0000000000..021008bebf --- /dev/null +++ b/tribe-common/src/Tribe/Extension.php @@ -0,0 +1,454 @@ +args = $args; + $this->construct(); + + // The init() action/hook. + $init_hook = $this->get_init_hook(); + + // Continue plugin run after $init_hook has fired. + if ( did_action( $init_hook ) > 0 ) { + $this->register(); + } else { + add_action( $init_hook, [ $this, 'register' ] ); + } + } + + /** + * Empty function typically overridden by child class + */ + protected function construct() {} + + /** + * This is where the magic begins + * + * Declare this inside the child and put any custom code inside of it. + */ + abstract public function init(); + + /** + * Adds a Tribe Plugin to the list of plugins this extension depends upon. + * + * If this plugin is not present or does not exceed the specified version + * init() will not run. + * + * @param string $main_class The Main class for this Tribe plugin. + * @param string|null $minimum_version Minimum acceptable version of plugin. + */ + final protected function add_required_plugin( $main_class, $minimum_version = null ) { + $this->set( [ 'requires', $main_class ], $minimum_version ); + } + + /** + * Set the extension's tec.com URL + * + * @param string $url URL to the extension's page. + */ + final protected function set_url( $url ) { + $this->set( 'url', $url ); + + // Adds this as a tutorial link to Wp Admin > Plugins page. + Tribe__Plugin_Meta_Links::instance()->add_link( + $this->get_plugin_file(), + __( 'Tutorial', 'tribe-common' ), + $url, + [ 'class' => 'tribe-meta-link-extension' ] + ); + } + + /** + * Set the extension's version number + * + * @param string $version Extensions semantic version number. + */ + final protected function set_version( $version ) { + $this->set( 'version', $version ); + } + + /** + * Checks if the extension has permission to run, if so runs init() in child class + */ + final public function register() { + $extension_file = $this->get_plugin_file(); + $extension_class_name = $this->get( 'class' ); + $extension_version = $this->get_version(); + $plugins_required = $this->get( 'requires', [] ); + + tribe_register_plugin( + $extension_file, + $extension_class_name, + $extension_version, + $plugins_required + ); + + $dependency = Tribe__Dependency::instance(); + + // check requisite plugins are active for this extension + $is_plugin_authorized = $dependency->has_requisite_plugins( $plugins_required ); + + /** + * Explicitly disallow an extension, such as a core plugin having absorbed/replaced its functionality. + * + * @since 4.12.2 + * + * @param bool $is_disallowedย ย ย  False by default. + * @param string $extension_class_name This extension's class name string + * (without initial forward slash for namespaced classes). + * @param Tribe__Extension $this_instance This extension class' instance. + */ + $is_disallowed = (bool) apply_filters( 'tribe_extension_is_disallowed', false, $extension_class_name, $this ); + + if ( $is_disallowed ) { + if ( + is_admin() + && current_user_can( 'activate_plugins' ) + ) { + tribe_notice( 'tribe_extension_is_disallowed', [ $this, 'notice_disallowed' ], [ 'type' => 'error' ] ); + } + + deactivate_plugins( $extension_file, true ); + + return; + } + + if ( $is_plugin_authorized ) { + $this->init(); + + // Add extension as active to dependency checker. + $dependency->add_active_plugin( $extension_class_name, $extension_version, $extension_file ); + } + } + + /** + * Gets the full path to the extension's plugin file + * + * Sets default if the arg is blank. + * + * @return string File path + */ + final public function get_plugin_file() { + $file = $this->get( 'file' ); + + // If this is not set assume the extension's plugin class is the plugin file. + if ( empty( $file ) ) { + $reflection = new ReflectionClass( $this->get( 'class' ) ); + $file = $reflection->getFileName(); + $this->set( 'file', $file ); + } + + return $file; + } + + /** + * Get the extension's version number + * + * @return string Semantic version number + */ + final public function get_version() { + return $this->get_arg_or_plugin_data( 'version', 'Version' ); + } + + /** + * Get the extension's plugin name + * + * @return string Plugin name + */ + final public function get_name() { + return $this->get_arg_or_plugin_data( 'name', 'Name' ); + } + + /** + * Get the extension's description + * + * @return string Plugin description + */ + final public function get_description() { + return $this->get_arg_or_plugin_data( 'description', 'Description' ); + } + + /** + * Gets the action/hook for the extensions' init(). + * + * @return string Action/hook + */ + final public function get_init_hook() { + return $this->get( 'hook', 'tribe_plugins_loaded' ); + } + + /** + * Gets the plugin data from the plugin file header + * + * This is somewhat resource intensive, so data is stored in $args + * in case of subsequent calls. + * + * @see get_plugin_data() for WP Admin only function this is similar to. + * + * @return array Plugin data; keys match capitalized file header declarations. + */ + final public function get_plugin_data() { + $plugin_data = $this->get( 'plugin_data' ); + + // Set the plugin data arg/cache to match. + if ( empty( $plugin_data ) ) { + $plugin_data = $this->set( 'plugin_data', Tribe__Utils__Plugins::get_plugin_data( $this->get_plugin_file() ) ); + } + + return $plugin_data; + } + + /** + * Retrieves any args whose default value is stored in the plugin file header + * + * @param string $arg The key for arg. + * @param string $plugin_data_key The key for the arg in the file header. + * + * @return string|null String if set, otherwise null. + */ + final public function get_arg_or_plugin_data( $arg, $plugin_data_key ) { + $arg_value = $this->get( $arg, null ); + + // See if the arg is already set, if not get default from plugin data and set it. + if ( null === $arg_value ) { + $pdata = $this->get_plugin_data(); + $arg_value = isset( $pdata[ $plugin_data_key ] ) ? $pdata[ $plugin_data_key ] : null; + } + + return $arg_value; + } + + /** + * Sets an arg, including one nested a few levels deep + * + * @param string|array $key To set an arg nested multiple levels deep pass an array + * specifying each key in order as a value. + * Example: array( 'lvl1', 'lvl2', 'lvl3' ); + * @param mixed $value The value. + */ + final protected function set( $key, $value ) { + $this->args = Tribe__Utils__Array::set( $this->args, $key, $value ); + } + + /** + * Retrieves arg, including one nested a few levels deep + * + * @param string|array $key To select an arg nested multiple levels deep pass an + * array specifying each key in order as a value. + * Example: array( 'lvl1', 'lvl2', 'lvl3' ); + * @param null $default Value to return if nothing is set. + * + * @return mixed Returns the args value or the default if arg is not found. + */ + final public function get( $key, $default = null ) { + return Tribe__Utils__Array::get( $this->args, $key, $default ); + } + + /** + * Gets the name of the class the method is called in; typically will be a child class + * + * This uses some hackery if the server is on PHP 5.2, and it can fail in rare + * circumstances causing a null value to be returned. + * + * @return string|null Class name + */ + final protected static function get_called_class() { + $class_name = null; + + if ( function_exists( 'get_called_class' ) ) { + // For PHP 5.3+ we can use the late static binding class name. + $class_name = get_called_class(); + } else { + // For PHP 5.2 and under we hack around the lack of late static bindings. + try { + $backtraces = debug_backtrace(); + + // Grab each class from the backtrace. + foreach ( $backtraces as $i ) { + $class = null; + + if ( array_key_exists( 'class', $i ) ) { + // Direct call to a class. + $class = $i['class']; + } elseif ( + array_key_exists( 'function', $i ) && + strpos( $i['function'], 'call_user_func' ) === 0 && + array_key_exists( 'args', $i ) && + is_array( $i['args'] ) && + is_array( $i['args'][0] ) && + isset( $i['args'][0][0] ) + ) { + // Found a call from call_user_func... and $i['args'][0][0] is present + // indicating a static call to a method. + $class = $i['args'][0][0]; + } else { + // Slight performance boost from skipping ahead. + continue; + } + + // Check to see if the parent is the current class. + // The first backtrace with a matching parent is our class. + if ( get_parent_class( $class ) === __CLASS__ ) { + $class_name = $class; + break; + } + } + } catch ( Exception $e ) { + // Host has disabled or misconfigured debug_backtrace(). + $exception = new Tribe__Exception( $e ); + $exception->handle(); + } + } + + // Class name was not set by debug_backtrace() hackery. + if ( null === $class_name ) { + tribe_notice( 'tribe_debug_backtrace_disabled', [ __CLASS__, 'notice_debug_backtrace' ] ); + } + + return $class_name; + } + + /** + * Echoes error message indicating user is on PHP 5.2 and debug_backtrace is disabled + */ + final public static function notice_debug_backtrace() { + printf( + '

          %s

          ', + esc_html__( 'Unable to run Tribe Extensions. Your website host is running PHP 5.2 or older, and has likely disabled or misconfigured debug_backtrace(). You, or your website host, will need to upgrade PHP or properly configure debug_backtrace() for Tribe Extensions to work.', 'tribe-common' ) + ); + } + + /** + * Gets the error message about being explicitly disallowed. + * + * @since 4.12.2 + * + * @return string Notice text. + */ + public function notice_disallowed() { + return sprintf( + '

          %1$s: %2$s

          ', + $this->get_name(), + esc_html_x( + "This extension has been programmatically disallowed. The most common reason is due to another The Events Calendar plugin having absorbed or replaced this extension's functionality. This extension plugin has been deactivated, and you should likely delete it.", + 'extension disallowed', + 'tribe-common' + ) + ); + } + + /** + * Prevent cloning the singleton with 'clone' operator + * + * @return void + */ + final public function __clone() { + _doing_it_wrong( + __FUNCTION__, + 'Can not use this method on singletons.', + '4.3' + ); + } + + /** + * Prevent unserializing the singleton instance + * + * @return void + */ + final public function __wakeup() { + _doing_it_wrong( + __FUNCTION__, + 'Can not use this method on singletons.', + '4.3' + ); + } +} diff --git a/tribe-common/src/Tribe/Extension_Loader.php b/tribe-common/src/Tribe/Extension_Loader.php new file mode 100644 index 0000000000..da1271b87f --- /dev/null +++ b/tribe-common/src/Tribe/Extension_Loader.php @@ -0,0 +1,168 @@ +instantiate_extension( $plugin_file ); + } + } + + /** + * Gets tribe extension plugin foldername prefixes + * + * @return array Prefixes + */ + public static function get_extension_file_prefixes() { + $prefixes = [ 'tribe-ext-' ]; + + /** + * Filter which plugin folder prefixes are considered tribe extensions. + * + * @param array $prefixes Extension plugin folder name prefixes. + */ + return apply_filters( 'tribe_extension_prefixes', $prefixes ); + } + + /** + * Instantiates an extension based on info in its plugin file header. + * + * @param string $plugin_file Full path to extension's plugin file header. + * + * @return bool Indicates if extension was instantiated successfully. + */ + public function instantiate_extension( $plugin_file ) { + $p_data = $this->get_cached_plugin_data( $plugin_file ); + $p_folder = trailingslashit( dirname( $plugin_file ) ); + $success = false; + + // Nothing to instantiate if class is not set. + if ( empty( $p_data['ExtensionClass'] ) ) { + return $success; + } + + // Default to plugin file when empty. + $class_file = ! empty( $p_data['ExtensionFile'] ) ? $p_folder . $p_data['ExtensionFile'] : $plugin_file; + + // Include file. + if ( file_exists( $class_file ) ) { + // Prevent loading class twice in edge cases where require_once wouldn't work. + if ( ! class_exists( $p_data['ExtensionClass'] ) ) { + require( $class_file ); + } + } else { + _doing_it_wrong( + esc_html( $class_file ), + 'Extension file does not exist, please specify valid extension file.', + '4.3' + ); + } + + // Class instantiation. + if ( class_exists( $p_data['ExtensionClass'] ) ) { + $extension_args = [ + 'file' => $plugin_file, + 'plugin_data' => $p_data, + ]; + + // Instantiates extension instance. + $extension = call_user_func( + [ $p_data['ExtensionClass'], 'instance' ], + $p_data['ExtensionClass'], + $extension_args + ); + + if ( null !== $extension ) { + $success = true; + } + } else { + _doing_it_wrong( + esc_html( $p_data['ExtensionClass'] ), + 'Specified extension class does not exist. Please double check that this class is declared in the extension file.', + '4.3' + ); + } + + return $success; + } + + /** + * Retrieves plugin data from cache if it exists. + * + * @param string $plugin_path Path to plugin header file. + * + * @return array|null Plugin data or null. + */ + public function get_cached_plugin_data( $plugin_path ) { + $plugin_basename = plugin_basename( $plugin_path ); + + if ( ! array_key_exists( $plugin_basename, $this->plugin_data ) ) { + $this->plugin_data[ $plugin_basename ] = Tribe__Utils__Plugins::get_plugin_data( $plugin_path ); + } + + return $this->plugin_data[ $plugin_basename ]; + } + + /** + * Prevent cloning the singleton with 'clone' operator + * + * @return void + */ + public function __clone() { + _doing_it_wrong( + __FUNCTION__, + 'Can not use this method on singletons.', + '4.3' + ); + } + + /** + * Prevent unserializing the singleton instance + * + * @return void + */ + public function __wakeup() { + _doing_it_wrong( + __FUNCTION__, + 'Can not use this method on singletons.', + '4.3' + ); + } +} diff --git a/tribe-common/src/Tribe/Feature_Detection.php b/tribe-common/src/Tribe/Feature_Detection.php new file mode 100644 index 0000000000..da59664192 --- /dev/null +++ b/tribe-common/src/Tribe/Feature_Detection.php @@ -0,0 +1,258 @@ + 6000, + ]; + + /** + * The name of the option that will be used to indicate a feature detection is running. + * + * @var string + */ + protected $lock_option_name; + + /** + * Checks whether async, AJAX-based, background processing is supported or not. + * + * To avoid making this costly check on each load the result of this check is cached + * in the `tribe_feature_detection` transient, under the `supports_async_process` key. + * + * @since 4.7.23 + * + * @param bool $force Whether to use the cache value, if available, or force the check + * to be made again. + * + * @return bool Whether async, AJAX-based, background processing is supported or not. + */ + public function supports_async_process( $force = false ) { + /** + * Filters whether async, AJAX-based, processing is supported or not. + * + * Returning a non `null` value here will make this method bail and + * return the filtered value immediately. + * + * @since 4.7.23 + * + * @param bool $supports_async_process Whether async, AJAX-based, processing is supported or not. + * @param bool $force Whether the check is forcing the cached value to be refreshed + * or not. + */ + $supports_async_process = apply_filters( 'tribe_supports_async_process', null, $force ); + if ( null !== $supports_async_process ) { + return (bool) $supports_async_process; + } + + $cached = get_transient( self::$transient ); + + $this->lock_option_name = 'tribe_feature_support_check_lock'; + if ( + $force + || false === $cached + || ( is_array( $cached ) && ! isset( $cached['supports_async_process'] ) ) + ) { + if ( $this->is_locked() ) { + // We're already running this check, bail and return the safe option for the time being. + return false; + } + + // Let's avoid race conditions by running two or more checks at the same time. + $this->lock(); + + // Log that we're checking for AJAX-based async process support using the tester. + tribe( 'logger' )->log( 'Checking for AJAX-based async processing support triggering a test request.', Tribe__Log::DEBUG ); + + /* + * Build and dispatch the tester: if it works a transient should be set. + */ + $tester = new Tribe__Process__Tester(); + tribe( 'logger' )->log( 'Dispatching AJAX-based async processing support test request.', Tribe__Log::DEBUG ); + $tester->dispatch(); + + $wait_up_to = 10; + $start = time(); + $supports_async_process = false; + $transient_name = Tribe__Process__Tester::TRANSIENT_NAME; + + while ( time() <= $start + $wait_up_to ) { + // We want to force a refetch from the database on each check. + wp_cache_delete( $transient_name, 'transient' ); + $supports_async_process = (bool) get_transient( $transient_name ); + + if ( $supports_async_process ) { + break; + } + sleep( $wait_up_to / 5 ); + } + + // Remove it not to spoof future checks. + delete_transient( $transient_name ); + + $this->unlock(); + + $cached['supports_async_process'] = $supports_async_process; + + if ( $supports_async_process ) { + tribe( 'logger' )->log( 'AJAX-based async processing is supported.', Tribe__Log::DEBUG ); + } else { + tribe( 'logger' )->log( 'AJAX-based async processing is not supported; background processing will rely on WP Cron.', Tribe__Log::DEBUG ); + } + + set_transient( self::$transient, $cached, WEEK_IN_SECONDS ); + } + + return $cached['supports_async_process']; + } + + /** + * Sets the lock option to `1` to indicate a feature detection is running. + * + * @since 4.8.1 + */ + protected function lock() { + update_option( $this->lock_option_name, '1' ); + } + + /** + * Deletes the lock option to indicate the current feature detection process is done. + * + * @since 4.8.1 + */ + protected function unlock() { + delete_option( $this->lock_option_name ); + } + + /** + * Checks whether a feature detection lock is currently in place or not. + * + * @since 4.8.1 + * + * @return bool Whether a feature detection lock is currently in place or not. + */ + protected function is_locked() { + $lock_option = get_option( $this->lock_option_name ); + + return ! empty( $lock_option ); + } + + /** + * Returns the value of the `max_allowed_packet` MYSQL variable, if set, or a default value. + * + * @since 4.10.2 + * + * @return int The byte size of the `max_allowed_packet` MYSQL variable. + */ + public function get_mysql_max_packet_size() { + /** + * Filters the value of the `max_allowed_packet` variable before it's read from the database. + * + * If the value returned from this filter is not `null`, then it will be assumed to be the value. + * + * @since 4.10.2 + * + * @param int $mysql_max_packet_size The value of the `max_allowed_packet` variable, initially `null`. + */ + $mysql_max_packet_size = apply_filters( 'tribe_max_allowed_packet_size', null ); + + if ( null !== $mysql_max_packet_size ) { + return absint( $mysql_max_packet_size ); + } + + /** @var Tribe__Cache $cache */ + $cache = tribe( 'cache' ); + + $cached = $cache->get( 'max_allowed_packet' ); + + if ( false !== $cached ) { + return $cached; + } + + global $wpdb; + $mysql_max_packet_size = $wpdb->get_var( "SHOW VARIABLES LIKE 'max_allowed_packet'", 1 ); + // At min set it to 2 MBs. + $mysql_max_packet_size = absint( max( absint( $mysql_max_packet_size ), 2097152 ) ); + + $cache->set( 'max_allowed_packet', $mysql_max_packet_size, WEEK_IN_SECONDS ); + + return $mysql_max_packet_size; + } + + /** + * Returns the suggested SQL LIMIT value, based on the `max_allowed_packet` size and example string length. + * + * This is useful to size "reasonable" LIMITs when dealing with either very long queries or potentially long + * result sets. + * + * @since 4.10.2 + * + * @param string $example_string The example string. + * + * @return int The suggested LIMIT value. + */ + public function mysql_limit_for_string( $example_string ) { + $byte_size = function_exists( 'mb_strlen' ) + ? mb_strlen( $example_string ) + : strlen( $example_string ); + + return $this->mysql_limit_for_size( $byte_size ); + } + + /** + * Returns the SQL LIMIT for a byte size, in relation to the `max_allowed_packet` value. + * + * @since 4.10.2 + * + * @param int $byte_size The byte size to check. + * + * @return int The SQL LIMIT value. + */ + public function mysql_limit_for_size( $byte_size ) { + return absint( floor( $this->get_mysql_max_packet_size() / $byte_size ) * 0.8 ); + } + + /** + * Provides the SQL LIMIT value, in relation to the `max_allowed_packet` value, for a pre-existing example. + * + * Defaults to the complete post result example string if the example is not found. + * + * @since 4.10.2 + * + * @param string $example The name of the example to return. See the `Tribe__Feature_Detection::$example_sizes` + * prop for the available examples. Defaults to the `post_result` one. + * + * @return int The SQL LIMIT value for the example. + */ + public function mysql_limit_for_example( $example ) { + $example_size = Arr::get( static::$example_size, $example, static::$example_size['post_result'] ); + + return $this->mysql_limit_for_size( $example_size ); + } +} diff --git a/tribe-common/src/Tribe/Field.php b/tribe-common/src/Tribe/Field.php new file mode 100755 index 0000000000..ad14799e85 --- /dev/null +++ b/tribe-common/src/Tribe/Field.php @@ -0,0 +1,840 @@ +defaults = [ + 'type' => 'html', + 'name' => $id, + 'fieldset_attributes' => [], + 'attributes' => [], + 'class' => null, + 'label' => null, + 'label_attributes' => null, + 'placeholder' => null, + 'tooltip' => null, + 'size' => 'medium', + 'html' => null, + 'error' => false, + 'value' => $value, + 'options' => null, + 'conditional' => true, + 'display_callback' => null, + 'if_empty' => null, + 'can_be_empty' => false, + 'clear_after' => true, + 'tooltip_first' => false, + 'allow_clear' => false, + ]; + + // a list of valid field types, to prevent screwy behavior + $this->valid_field_types = [ + 'heading', + 'html', + 'text', + 'textarea', + 'wysiwyg', + 'radio', + 'checkbox_bool', + 'checkbox_list', + 'dropdown', + 'dropdown', + 'dropdown_select2', // Deprecated use `dropdown` + 'dropdown_chosen', // Deprecated use `dropdown` + 'license_key', + 'number', + 'wrapped_html', + 'email', + ]; + + $this->valid_field_types = apply_filters( 'tribe_valid_field_types', $this->valid_field_types ); + + // parse args with defaults and extract them + $args = wp_parse_args( $field, $this->defaults ); + + // sanitize the values just to be safe + $id = esc_attr( $id ); + $type = esc_attr( $args['type'] ); + $name = esc_attr( $args['name'] ); + $placeholder = esc_attr( $args['placeholder'] ); + $class = $this->sanitize_class_attribute( $args['class'] ); + $label = wp_kses( + $args['label'], [ + 'a' => [ 'href' => [], 'title' => [] ], + 'br' => [], + 'em' => [], + 'strong' => [], + 'b' => [], + 'i' => [], + 'u' => [], + 'img' => [ + 'title' => [], + 'src' => [], + 'alt' => [], + ], + 'span' => [ 'class' => [] ], + ] + ); + $label_attributes = $args['label_attributes']; + $tooltip = wp_kses( + $args['tooltip'], [ + 'a' => [ 'href' => [], 'title' => [], 'target' => [] ], + 'br' => [], + 'em' => [], + 'strong' => [], + 'b' => [], + 'i' => [], + 'u' => [], + 'img' => [ + 'title' => [], + 'src' => [], + 'alt' => [], + ], + 'code' => [ 'span' => [] ], + 'span' => [], + ] + ); + $fieldset_attributes = []; + if ( is_array( $args['fieldset_attributes'] ) ) { + foreach ( $args['fieldset_attributes'] as $key => $val ) { + $fieldset_attributes[ $key ] = esc_attr( $val ); + } + } + $attributes = []; + if ( is_array( $args['attributes'] ) ) { + foreach ( $args['attributes'] as $key => $val ) { + $attributes[ $key ] = esc_attr( $val ); + } + } + if ( is_array( $args['options'] ) ) { + $options = []; + foreach ( $args['options'] as $key => $val ) { + $options[ $key ] = $val; + } + } else { + $options = $args['options']; + } + $size = esc_attr( $args['size'] ); + $html = $args['html']; + $error = (bool) $args['error']; + $value = is_array( $value ) ? array_map( 'esc_attr', $value ) : esc_attr( $value ); + $conditional = $args['conditional']; + $display_callback = $args['display_callback']; + $if_empty = is_string( $args['if_empty'] ) ? trim( $args['if_empty'] ) : $args['if_empty']; + $can_be_empty = (bool) $args['can_be_empty']; + $clear_after = (bool) $args['clear_after']; + $tooltip_first = (bool) $args['tooltip_first']; + $allow_clear = (bool) $args['allow_clear']; + + // set the ID + $this->id = apply_filters( 'tribe_field_id', $id ); + + // set each instance variable and filter + foreach ( array_keys( $this->defaults ) as $key ) { + $this->{$key} = apply_filters( 'tribe_field_' . $key, $$key, $this->id ); + } + + // epicness + $this->do_field(); + } + + /** + * Determines how to handle this field's creation + * either calls a callback function or runs this class' course of action + * logs an error if it fails + * + * @return void + */ + public function do_field() { + + if ( $this->conditional ) { + + if ( $this->display_callback && is_callable( $this->display_callback ) ) { + + // if there's a callback, run it + call_user_func( $this->display_callback ); + + } elseif ( in_array( $this->type, $this->valid_field_types ) ) { + + // the specified type exists, run the appropriate method + $field = call_user_func( [ $this, $this->type ] ); + + // filter the output + $field = apply_filters( 'tribe_field_output_' . $this->type, $field, $this->id, $this ); + echo apply_filters( 'tribe_field_output_' . $this->type . '_' . $this->id, $field, $this->id, $this ); + + } else { + + // fail, log the error + Tribe__Main::debug( esc_html__( 'Invalid field type specified', 'tribe-common' ), $this->type, 'notice' ); + + } + } + } + + /** + * returns the field's start + * + * @return string the field start + */ + public function do_field_start() { + $return = '
          type; + $return .= ( $this->error ) ? ' tribe-error' : ''; + $return .= ( $this->size ) ? ' tribe-size-' . $this->size : ''; + $return .= ( $this->class ) ? ' ' . $this->class . '"' : '"'; + $return .= ( $this->fieldset_attributes ) ? ' ' . $this->do_fieldset_attributes() : ''; + $return .= '>'; + + return apply_filters( 'tribe_field_start', $return, $this->id, $this->type, $this->error, $this->class, $this ); + } + + /** + * returns the field's end + * + * @return string the field end + */ + public function do_field_end() { + $return = '
          '; + $return .= ( $this->clear_after ) ? '
          ' : ''; + + return apply_filters( 'tribe_field_end', $return, $this->id, $this ); + } + + /** + * returns the field's label + * + * @return string the field label + */ + public function do_field_label() { + $return = ''; + if ( $this->label ) { + if ( isset( $this->label_attributes ) ) { + $this->label_attributes['class'] = isset( $this->label_attributes['class'] ) ? + implode( ' ', array_merge( [ 'tribe-field-label' ], $this->label_attributes['class'] ) ) : + [ 'tribe-field-label' ]; + $this->label_attributes = $this->concat_attributes( $this->label_attributes ); + } + $return = sprintf( '%s', $this->label_attributes, $this->label ); + } + + return apply_filters( 'tribe_field_label', $return, $this->label, $this ); + } + + /** + * returns the field's div start + * + * @return string the field div start + */ + public function do_field_div_start() { + $return = '
          '; + + if ( true === $this->tooltip_first ) { + $return .= $this->do_tool_tip(); + // and empty it to avoid it from being printed again + $this->tooltip = ''; + } + + return apply_filters( 'tribe_field_div_start', $return, $this ); + } + + /** + * returns the field's div end + * + * @return string the field div end + */ + public function do_field_div_end() { + $return = $this->do_tool_tip(); + $return .= '
          '; + + return apply_filters( 'tribe_field_div_end', $return, $this ); + } + + /** + * returns the field's tooltip/description + * + * @return string the field tooltip + */ + public function do_tool_tip() { + $return = ''; + if ( $this->tooltip ) { + $return = '

          ' . $this->tooltip . '

          '; + } + + return apply_filters( 'tribe_field_tooltip', $return, $this->tooltip, $this ); + } + + /** + * returns the screen reader label + * + * @return string the screen reader label + */ + public function do_screen_reader_label() { + $return = ''; + if ( $this->tooltip ) { + $return = ''; + } + + return apply_filters( 'tribe_field_screen_reader_label', $return, $this->tooltip, $this ); + } + + /** + * returns the field's value + * + * @return string the field value + */ + public function do_field_value() { + $return = ''; + if ( $this->value ) { + $return = ' value="' . $this->value . '"'; + } + + return apply_filters( 'tribe_field_value', $return, $this->value, $this ); + } + + /** + * returns the field's name + * + * @param bool $multi + * + * @return string the field name + */ + public function do_field_name( $multi = false ) { + $return = ''; + if ( $this->name ) { + if ( $multi ) { + $return = ' name="' . $this->name . '[]"'; + } else { + $return = ' name="' . $this->name . '"'; + } + } + + return apply_filters( 'tribe_field_name', $return, $this->name, $this ); + } + + /** + * returns the field's placeholder + * + * @return string the field value + */ + public function do_field_placeholder() { + $return = ''; + if ( $this->placeholder ) { + $return = ' placeholder="' . $this->placeholder . '"'; + } + + return apply_filters( 'tribe_field_placeholder', $return, $this->placeholder, $this ); + } + + /** + * Return a string of attributes for the field + * + * @return string + **/ + public function do_field_attributes() { + $return = ''; + if ( ! empty( $this->attributes ) ) { + foreach ( $this->attributes as $key => $value ) { + $return .= ' ' . $key . '="' . $value . '"'; + } + } + + return apply_filters( 'tribe_field_attributes', $return, $this->name, $this ); + } + + /** + * Return a string of attributes for the fieldset + * + * @return string + **/ + public function do_fieldset_attributes() { + $return = ''; + if ( ! empty( $this->fieldset_attributes ) ) { + foreach ( $this->fieldset_attributes as $key => $value ) { + $return .= ' ' . $key . '="' . $value . '"'; + } + } + + return apply_filters( 'tribe_fieldset_attributes', $return, $this->name, $this ); + } + + /** + * generate a heading field + * + * @return string the field + */ + public function heading() { + $field = '

          ' . $this->label . '

          '; + + return $field; + } + + /** + * generate an html field + * + * @return string the field + */ + public function html() { + $field = $this->do_field_label(); + $field .= $this->html; + + return $field; + } + + /** + * generate a simple text field + * + * @return string the field + */ + public function text() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + $field .= 'do_field_name(); + $field .= $this->do_field_value(); + $field .= $this->do_field_placeholder(); + $field .= $this->do_field_attributes(); + $field .= '/>'; + $field .= $this->do_screen_reader_label(); + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a textarea field + * + * @return string the field + */ + public function textarea() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + $field .= 'do_field_name(); + $field .= $this->do_field_attributes(); + $field .= '>'; + $field .= esc_html( stripslashes( $this->value ) ); + $field .= ''; + $field .= $this->do_screen_reader_label(); + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a wp_editor field + * + * @return string the field + */ + public function wysiwyg() { + $settings = [ + 'teeny' => true, + 'wpautop' => true, + ]; + ob_start(); + wp_editor( html_entity_decode( ( $this->value ) ), $this->name, $settings ); + $editor = ob_get_clean(); + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + $field .= $editor; + $field .= $this->do_screen_reader_label(); + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a radio button field + * + * @return string the field + */ + public function radio() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + if ( is_array( $this->options ) ) { + foreach ( $this->options as $option_id => $title ) { + $field_id = sprintf( + '%1$s-%2$s', + sanitize_html_class( trim( $this->id ) ), + sanitize_html_class( trim( $option_id ) ) + ); + + $field .= ''; + } + } else { + $field .= '' . esc_html__( 'No radio options specified', 'tribe-common' ) . ''; + } + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a checkbox_list field + * + * @return string the field + */ + public function checkbox_list() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + + if ( ! is_array( $this->value ) ) { + if ( ! empty( $this->value ) ) { + $this->value = [ $this->value ]; + } else { + $this->value = []; + } + } + + if ( is_array( $this->options ) ) { + foreach ( $this->options as $option_id => $title ) { + $field .= ''; + } + } else { + $field .= '' . esc_html__( 'No checkbox options specified', 'tribe-common' ) . ''; + } + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a boolean checkbox field + * + * @return string the field + */ + public function checkbox_bool() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + $field .= 'do_field_name(); + $field .= ' value="1" ' . checked( $this->value, true, false ); + $field .= $this->do_field_attributes(); + $field .= '/>'; + $field .= $this->do_screen_reader_label(); + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a dropdown field + * + * @return string the field + */ + public function dropdown() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + if ( is_array( $this->options ) && ! empty( $this->options ) ) { + $field .= 'do_field_name(); + $field .= " id='{$this->id}-select'"; + $field .= " class='tribe-dropdown'"; + if ( empty( $this->allow_clear ) ) { + $field .= " data-prevent-clear='true'"; + } + $field .= $this->do_field_attributes(); + $field .= '>'; + foreach ( $this->options as $option_id => $title ) { + $field .= ''; + } + $field .= ''; + $field .= $this->do_screen_reader_label(); + } elseif ( $this->if_empty ) { + $field .= '' . (string) $this->if_empty . ''; + } else { + $field .= '' . esc_html__( 'No select options specified', 'tribe-common' ) . ''; + } + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * generate a chosen dropdown field - the same as the + * regular dropdown but wrapped so it can have the + * right css class applied to it + * + * @deprecated + * + * @return string the field + */ + public function dropdown_chosen() { + $field = $this->dropdown(); + + return $field; + } + + /** + * generate a select2 dropdown field - the same as the + * regular dropdown but wrapped so it can have the + * right css class applied to it + * + * @deprecated + * + * @return string the field + */ + public function dropdown_select2() { + $field = $this->dropdown(); + + return $field; + } + + /** + * generate a license key field + * + * @return string the field + */ + public function license_key() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + $field .= 'do_field_name(); + $field .= $this->do_field_value(); + $field .= $this->do_field_attributes(); + $field .= '/>'; + $field .= '

          '; + $field .= ''; + $field .= $this->do_screen_reader_label(); + $field .= $this->do_field_div_end(); + $field .= $this->do_field_end(); + + return $field; + } + + /* deprecated camelCase methods */ + public function doField() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field' ); + return $this->do_field(); + } + + public function doFieldStart() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_start' ); + return $this->do_field_start(); + } + + public function doFieldEnd() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_end' ); + return $this->do_field_end(); + } + + public function doFieldLabel() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_label' ); + return $this->do_field_label(); + } + + public function doFieldDivStart() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_div_start' ); + return $this->do_field_div_start(); + } + + public function doFieldDivEnd() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_div_end' ); + return $this->do_field_div_end(); + } + + public function doToolTip() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_tool_tip' ); + return $this->do_tool_tip(); + } + + public function doFieldValue() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_value' ); + return $this->do_field_value(); + } + + public function doFieldName( $multi = false ) { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_name' ); + return $this->do_field_name( $multi ); + } + + public function doFieldAttributes() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_field_attributes' ); + return $this->do_field_attributes(); + } + + public function doScreenReaderLabel() { + _deprecated_function( __METHOD__, '4.3', __CLASS__ . '::do_screen_reader_label' ); + return $this->do_screen_reader_label(); + } + + /** + * Generate a wrapped html field. + * + * This is useful to print some HTML that should be inline with the other fieldsets. + * + * @return string The field markup. + */ + public function wrapped_html() { + $field = $this->do_field_start(); + $field .= $this->do_field_label(); + $field .= $this->do_field_div_start(); + $field .= $this->html; + $field .= $this->do_field_div_start(); + $field .= $this->do_field_end(); + + return $field; + } + + /** + * Concatenates an array of attributes to use in HTML tags. + * + * Example usage: + * + * $attrs = [ 'class' => ['one', 'two'], 'style' => 'color:red;' ]; + * printf ( '

          %s

          ', tribe_concat_attributes( $attrs ), 'bar' ); + * + * //

          class="one two" style="color:red;">bar

          + * + * @param array $attributes An array of attributes in the format + * [ => , => ] + * where `value` can be a string or an array. + * + * @return string The concatenated attributes. + */ + protected function concat_attributes( array $attributes = [] ) { + if ( empty( $attributes ) ) { + return ''; + } + + $concat = []; + foreach ( $attributes as $attribute => $value ) { + if ( is_array( $value ) ) { + $value = implode( ' ', $value ); + } + $quote = false !== strpos( $value, '"' ) ? "'" : '"'; + $concat[] = esc_attr( $attribute ) . '=' . $quote . esc_attr( $value ) . $quote; + } + + return implode( ' ', $concat ); + } + + /** + * Generate an email address field + * + * @since 4.7.4 + * + * @return string The field + */ + public function email() { + $this->value = trim( $this->value ); + return $this->text(); + } + + /** + * Sanitizes a space-separated or array of classes. + * + * @since 4.7.7 + * + * @param string|array $class A single class, a space-separated list of classes + * or an array of classes. + * + * @return string A space-separated list of classes. + */ + protected function sanitize_class_attribute( $class ) { + $classes = is_array( $class ) ? $class : explode( ' ', $class ); + $sanitized = array_map( 'sanitize_html_class', $classes ); + + return implode( ' ', $sanitized ); + } + } // end class +} // endif class_exists diff --git a/tribe-common/src/Tribe/Field_Conditional.php b/tribe-common/src/Tribe/Field_Conditional.php new file mode 100644 index 0000000000..ca1af05372 --- /dev/null +++ b/tribe-common/src/Tribe/Field_Conditional.php @@ -0,0 +1,79 @@ + array( + * 'type' => 'checkbox_bool', + * // ... + * ), + * 'bar' => array( + * 'type' => 'text' + * 'validate_if' => new Tribe__Field_Conditional( 'foo', 'tribe_is_truthy' ) + * 'conditional' => tribe_is_truthy( tribe_get_option( 'foo' ) ), + * // ... + * ), + * ); + * + * The above will modify the validation logic to make it so that the field will not be validated if + * the parent (`foo` in the example) is not "truthy". + * If you need to hide/show the field conditionally use the `conditional` attribute of the field. + * + * @since 4.7.7 + */ +class Tribe__Field_Conditional { + + /** + * @var string The slug of the field the condition + */ + protected $depends_on; + /** + * @var bool + */ + protected $condition; + + /** + * Tribe__Field_Conditional constructor. + * + * @since 4.7.7 + * + * @param string $depends_on_field The slug or identifier of the parent field. + * @param mixed|callable $condition Either a valid callable function or method or a + * value that will be used for a shallow comparison. + */ + public function __construct( $depends_on_field, $condition = true ) { + $this->depends_on = $depends_on_field; + $this->condition = $condition; + } + + /** + * @param mixed $value The value to check, typically the parent field value. + * @param array $fields An array of all the current fields; this will be passed to + * the condition callback function for context if the condition + * is a callable function or method. + * + * @return bool Whether the check was successful (the parent field does have the required + * value) or not. + */ + public function check( $value, array $fields ) { + return is_callable( $this->condition ) + ? call_user_func( $this->condition, $value, $fields ) + : $value == $this->condition; + } + + /** + * Return the id/slug of the field this condition depends on. + * + * @since 4.7.7 + * + * @return string + */ + public function depends_on() { + return $this->depends_on; + } +} diff --git a/tribe-common/src/Tribe/Freemius.php b/tribe-common/src/Tribe/Freemius.php new file mode 100644 index 0000000000..ef21e80a1e --- /dev/null +++ b/tribe-common/src/Tribe/Freemius.php @@ -0,0 +1,63 @@ +plugin_path . 'vendor/freemius/start.php'; + } + + /** + * Initialize the Fremius instance using their methods + * + * @since 4.9.5 + * + * @param string $slug Slug of the plugin + * @param string $id ID in Freemius + * @param string $key Your public key in freemius + * @param array $args Array of extra arguments to register on Freemius + * + * @return Freemius + */ + public function initialize( $slug, $id, $key, array $args = [] ) { + $defaults = [ + 'id' => null, + 'slug' => null, + 'type' => 'plugin', + 'public_key' => null, + 'is_premium' => false, + 'has_addons' => false, + 'has_paid_plans' => false, + ]; + $args = wp_parse_args( $args, $defaults ); + + // These three values can't be overwritten + $args['slug'] = $slug; + $args['id'] = $id; + $args['public_key'] = $key; + + $freemius = fs_dynamic_init( $args ); + + $this->instances[ $slug ] = $freemius; + + return $freemius; + } +} diff --git a/tribe-common/src/Tribe/Image/Uploader.php b/tribe-common/src/Tribe/Image/Uploader.php new file mode 100644 index 0000000000..6b321a0538 --- /dev/null +++ b/tribe-common/src/Tribe/Image/Uploader.php @@ -0,0 +1,319 @@ +featured_image = $featured_image; + } + + /** + * Resets the static "cache" of the class. + */ + public static function reset_cache() { + self::$attachment_guids_cache = false; + self::$original_urls_cache = false; + } + + /** + * Uploads a file and creates the media attachment or simply returns the attachment ID if existing. + * + * @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an + * attachment; + * `false` otherwise. + */ + public function upload_and_get_attachment_id() { + if ( empty( $this->featured_image ) ) { + return false; + } + + $existing = false; + + if ( is_string( $this->featured_image ) && ! is_numeric( $this->featured_image ) ) { + // Assume image exists in the local file system. + $id = $this->get_attachment_ID_from_url( $this->featured_image ); + if ( ! $id ) { + $id = $this->upload_file( $this->featured_image ); + $id = $this->maybe_retry_upload( $id ); + } + $existing = (bool) $id; + } elseif ( $post = get_post( $this->featured_image ) ) { + $id = $post && 'attachment' === $post->post_type ? $this->featured_image : false; + } else { + $id = false; + } + + do_action( + 'tribe_log', + 'debug', + __CLASS__, + [ + 'featured_image' => $this->featured_image, + 'exists' => $existing, + 'id' => $id, + ] + ); + + return $id; + } + + /** + * Retry to upload an image after it failed as was provided, try to decode the URL as in some cases the + * original URL might be encoded HTML components such as: "&" and some CDNs does not handle well different URLs + * as they were provided so we try to recreate the original URL where it might be required. + * + * @since 4.11.5 + * + * @param int|bool $id The id of the attachment if was uploaded correctly, false otherwise. + * + * @return int The ID of the attachment after the upload retry. + */ + protected function maybe_retry_upload( $id ) { + if ( $id ) { + do_action( 'tribe_log', 'debug', __CLASS__, [ 'message' => "ID: {$id} is already a valid one." ] ); + + return $id; + } + + $decoded = esc_url_raw( html_entity_decode( $this->featured_image ) ); + + do_action( 'tribe_log', 'debug', __CLASS__, [ + 'message' => 'Retry upload decoding the URL of the image', + 'url' => $this->featured_image, + 'decoded' => $decoded, + ] ); + + // Maybe the URL was encoded and we need to convert it to a valid URL. + return $this->upload_file( $decoded ); + } + + /** + * @param string $file_url + * + * @return int + */ + protected function upload_file( $file_url ) { + /** + * Allow plugins to enable local URL uploads, mainly used for testing. + * + * @since 4.9.5 + * + * @param bool $allow_local_urls Whether to allow local URLs. + * @param string $file_url File URL. + */ + $allow_local_urls = apply_filters( 'tribe_image_uploader_local_urls', false, $file_url ); + + if ( ! $allow_local_urls && ! filter_var( $file_url, FILTER_VALIDATE_URL ) ) { + return false; + } + + // These files need to be included as dependencies + require_once( ABSPATH . 'wp-admin/includes/image.php' ); + require_once( ABSPATH . 'wp-admin/includes/file.php' ); + require_once( ABSPATH . 'wp-admin/includes/media.php' ); + + $is_local = false; + // This is a local file no need to fetch it from the wire. + if ( $allow_local_urls && file_exists( $file_url ) ) { + $file = $file_url; + $is_local = true; + } else { + /** + * Some CDN services will append query arguments to the image URL; removing + * them now has the potential of blocking the image fetching completely so we + * let them be here. + */ + $file = download_url( $file_url ); + if ( is_wp_error( $file ) ) { + do_action( 'tribe_log', 'error', __CLASS__, [ + 'message' => $file->get_error_message(), + 'url' => $file_url, + 'error' => $file, + ] ); + + return false; + } + } + + // Upload file into WP and leave WP handle the resize and such. + $attachment_id = media_handle_sideload( + [ + 'name' => $this->create_file_name( $file ), + 'tmp_name' => $file, + 'post_mime_type' => 'image', + ], + 0 + ); + + // Remove the temporary file as is no longer required at this point. + if ( ! $is_local && file_exists( $file ) ) { + @unlink( $file ); + } + + if ( is_wp_error( $attachment_id ) ) { + do_action( 'tribe_log', 'error', __CLASS__, [ + 'message' => $attachment_id->get_error_message(), + 'url' => $file_url, + 'error' => $attachment_id, + ] ); + + return false; + } + + update_post_meta( $attachment_id, '_tribe_importer_original_url', $file_url ); + + $this->maybe_init_attachment_guids_cache(); + $this->maybe_init_attachment_original_urls_cache(); + + $attachment_post = get_post( $attachment_id ); + // Only update the cache if is a valid attachment. + if ( $attachment_post instanceof WP_Post ) { + self::$attachment_guids_cache[ $attachment_post->guid ] = $attachment_id; + self::$original_urls_cache[ $file_url ] = $attachment_id; + } + + return $attachment_id; + } + + /** + * WordPress requires to have an extension in all all files as uses `wp_check_filetype` which uses the extension + * of the file to define if a file is valid or not, in this case the extension might not be present in some URLs of + * attachments or media files, in those cases we try to guess the right extension using the mime of the file as + * an alternative, if the $filename is a path we can verify the mime type using native WP functions. + * + * @since 4.11.5 + * + * @param string $filename The name of the file or URL. + * + * @return string Returned a file name with an extension if is not already part of the file name. + */ + protected function create_file_name( $filename ) { + /** + * We use the path basename only here to provided WordPress with a good filename + * that will allow it to correctly detect and validate the extension. + */ + $path = wp_parse_url( $filename, PHP_URL_PATH ); + + $name = basename( $path ); + $properties = wp_check_filetype( $name ); + + // Type can be defined from the name use that one instead. + if ( ! empty( $properties['type'] ) ) { + return $name; + } + + // This is not a file that exists on the system, use the name instead. + if ( ! file_exists( $filename ) ) { + return $name; + } + + $mime = wp_get_image_mime( $filename ); + + // There's no mime defined for the file use the plain name instead. + if ( $mime === '' ) { + return $name; + } + + // create an array with the mimes as the keys and extensions as values. + $mime_to_extensions = array_flip( wp_get_mime_types() ); + + // No mime was found for the file on the array of allowed mime types, fallback to the name. + if ( ! isset( $mime_to_extensions[ $mime ] ) ) { + return $name; + } + + // If there are more than one extension just ose one. + $parts = explode( '|', $mime_to_extensions[ $mime ] ); + + // Create a new name with extension. + return implode( '.', [ $name, reset( $parts ) ] ); + } + + protected function get_attachment_ID_from_url( $featured_image ) { + $this->maybe_init_attachment_guids_cache(); + $this->maybe_init_attachment_original_urls_cache(); + + $guids_cache = self::$attachment_guids_cache; + $original_urls_cache = self::$original_urls_cache; + if ( isset( $guids_cache[ $featured_image ] ) ) { + return $guids_cache[ $featured_image ]; + } + + if ( isset( $original_urls_cache[ $featured_image ] ) ) { + return $original_urls_cache[ $featured_image ]; + } + + return false; + } + + protected function maybe_init_attachment_guids_cache() { + if ( false === self::$attachment_guids_cache ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $guids = $wpdb->get_results( "SELECT ID, guid FROM $wpdb->posts where post_type = 'attachment'" ); + + if ( $guids ) { + $keys = wp_list_pluck( $guids, 'guid' ); + $values = wp_list_pluck( $guids, 'ID' ); + self::$attachment_guids_cache = array_combine( $keys, $values ); + } else { + self::$attachment_guids_cache = []; + } + } + } + + protected function maybe_init_attachment_original_urls_cache() { + if ( false === self::$original_urls_cache ) { + /** @var \wpdb $wpdb */ + global $wpdb; + $original_urls = $wpdb->get_results( " + SELECT p.ID, pm.meta_value FROM $wpdb->posts p + JOIN $wpdb->postmeta pm + ON p.ID = pm.post_id + WHERE p.post_type = 'attachment' + AND pm.meta_key = '_tribe_importer_original_url' + " ); + + if ( $original_urls ) { + $keys = wp_list_pluck( $original_urls, 'meta_value' ); + $values = wp_list_pluck( $original_urls, 'ID' ); + self::$original_urls_cache = array_combine( $keys, $values ); + } else { + self::$original_urls_cache = []; + } + } + } + + /** + * Handles errors generated during the use of `file_get_contents` to + * make them run-time exceptions. + * + * @since 4.7.22 + * + * @param string $unused_error_code The error numeric code. + * @param string $message The error message. + * + * @throws RuntimeException To pass the error as an exception to + * the handler. + */ + public function handle_error( $unused_error_code, $message ) { + throw new RuntimeException( $message ); + } +} diff --git a/tribe-common/src/Tribe/JSON_LD/Abstract.php b/tribe-common/src/Tribe/JSON_LD/Abstract.php new file mode 100755 index 0000000000..04ed7e21fe --- /dev/null +++ b/tribe-common/src/Tribe/JSON_LD/Abstract.php @@ -0,0 +1,358 @@ +exists( $post_id ) && $this->type_exists( $post_id, $this->type ) ) { + return []; + } + + $post = get_post( $post_id ); + + if ( empty( $post->ID ) ) { + return []; + } + + $data = (object) []; + + // We may need to prevent the context to be triggered + if ( ! isset( $args['context'] ) || false !== $args['context'] ) { + $data->{'@context'} = 'http://schema.org'; + } + + $data->{'@type'} = $this->type; + + $data->name = esc_js( get_the_title( $post ) ); + $data->description = esc_js( tribe_post_excerpt( $post ) ); + + if ( has_post_thumbnail( $post ) ) { + $data->image = wp_get_attachment_url( get_post_thumbnail_id( $post ) ); + } + + $data->url = esc_url_raw( $this->get_link( $post ) ); + + $type = strtolower( esc_attr( $this->type ) ); + $data = $this->apply_object_data_filter( $data, $args, $post ); + + // Index by ID: this will allow filter code to identify the actual event being referred to + // without injecting an additional property + return [ $post->ID => $data ]; + } + + /** + * Filters the JSON LD object data. + * + * The expectation is that any sub-classes overriding the get_data() method will ensure they + * call this method for consistency. + * + * @param string $type + * @param object $data + * @param array $args + * @param WP_Post $post + * + * @return mixed + */ + protected function apply_object_data_filter( $data, $args, $post ) { + $type = strtolower( esc_attr( $this->type ) ); + + /** + * Allows the event data to be modifed by themes and other plugins. + * + * @example tribe_json_ld_thing_object + * @example tribe_json_ld_event_object + * + * @param object $data The JSON-LD object + * @param array $args The arguments used to get data + * @param WP_Post $post The post object + */ + return apply_filters( "tribe_json_ld_{$type}_object", $data, $args, $post ); + } + + /** + * puts together the actual html/json javascript block for output + * + * @return string + */ + public function get_markup( $post = null, $args = [] ) { + $data = $this->get_data( $post, $args ); + $type = strtolower( esc_attr( $this->type ) ); + $this->set_type( $post, $type ); + + foreach ( $data as $post_id => $_data ) { + // Register this post as done already + $this->register( $post_id ); + } + + /** + * Allows the event data to be modifed by themes and other plugins. + * + * @example tribe_json_ld_thing_data + * @example tribe_json_ld_event_data + * + * @param array $data objects representing the Google Markup for each event. + * @param array $args the arguments used to get data + */ + $data = apply_filters( "tribe_json_ld_{$type}_data", $data, $args ); + + // Strip the post ID indexing before returning + $data = array_values( $data ); + + if ( ! empty( $data ) ) { + $html[] = ''; + } + + return ! empty( $html ) ? implode( "\r\n", $html ) : ''; + } + + public function markup( $post = null, $args = [] ) { + $html = $this->get_markup( $post, $args ); + + /** + * Allows users to filter the end markup of JSON-LD + * + * @deprecated + * @todo Remove on 4.4 + * + * @param string The HTML for the JSON LD markup + */ + $html = apply_filters( 'tribe_google_data_markup_json', $html ); + /** + * Allows users to filter the end markup of JSON-LD + * + * @param string The HTML for the JSON LD markup + */ + $html = apply_filters( 'tribe_json_ld_markup', $html ); + echo $html; + } + + /** + * Get a link to the post + * + * Children of this class are likely to override it with their + * own functions that only work with their designated post type. + * + * @since 4.5.10 + * + * @param int|WP_Post $post The Post Object or ID + * + * @return false|string Link to the post or false + */ + protected function get_link( $post ) { + return get_permalink( $post ); + } + + /** + * Gets from the Posts index a specific post or fetch all of them + * + * @param int|WP_Post $post The Post Object or ID + * + * @return null|array|WP_Post Returns an Indexed Array of Posts, a found Post or Null if not found + */ + public function get( $post = null ) { + if ( is_null( $post ) ) { + return self::$posts; + } + $id = Tribe__Main::post_id_helper( $post ); + + if ( $this->exists( $id ) ) { + return self::$posts[ $id ]; + } + + return null; + } + + /** + * Checks if a Post has been registered to the JSON-LD index + * + * @param int|WP_Post $post The Post Object or ID + * + * @return bool + */ + public function exists( $post ) { + return isset( self::$posts[ Tribe__Main::post_id_helper( $post ) ] ); + } + + /** + * Register the new Post on the Index of created ones + * + * @param int|WP_Post $post The Post Object or ID + * + * @return WP_Post The Post Object that was registered + */ + public function register( $post ) { + $id = Tribe__Main::post_id_helper( $post ); + if ( $this->exists( $id ) ) { + return self::$posts[ $id ]; + } + self::$posts[ $id ] = get_post( $id ); + return self::$posts[ $id ]; + } + + + /** + * Public method to have access to the types + * + * @since 4.7.12 + * + * @return array + */ + public function get_types() { + return self::$types; + } + + /** + * Register the current $type to prevent duplicates entries with different $types and IDs + * + * @since 4.7.12 + * + * @param $post + * @param $type + * + * @return mixed + */ + public function set_type( $post, $type ) { + $id = Tribe__Main::post_id_helper( $post ); + + if ( $this->type_exists( $id, $type ) ) { + return self::$types[ $id ]; + } + + if ( empty( self::$types[ $id ] ) ) { + self::$types[ $id ] = [ $this->type ]; + } else { + self::$types[ $id ][] = $this->type; + } + + return self::$types[ $id ]; + } + + /** + * Remove an Post from the Indexed list + * + * @param int|WP_Post $post The Post Object or ID + * + * @return bool + */ + public function remove( $post ) { + $id = Tribe__Main::post_id_helper( $post ); + + if ( ! $this->exists( $id ) ) { + return false; + } + + unset( self::$posts[ $id ] ); + + return true; + } + + /** + * Return `true` if the $type has been already registered for the specified $id. + * + * @since 4.7.12 + * + * @param $id + * @param $type + * + * @return bool + */ + public function type_exists( $id, $type ) { + return isset( self::$types[ $id ] ) && false !== array_search( $type, self::$types[ $id ] ); + } + + /** + * Empties the registered posts cache variable. + * + * Added for testing purposes. + */ + public static function unregister_all() { + self::$posts = []; + self::$types = []; + } + + /** + * Returns an array of the registered post IDs. + * + * @return array + */ + public static function get_registered_post_ids() { + return array_keys( self::$posts ); + } +} diff --git a/tribe-common/src/Tribe/Languages/Locations.php b/tribe-common/src/Tribe/Languages/Locations.php new file mode 100644 index 0000000000..36449a9075 --- /dev/null +++ b/tribe-common/src/Tribe/Languages/Locations.php @@ -0,0 +1,413 @@ +get( $cache_key , '', null ); + + if ( null === $countries ) { + $countries = $this->build_country_array(); + + if ( $escape ) { + $countries = array_map( static function( $country ) { + return html_entity_decode( $country, ENT_QUOTES ); + }, $countries ); + } + + // Actually set the cache in case it's not in place. + $cache->set( $cache_key, $countries ); + } + + return $countries; + } + + /** + * Returns an array of countries and their codes. + * + * Adds array to object cache to speed up subsequent retrievals. + * + * @return array { + * List of countries + * + * @type string $country_code Country name. + * } + */ + public function get_us_states() { + return tribe( 'cache' )->get( 'tribe_us_states_list', '', [ $this, 'build_us_states_array' ] ); + } + + /** + * Get a translated array of countries. + * + * @return array { + * List of countries + * + * @type string $country_code Country name. + * } + */ + public function build_country_array() { + $countries = [ + 'US' => esc_html__( 'United States', 'tribe-common' ), + 'AF' => esc_html__( 'Afghanistan', 'tribe-common' ), + 'AX' => esc_html__( 'Åland Islands', 'tribe-common' ), + 'AL' => esc_html__( 'Albania', 'tribe-common' ), + 'DZ' => esc_html__( 'Algeria', 'tribe-common' ), + 'AS' => esc_html__( 'American Samoa', 'tribe-common' ), + 'AD' => esc_html__( 'Andorra', 'tribe-common' ), + 'AO' => esc_html__( 'Angola', 'tribe-common' ), + 'AI' => esc_html__( 'Anguilla', 'tribe-common' ), + 'AQ' => esc_html__( 'Antarctica', 'tribe-common' ), + 'AG' => esc_html__( 'Antigua and Barbuda', 'tribe-common' ), + 'AR' => esc_html__( 'Argentina', 'tribe-common' ), + 'AM' => esc_html__( 'Armenia', 'tribe-common' ), + 'AW' => esc_html__( 'Aruba', 'tribe-common' ), + 'AU' => esc_html__( 'Australia', 'tribe-common' ), + 'AT' => esc_html__( 'Austria', 'tribe-common' ), + 'AZ' => esc_html__( 'Azerbaijan', 'tribe-common' ), + 'BS' => esc_html__( 'Bahamas', 'tribe-common' ), + 'BH' => esc_html__( 'Bahrain', 'tribe-common' ), + 'BD' => esc_html__( 'Bangladesh', 'tribe-common' ), + 'BB' => esc_html__( 'Barbados', 'tribe-common' ), + 'BY' => esc_html__( 'Belarus', 'tribe-common' ), + 'BE' => esc_html__( 'Belgium', 'tribe-common' ), + 'BZ' => esc_html__( 'Belize', 'tribe-common' ), + 'BJ' => esc_html__( 'Benin', 'tribe-common' ), + 'BM' => esc_html__( 'Bermuda', 'tribe-common' ), + 'BT' => esc_html__( 'Bhutan', 'tribe-common' ), + 'BO' => esc_html__( 'Bolivia', 'tribe-common' ), + 'BA' => esc_html__( 'Bosnia and Herzegovina', 'tribe-common' ), + 'BW' => esc_html__( 'Botswana', 'tribe-common' ), + 'BV' => esc_html__( 'Bouvet Island', 'tribe-common' ), + 'BR' => esc_html__( 'Brazil', 'tribe-common' ), + 'IO' => esc_html__( 'British Indian Ocean Territory', 'tribe-common' ), + 'BN' => esc_html__( 'Brunei Darussalam', 'tribe-common' ), + 'BG' => esc_html__( 'Bulgaria', 'tribe-common' ), + 'BF' => esc_html__( 'Burkina Faso', 'tribe-common' ), + 'BI' => esc_html__( 'Burundi', 'tribe-common' ), + 'KH' => esc_html__( 'Cambodia', 'tribe-common' ), + 'CM' => esc_html__( 'Cameroon', 'tribe-common' ), + 'CA' => esc_html__( 'Canada', 'tribe-common' ), + 'CV' => esc_html__( 'Cape Verde', 'tribe-common' ), + 'KY' => esc_html__( 'Cayman Islands', 'tribe-common' ), + 'CF' => esc_html__( 'Central African Republic', 'tribe-common' ), + 'TD' => esc_html__( 'Chad', 'tribe-common' ), + 'CL' => esc_html__( 'Chile', 'tribe-common' ), + 'CN' => esc_html__( 'China', 'tribe-common' ), + 'CX' => esc_html__( 'Christmas Island', 'tribe-common' ), + 'CC' => esc_html__( 'Cocos (Keeling) Islands', 'tribe-common' ), + 'MF' => esc_html__( 'Collectivity of Saint Martin', 'tribe-common' ), + 'CO' => esc_html__( 'Colombia', 'tribe-common' ), + 'KM' => esc_html__( 'Comoros', 'tribe-common' ), + 'CG' => esc_html__( 'Congo', 'tribe-common' ), + 'CD' => esc_html__( 'Congo, Democratic Republic of the', 'tribe-common' ), + 'CK' => esc_html__( 'Cook Islands', 'tribe-common' ), + 'CR' => esc_html__( 'Costa Rica', 'tribe-common' ), + 'CI' => esc_html__( "Côte d'Ivoire", 'tribe-common' ), + 'HR' => esc_html__( 'Croatia (Local Name: Hrvatska)', 'tribe-common' ), + 'CU' => esc_html__( 'Cuba', 'tribe-common' ), + 'CW' => esc_html__( 'Curaçao', 'tribe-common' ), + 'CY' => esc_html__( 'Cyprus', 'tribe-common' ), + 'CZ' => esc_html__( 'Czech Republic', 'tribe-common' ), + 'DK' => esc_html__( 'Denmark', 'tribe-common' ), + 'DJ' => esc_html__( 'Djibouti', 'tribe-common' ), + 'DM' => esc_html__( 'Dominica', 'tribe-common' ), + 'DO' => esc_html__( 'Dominican Republic', 'tribe-common' ), + 'TP' => esc_html__( 'East Timor', 'tribe-common' ), + 'EC' => esc_html__( 'Ecuador', 'tribe-common' ), + 'EG' => esc_html__( 'Egypt', 'tribe-common' ), + 'SV' => esc_html__( 'El Salvador', 'tribe-common' ), + 'GQ' => esc_html__( 'Equatorial Guinea', 'tribe-common' ), + 'ER' => esc_html__( 'Eritrea', 'tribe-common' ), + 'EE' => esc_html__( 'Estonia', 'tribe-common' ), + 'ET' => esc_html__( 'Ethiopia', 'tribe-common' ), + 'FK' => esc_html__( 'Falkland Islands (Malvinas)', 'tribe-common' ), + 'FO' => esc_html__( 'Faroe Islands', 'tribe-common' ), + 'FJ' => esc_html__( 'Fiji', 'tribe-common' ), + 'FI' => esc_html__( 'Finland', 'tribe-common' ), + 'FR' => esc_html__( 'France', 'tribe-common' ), + 'GF' => esc_html__( 'French Guiana', 'tribe-common' ), + 'PF' => esc_html__( 'French Polynesia', 'tribe-common' ), + 'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ), + 'GA' => esc_html__( 'Gabon', 'tribe-common' ), + 'GM' => esc_html__( 'Gambia', 'tribe-common' ), + 'GE' => esc_html_x( 'Georgia', 'The country', 'tribe-common' ), + 'DE' => esc_html__( 'Germany', 'tribe-common' ), + 'GH' => esc_html__( 'Ghana', 'tribe-common' ), + 'GI' => esc_html__( 'Gibraltar', 'tribe-common' ), + 'GR' => esc_html__( 'Greece', 'tribe-common' ), + 'GL' => esc_html__( 'Greenland', 'tribe-common' ), + 'GD' => esc_html__( 'Grenada', 'tribe-common' ), + 'GP' => esc_html__( 'Guadeloupe', 'tribe-common' ), + 'GU' => esc_html__( 'Guam', 'tribe-common' ), + 'GT' => esc_html__( 'Guatemala', 'tribe-common' ), + 'GN' => esc_html__( 'Guinea', 'tribe-common' ), + 'GW' => esc_html__( 'Guinea-Bissau', 'tribe-common' ), + 'GY' => esc_html__( 'Guyana', 'tribe-common' ), + 'HT' => esc_html__( 'Haiti', 'tribe-common' ), + 'HM' => esc_html__( 'Heard and McDonald Islands', 'tribe-common' ), + 'VA' => esc_html__( 'Holy See (Vatican City State)', 'tribe-common' ), + 'HN' => esc_html__( 'Honduras', 'tribe-common' ), + 'HK' => esc_html__( 'Hong Kong', 'tribe-common' ), + 'HU' => esc_html__( 'Hungary', 'tribe-common' ), + 'IS' => esc_html__( 'Iceland', 'tribe-common' ), + 'IN' => esc_html__( 'India', 'tribe-common' ), + 'ID' => esc_html__( 'Indonesia', 'tribe-common' ), + 'IR' => esc_html__( 'Iran, Islamic Republic of', 'tribe-common' ), + 'IQ' => esc_html__( 'Iraq', 'tribe-common' ), + 'IE' => esc_html__( 'Ireland', 'tribe-common' ), + 'IL' => esc_html__( 'Israel', 'tribe-common' ), + 'IT' => esc_html__( 'Italy', 'tribe-common' ), + 'JM' => esc_html__( 'Jamaica', 'tribe-common' ), + 'JP' => esc_html__( 'Japan', 'tribe-common' ), + 'JO' => esc_html__( 'Jordan', 'tribe-common' ), + 'KZ' => esc_html__( 'Kazakhstan', 'tribe-common' ), + 'KE' => esc_html__( 'Kenya', 'tribe-common' ), + 'KI' => esc_html__( 'Kiribati', 'tribe-common' ), + 'KP' => esc_html__( "Korea, Democratic People's Republic of", 'tribe-common' ), + 'KR' => esc_html__( 'Korea, Republic of', 'tribe-common' ), + 'KW' => esc_html__( 'Kuwait', 'tribe-common' ), + 'KG' => esc_html__( 'Kyrgyzstan', 'tribe-common' ), + 'LA' => esc_html__( "Lao People's Democratic Republic", 'tribe-common' ), + 'LV' => esc_html__( 'Latvia', 'tribe-common' ), + 'LB' => esc_html__( 'Lebanon', 'tribe-common' ), + 'LS' => esc_html__( 'Lesotho', 'tribe-common' ), + 'LR' => esc_html__( 'Liberia', 'tribe-common' ), + 'LY' => esc_html__( 'Libya', 'tribe-common' ), + 'LI' => esc_html__( 'Liechtenstein', 'tribe-common' ), + 'LT' => esc_html__( 'Lithuania', 'tribe-common' ), + 'LU' => esc_html__( 'Luxembourg', 'tribe-common' ), + 'MO' => esc_html__( 'Macau', 'tribe-common' ), + 'MG' => esc_html__( 'Madagascar', 'tribe-common' ), + 'MW' => esc_html__( 'Malawi', 'tribe-common' ), + 'MY' => esc_html__( 'Malaysia', 'tribe-common' ), + 'MV' => esc_html__( 'Maldives', 'tribe-common' ), + 'ML' => esc_html__( 'Mali', 'tribe-common' ), + 'MT' => esc_html__( 'Malta', 'tribe-common' ), + 'MH' => esc_html__( 'Marshall Islands', 'tribe-common' ), + 'MQ' => esc_html__( 'Martinique', 'tribe-common' ), + 'MR' => esc_html__( 'Mauritania', 'tribe-common' ), + 'MU' => esc_html__( 'Mauritius', 'tribe-common' ), + 'YT' => esc_html__( 'Mayotte', 'tribe-common' ), + 'MX' => esc_html__( 'Mexico', 'tribe-common' ), + 'FM' => esc_html__( 'Micronesia, Federated States of', 'tribe-common' ), + 'MD' => esc_html__( 'Moldova, Republic of', 'tribe-common' ), + 'MC' => esc_html__( 'Monaco', 'tribe-common' ), + 'MN' => esc_html__( 'Mongolia', 'tribe-common' ), + 'ME' => esc_html__( 'Montenegro', 'tribe-common' ), + 'MS' => esc_html__( 'Montserrat', 'tribe-common' ), + 'MA' => esc_html__( 'Morocco', 'tribe-common' ), + 'MZ' => esc_html__( 'Mozambique', 'tribe-common' ), + 'MM' => esc_html__( 'Myanmar', 'tribe-common' ), + 'NA' => esc_html__( 'Namibia', 'tribe-common' ), + 'NR' => esc_html__( 'Nauru', 'tribe-common' ), + 'NP' => esc_html__( 'Nepal', 'tribe-common' ), + 'NL' => esc_html__( 'Netherlands', 'tribe-common' ), + 'NC' => esc_html__( 'New Caledonia', 'tribe-common' ), + 'NZ' => esc_html__( 'New Zealand', 'tribe-common' ), + 'NI' => esc_html__( 'Nicaragua', 'tribe-common' ), + 'NE' => esc_html__( 'Niger', 'tribe-common' ), + 'NG' => esc_html__( 'Nigeria', 'tribe-common' ), + 'NU' => esc_html__( 'Niue', 'tribe-common' ), + 'NF' => esc_html__( 'Norfolk Island', 'tribe-common' ), + 'MK' => esc_html__( 'North Macedonia', 'tribe-common' ), + 'MP' => esc_html__( 'Northern Mariana Islands', 'tribe-common' ), + 'NO' => esc_html__( 'Norway', 'tribe-common' ), + 'OM' => esc_html__( 'Oman', 'tribe-common' ), + 'PK' => esc_html__( 'Pakistan', 'tribe-common' ), + 'PW' => esc_html__( 'Palau', 'tribe-common' ), + 'PA' => esc_html__( 'Panama', 'tribe-common' ), + 'PG' => esc_html__( 'Papua New Guinea', 'tribe-common' ), + 'PY' => esc_html__( 'Paraguay', 'tribe-common' ), + 'PE' => esc_html__( 'Peru', 'tribe-common' ), + 'PH' => esc_html__( 'Philippines', 'tribe-common' ), + 'PN' => esc_html__( 'Pitcairn', 'tribe-common' ), + 'PL' => esc_html__( 'Poland', 'tribe-common' ), + 'PT' => esc_html__( 'Portugal', 'tribe-common' ), + 'PR' => esc_html__( 'Puerto Rico', 'tribe-common' ), + 'QA' => esc_html__( 'Qatar', 'tribe-common' ), + 'RE' => esc_html__( 'Reunion', 'tribe-common' ), + 'RO' => esc_html__( 'Romania', 'tribe-common' ), + 'RU' => esc_html__( 'Russian Federation', 'tribe-common' ), + 'RW' => esc_html__( 'Rwanda', 'tribe-common' ), + 'BL' => esc_html__( 'Saint Barthélemy', 'tribe-common' ), + 'SH' => esc_html__( 'Saint Helena', 'tribe-common' ), + 'KN' => esc_html__( 'Saint Kitts and Nevis', 'tribe-common' ), + 'LC' => esc_html__( 'Saint Lucia', 'tribe-common' ), + 'PM' => esc_html__( 'Saint Pierre and Miquelon', 'tribe-common' ), + 'VC' => esc_html__( 'Saint Vincent and The Grenadines', 'tribe-common' ), + 'WS' => esc_html__( 'Samoa', 'tribe-common' ), + 'SM' => esc_html__( 'San Marino', 'tribe-common' ), + 'ST' => esc_html__( 'São Tomé and Príncipe', 'tribe-common' ), + 'SA' => esc_html__( 'Saudi Arabia', 'tribe-common' ), + 'SN' => esc_html__( 'Senegal', 'tribe-common' ), + 'RS' => esc_html__( 'Serbia', 'tribe-common' ), + 'SC' => esc_html__( 'Seychelles', 'tribe-common' ), + 'SL' => esc_html__( 'Sierra Leone', 'tribe-common' ), + 'SG' => esc_html__( 'Singapore', 'tribe-common' ), + 'SX' => esc_html__( 'Sint Maarten', 'tribe-common' ), + 'SK' => esc_html__( 'Slovakia (Slovak Republic)', 'tribe-common' ), + 'SI' => esc_html__( 'Slovenia', 'tribe-common' ), + 'SB' => esc_html__( 'Solomon Islands', 'tribe-common' ), + 'SO' => esc_html__( 'Somalia', 'tribe-common' ), + 'ZA' => esc_html__( 'South Africa', 'tribe-common' ), + 'GS' => esc_html__( 'South Georgia, South Sandwich Islands', 'tribe-common' ), + 'ES' => esc_html__( 'Spain', 'tribe-common' ), + 'LK' => esc_html__( 'Sri Lanka', 'tribe-common' ), + 'SD' => esc_html__( 'Sudan', 'tribe-common' ), + 'SR' => esc_html__( 'Suriname', 'tribe-common' ), + 'SJ' => esc_html__( 'Svalbard and Jan Mayen Islands', 'tribe-common' ), + 'SZ' => esc_html__( 'Swaziland', 'tribe-common' ), + 'SE' => esc_html__( 'Sweden', 'tribe-common' ), + 'CH' => esc_html__( 'Switzerland', 'tribe-common' ), + 'SY' => esc_html__( 'Syrian Arab Republic', 'tribe-common' ), + 'TW' => esc_html__( 'Taiwan', 'tribe-common' ), + 'TJ' => esc_html__( 'Tajikistan', 'tribe-common' ), + 'TZ' => esc_html__( 'Tanzania, United Republic of', 'tribe-common' ), + 'TH' => esc_html__( 'Thailand', 'tribe-common' ), + 'TG' => esc_html__( 'Togo', 'tribe-common' ), + 'TK' => esc_html__( 'Tokelau', 'tribe-common' ), + 'TO' => esc_html__( 'Tonga', 'tribe-common' ), + 'TT' => esc_html__( 'Trinidad and Tobago', 'tribe-common' ), + 'TN' => esc_html__( 'Tunisia', 'tribe-common' ), + 'TR' => esc_html__( 'Turkey', 'tribe-common' ), + 'TM' => esc_html__( 'Turkmenistan', 'tribe-common' ), + 'TC' => esc_html__( 'Turks and Caicos Islands', 'tribe-common' ), + 'TV' => esc_html__( 'Tuvalu', 'tribe-common' ), + 'UG' => esc_html__( 'Uganda', 'tribe-common' ), + 'UA' => esc_html__( 'Ukraine', 'tribe-common' ), + 'AE' => esc_html__( 'United Arab Emirates', 'tribe-common' ), + 'GB' => esc_html__( 'United Kingdom', 'tribe-common' ), + 'UM' => esc_html__( 'United States Minor Outlying Islands', 'tribe-common' ), + 'UY' => esc_html__( 'Uruguay', 'tribe-common' ), + 'UZ' => esc_html__( 'Uzbekistan', 'tribe-common' ), + 'VU' => esc_html__( 'Vanuatu', 'tribe-common' ), + 'VE' => esc_html__( 'Venezuela', 'tribe-common' ), + 'VN' => esc_html__( 'Viet Nam', 'tribe-common' ), + 'VG' => esc_html__( 'Virgin Islands (British)', 'tribe-common' ), + 'VI' => esc_html__( 'Virgin Islands (U.S.)', 'tribe-common' ), + 'WF' => esc_html__( 'Wallis and Futuna Islands', 'tribe-common' ), + 'EH' => esc_html__( 'Western Sahara', 'tribe-common' ), + 'YE' => esc_html__( 'Yemen', 'tribe-common' ), + 'ZM' => esc_html__( 'Zambia', 'tribe-common' ), + 'ZW' => esc_html__( 'Zimbabwe', 'tribe-common' ), + ]; + + // Perform a natural sort, ensures the countries are in the expected order even once translated. + natsort( $countries ); + + /** + * Filter that allows to change the list and the output of the countries names. + * + * @since 4.7.12 + * + * @param array associative array with: Country Code => Country Name + */ + return (array) apply_filters( 'tribe_countries', $countries ); + } + + /** + * Get a translated array of US States. + * + * @return array { + * List of States + * + * @type string $state_abbreviation State. + * } + */ + public function build_us_states_array() { + $states = [ + 'AL' => esc_html__( 'Alabama', 'tribe-common' ), + 'AK' => esc_html__( 'Alaska', 'tribe-common' ), + 'AZ' => esc_html__( 'Arizona', 'tribe-common' ), + 'AR' => esc_html__( 'Arkansas', 'tribe-common' ), + 'CA' => esc_html__( 'California', 'tribe-common' ), + 'CO' => esc_html__( 'Colorado', 'tribe-common' ), + 'CT' => esc_html__( 'Connecticut', 'tribe-common' ), + 'DE' => esc_html__( 'Delaware', 'tribe-common' ), + 'DC' => esc_html__( 'District of Columbia', 'tribe-common' ), + 'FL' => esc_html__( 'Florida', 'tribe-common' ), + 'GA' => esc_html_x( 'Georgia', 'The US state Georgia', 'tribe-common' ), + 'HI' => esc_html__( 'Hawaii', 'tribe-common' ), + 'ID' => esc_html__( 'Idaho', 'tribe-common' ), + 'IL' => esc_html__( 'Illinois', 'tribe-common' ), + 'IN' => esc_html__( 'Indiana', 'tribe-common' ), + 'IA' => esc_html__( 'Iowa', 'tribe-common' ), + 'KS' => esc_html__( 'Kansas', 'tribe-common' ), + 'KY' => esc_html__( 'Kentucky', 'tribe-common' ), + 'LA' => esc_html__( 'Louisiana', 'tribe-common' ), + 'ME' => esc_html__( 'Maine', 'tribe-common' ), + 'MD' => esc_html__( 'Maryland', 'tribe-common' ), + 'MA' => esc_html__( 'Massachusetts', 'tribe-common' ), + 'MI' => esc_html__( 'Michigan', 'tribe-common' ), + 'MN' => esc_html__( 'Minnesota', 'tribe-common' ), + 'MS' => esc_html__( 'Mississippi', 'tribe-common' ), + 'MO' => esc_html__( 'Missouri', 'tribe-common' ), + 'MT' => esc_html__( 'Montana', 'tribe-common' ), + 'NE' => esc_html__( 'Nebraska', 'tribe-common' ), + 'NV' => esc_html__( 'Nevada', 'tribe-common' ), + 'NH' => esc_html__( 'New Hampshire', 'tribe-common' ), + 'NJ' => esc_html__( 'New Jersey', 'tribe-common' ), + 'NM' => esc_html__( 'New Mexico', 'tribe-common' ), + 'NY' => esc_html__( 'New York', 'tribe-common' ), + 'NC' => esc_html__( 'North Carolina', 'tribe-common' ), + 'ND' => esc_html__( 'North Dakota', 'tribe-common' ), + 'OH' => esc_html__( 'Ohio', 'tribe-common' ), + 'OK' => esc_html__( 'Oklahoma', 'tribe-common' ), + 'OR' => esc_html__( 'Oregon', 'tribe-common' ), + 'PA' => esc_html__( 'Pennsylvania', 'tribe-common' ), + 'RI' => esc_html__( 'Rhode Island', 'tribe-common' ), + 'SC' => esc_html__( 'South Carolina', 'tribe-common' ), + 'SD' => esc_html__( 'South Dakota', 'tribe-common' ), + 'TN' => esc_html__( 'Tennessee', 'tribe-common' ), + 'TX' => esc_html__( 'Texas', 'tribe-common' ), + 'UT' => esc_html__( 'Utah', 'tribe-common' ), + 'VT' => esc_html__( 'Vermont', 'tribe-common' ), + 'VA' => esc_html__( 'Virginia', 'tribe-common' ), + 'WA' => esc_html__( 'Washington', 'tribe-common' ), + 'WV' => esc_html__( 'West Virginia', 'tribe-common' ), + 'WI' => esc_html__( 'Wisconsin', 'tribe-common' ), + 'WY' => esc_html__( 'Wyoming', 'tribe-common' ), + ]; + + // Perform a natural sort, ensures the states are in the expected order even once translated. + natsort( $states ); + + /** + * Filter that allows to change the names of US states before output. + * + * @since 4.7.12 + * + * @param array Associative array with the format: State Code => State Name + */ + return (array) apply_filters( 'tribe_us_states', $states ); + } +} diff --git a/tribe-common/src/Tribe/Languages/Map_Interface.php b/tribe-common/src/Tribe/Languages/Map_Interface.php new file mode 100644 index 0000000000..725a4f81d6 --- /dev/null +++ b/tribe-common/src/Tribe/Languages/Map_Interface.php @@ -0,0 +1,32 @@ + => ] + * e.g. [ 'pt-BR' => 'Portuguese (Brazil)' ] + */ + public function get_supported_languages(); + + /** + * Checks whether a language code is supported by the language map or not. + * + * @param string $language_code + * + * @return bool Whether a language code is supported by the language map or not. + */ + public function is_supported( $language_code ); + + /** + * Converts a language code from the format used by WP to the one used by the language map. + * + * @param string $language_code A language code in the format used by WP; e.g. `en_US`. + * + * @return string|false The converted language code or `false` if the language code is not supported. + */ + public function convert_language_code( $language_code ); +} diff --git a/tribe-common/src/Tribe/Languages/Recaptcha_Map.php b/tribe-common/src/Tribe/Languages/Recaptcha_Map.php new file mode 100644 index 0000000000..e818a312ed --- /dev/null +++ b/tribe-common/src/Tribe/Languages/Recaptcha_Map.php @@ -0,0 +1,125 @@ + => ] + * e.g. [ 'pt-BR' => 'Portuguese (Brazil)' ] + */ + public function get_supported_languages() { + return [ + 'ar' => 'Arabic', + 'af' => 'Afrikaans', + 'am' => 'Amharic', + 'hy' => 'Armenian', + 'az' => 'Azerbaijani', + 'eu' => 'Basque', + 'bn' => 'Bengali', + 'bg' => 'Bulgarian', + 'ca' => 'Catalan', + 'zh-HK' => 'Chinese (Hong Kong)', + 'zh-CN' => 'Chinese (Simplified)', + 'zh-TW' => 'Chinese (Traditional)', + 'hr' => 'Croatian', + 'cs' => 'Czech', + 'da' => 'Danish', + 'nl' => 'Dutch', + 'en-GB' => 'English (UK)', + 'en' => 'English (US)', + 'et' => 'Estonian', + 'fil' => 'Filipino', + 'fi' => 'Finnish', + 'fr' => 'French', + 'fr-CA' => 'French (Canadian)', + 'gl' => 'Galician', + 'ka' => 'Georgian', + 'de' => 'German', + 'de-AT' => 'German (Austria)', + 'de-CH' => 'German (Switzerland)', + 'el' => 'Greek', + 'gu' => 'Gujarati', + 'iw' => 'Hebrew', + 'hi' => 'Hindi', + 'hu' => 'Hungarain', + 'is' => 'Icelandic', + 'id' => 'Indonesian', + 'it' => 'Italian', + 'ja' => 'Japanese', + 'kn' => 'Kannada', + 'ko' => 'Korean', + 'lo' => 'Laothian', + 'lv' => 'Latvian', + 'lt' => 'Lithuanian', + 'ms' => 'Malay', + 'ml' => 'Malayalam', + 'mr' => 'Marathi', + 'mn' => 'Mongolian', + 'no' => 'Norwegian', + 'fa' => 'Persian', + 'pl' => 'Polish', + 'pt' => 'Portuguese', + 'pt-BR' => 'Portuguese (Brazil)', + 'pt-PT' => 'Portuguese (Portugal)', + 'ro' => 'Romanian', + 'ru' => 'Russian', + 'sr' => 'Serbian', + 'si' => 'Sinhalese', + 'sk' => 'Slovak', + 'sl' => 'Slovenian', + 'es' => 'Spanish', + 'es-419' => 'Spanish (Latin America)', + 'sw' => 'Swahili', + 'sv' => 'Swedish', + 'ta' => 'Tamil', + 'te' => 'Telugu', + 'th' => 'Thai', + 'tr' => 'Turkish', + 'uk' => 'Ukrainian', + 'ur' => 'Urdu', + 'vi' => 'Vietnamese', + 'zu' => 'Zulu', + ]; + } + + /** + * Checks whether a language code is supported by the language map or not. + * + * @param string $language_code + * + * @return bool Whether a language code is supported by the language map or not. + */ + public function is_supported( $language_code ) { + return (bool) $this->convert_language_code( $language_code ); + } + + /** + * Converts a language code from the format used by WP to the one used by the language map. + * + * @param string $language_code A language code in the format used by WP; e.g. `en_US`. + * + * @return string|false The converted language code or `false` if the language code is not supported. + */ + public function convert_language_code( $language_code ) { + $converted_code = $language_code; + if ( strlen( $language_code ) > 2 ) { + // go from `en_US` to `en-US` + $converted_code = str_replace( '_', '-', $language_code ); + $exists = array_key_exists( $converted_code, $this->get_supported_languages() ); + // try with just the two first chars + $converted_code = $exists ? $converted_code : $this->convert_language_code( substr( $language_code, 0, 2 ) ); + } else { + $converted_code = array_key_exists( $language_code, $this->get_supported_languages() ) ? $converted_code : false; + } + + return $converted_code ? $converted_code : false; + } +} diff --git a/tribe-common/src/Tribe/Log.php b/tribe-common/src/Tribe/Log.php new file mode 100644 index 0000000000..b25ac9581d --- /dev/null +++ b/tribe-common/src/Tribe/Log.php @@ -0,0 +1,437 @@ + description ]. + * + * @var array + */ + protected $levels = []; + + /** + * Alternative representation of the $levels property allowing quick look + * up of levels by priority. + * + * @var array + */ + protected $prioritized_levels = []; + + /** + * Instantiated loggers, stored for re-use. + * + * @var array + */ + protected $loggers = []; + + public function __construct() { + if ( is_admin() ) { + $this->admin = new Tribe__Log__Admin(); + } + + $this->current_level = $this->get_level(); + $this->log_cleanup(); + } + + /** + * @return Tribe__Log__Admin + */ + public function admin() { + return $this->admin; + } + + /** + * Facilitates daily cleanup and log rotation. + */ + protected function log_cleanup() { + $this->register_cleanup_task(); + do_action( self::CLEANUP, [ $this, 'do_cleanup' ] ); + } + + /** + * Schedules a daily cleanup task if one is not already in place. + */ + protected function register_cleanup_task() { + if ( ! wp_next_scheduled( self::CLEANUP ) ) { + wp_schedule_event( strtotime( '+1 day' ), 'daily', self::CLEANUP ); + } + } + + /** + * Call the cleanup() method for each available logging engine. + * + * We don't just call it on the current engine since, if there was a recent change, + * we'll generally still want the now unused engine's output to be cleaned up. + */ + public function do_cleanup() { + foreach ( $this->get_logging_engines() as $engine ) { + /** + * @var Tribe__Log__Logger $engine + */ + $engine->cleanup(); + } + } + + /** + * Logs a debug-level entry. + * + * @param string $entry + * @param string $src + */ + public function log_debug( $entry, $src ) { + $this->log( $entry, self::DEBUG, $src ); + } + + /** + * Logs a warning. + * + * @param string $entry + * @param string $src + */ + public function log_warning( $entry, $src ) { + $this->log( $entry, self::WARNING, $src ); + } + + /** + * Logs an error. + * + * @param string $entry + * @param string $src + */ + public function log_error( $entry, $src ) { + $this->log( $entry, self::ERROR, $src ); + } + + /** + * Logs a successful operation. + * + * @param string $entry + * @param string $src + */ + public function log_success( $entry, $src ) { + $this->log( $entry, self::SUCCESS, $src ); + } + + /** + * Logs an entry colorizing it. + * + * This will only apply to WP-CLI based logging. + * + * @param string $entry + * @param string $src + */ + public function log_colorized( $entry, $src ) { + $this->log( $entry, self::COLORIZE, $src ); + } + + /** + * Adds an entry to the log (if it is at the appropriate level, etc) and outputs information using WP-CLI if available. + * + * This is simply a shorthand for calling log() on the current logger. + */ + public function log( $entry, $type = self::DEBUG, $src = '' ) { + $original_type = $type; + + // some levels are really just debug information + $debug_types = [ self::SUCCESS, self::COLORIZE ]; + + if ( in_array( $type, $debug_types ) ) { + $type = self::DEBUG; + } + + if ( $this->should_log( $type ) ) { + $this->get_current_logger()->log( $entry, $type, $src ); + } + + /** + * Whether to log the message to wp-cli, if available, or not. + * + * @since 4.9.6 + * + * @param bool $log_to_wpcli Whether to log to wp-cli, if available, or not. + * @param string $entry The message entry. + * @param string $type The message type. + * @param string $src The message source. + */ + $log_to_wpcli = apply_filters( 'tribe_common_log_to_wpcli', true, $entry, $type, $src ); + + // Only go further if we have WP_CLI or if we want to log to WP-CLI. + if ( ! class_exists( 'WP_CLI' ) || false === $log_to_wpcli ) { + return false; + } + + // We are always logging to WP-CLI if available + switch ( $original_type ) { + case self::ERROR: + WP_CLI::error( $entry ); + break; + case self::WARNING: + WP_CLI::warning( $entry ); + break; + case self::SUCCESS: + WP_CLI::success( $entry ); + break; + case self::DEBUG: + WP_CLI::debug( $entry, $src ); + break; + + case self::COLORIZE: + default: + WP_CLI::log( WP_CLI::colorize( $entry ) ); + break; + } + } + + /** + * Returns a list of available logging engines as an array where each + * key is the classname and the value is the logger itself. + * + * @return array + */ + public function get_logging_engines() { + $available_engines = []; + $bundled_engines = [ + 'Tribe__Log__File_Logger', + ]; + + foreach ( $bundled_engines as $engine_class ) { + $engine = $this->get_engine( $engine_class ); + + // Check that we have a valid engine that is available for use in the current environment + if ( $engine && $engine->is_available() ) { + $available_engines[ $engine_class ] = $engine; + } + } + + /** + * Offers a chance to modify the array of currently available logging engines. + * + * The array is organized with each key as the class name of the logging + * implementation and the matching value is the actual logger object. + * + * @var array $available_engines + */ + return apply_filters( 'tribe_common_logging_engines', $available_engines ); + } + + /** + * Returns the currently active logger. + * + * If no loggers are available, this will be the null logger which is a no-op + * implementation (making it safe to call Tribe__Log__Logger methods on the + * return value of this method at all times). + * + * @since 4.6.2 altered the return signature to only return instances of Tribe__Log__Logger + * + * @return Tribe__Log__Logger + */ + public function get_current_logger() { + if ( ! $this->current_logger ) { + $engine = tribe_get_option( 'logging_class', null ); + $available = $this->get_logging_engines(); + + if ( empty( $engine ) || ! isset( $available[ $engine ] ) ) { + return $this->current_logger = new Tribe__Log__Null_Logger(); + } else { + $this->current_logger = $this->get_engine( $engine ); + } + } + + return $this->current_logger; + } + + /** + * Sets the current logging engine to the provided class (if it is a valid + * and currently available logging class, else will set this to null - ie + * no logging). + * + * @param string $engine + * + * @throws Exception if the specified logging engine is invalid + */ + public function set_current_logger( $engine ) { + $available_engines = $this->get_logging_engines(); + + // Make sure to de-duplicate the slashes on class names. + $engine = str_replace( '\\\\', '\\', $engine ); + + if ( ! isset( $available_engines[ $engine ] ) ) { + throw new Exception( sprintf( __( 'Cannot set %s as the current logging engine', 'tribe-common' ), $engine ) ); + } + + tribe_update_option( 'logging_class', $engine ); + $this->current_logger = $available_engines[ $engine ]; + } + + /** + * Attempts to return the requested logging object or null if that + * is not possible. + * + * @param $class_name + * + * @return Tribe__Log__Logger|null + */ + public function get_engine( $class_name ) { + if ( ! isset( $this->loggers[ $class_name ] ) ) { + $object = new $class_name; + + if ( $object instanceof Tribe__Log__Logger ) { + $this->loggers[ $class_name ] = new $class_name(); + } + } + + if ( isset( $this->loggers[ $class_name ] ) ) { + return $this->loggers[ $class_name ]; + } + + return null; + } + + /** + * Sets the current logging level to the provided level (if it is a valid + * level, else will set the level to 'default'). + * + * @param string $level + */ + public function set_level( $level ) { + $available_levels = wp_list_pluck( $this->get_logging_levels(), 0 ); + + if ( ! in_array( $level, $available_levels ) ) { + $level = self::DISABLE; + } + + tribe_update_option( 'logging_level', $level ); + $this->current_level = $level; + } + + /** + * Returns the current logging level as a string. + * + * @return string + */ + public function get_level() { + $current_level = tribe_get_option( 'logging_level', null ); + $available_levels = wp_list_pluck( $this->get_logging_levels(), 0 ); + + if ( ! in_array( $current_level, $available_levels ) ) { + $current_level = self::DISABLE; + } + + return $current_level; + } + + /** + * Returns a list of logging levels. + * + * The format is an array of arrays, each inner array being comprised of the + * level code (index 0) and a human readable description (index 1). + * + * The ordering of the inner arrays is critical as it dictates what will be logged + * when a given logging level is in effect. Example: if the current logging level + * is "error" mode (only record error-level problems) then debug-level notices will + * *not* be recorded and nor will warnings. + * + * On the other hand, if the current logging level is "debug" then debug level + * notices *and* all higher levels (including warnings and errors) will be recorded. + * + * @return array + */ + public function get_logging_levels() { + if ( empty( $this->levels ) ) { + /** + * Provides an opportunity to add or remove logging levels. This is expected + * to be organized as an array of arrays: the ordering of each inner array + * is critical, see Tribe__Log::get_logging_levels() docs. + * + * General form: + * + * [ + * [ 'disable' => 'description' ], // * Do not log anything + * [ 'error' => 'description' ], // ^ Log only the most critical problems + * [ 'warning' => 'description' ], // | ... + * [ 'debug' => 'description' ] // v Log as much data as possible, including less important trivia + * ] + * + * @param array $logging_levels + */ + $this->levels = (array) apply_filters( 'tribe_common_logging_levels', [ + [ self::DISABLE, __( 'Disabled', 'tribe-common' ) ], + [ self::ERROR, __( 'Only errors', 'tribe-common' ) ], + [ self::WARNING, __( 'Warnings and errors', 'tribe-common' ) ], + [ self::DEBUG, __( 'Full debug (all events)', 'tribe-common' ) ], + ] ); + } + + return $this->levels; + } + + /** + * Indicates if errors relating to the specified logging level should indeed + * be logged. + * + * Examples if the current logging level is "warning" (log all warnings and errors): + * + * * Returns true for "error" + * * Returns true for "warning" + * * Returns false for "debug" + * + * The above assumes we are using the default logging levels. + * + * @param string $level_code + * + * @return bool + */ + protected function should_log( $level_code ) { + if ( empty( $this->prioritized_levels ) ) { + $this->build_prioritized_levels(); + } + + // Protect against the possibility non-existent level codes might be passed in + if ( ! isset( $this->prioritized_levels[ $level_code ] ) ) { + return false; + } + + return $this->prioritized_levels[ $level_code ] <= $this->prioritized_levels[ $this->current_level ]; + } + + /** + * Creates a second list of logging levels allowing easy lookup of + * their relative priorities (ie, a means of quickly checking if + * an "error" level entry should be recorded when we're in debug + * mode). + */ + protected function build_prioritized_levels() { + foreach ( $this->get_logging_levels() as $index => $level_data ) { + $this->prioritized_levels[ $level_data[ 0 ] ] = $index; + } + } +} diff --git a/tribe-common/src/Tribe/Log/Action_Logger.php b/tribe-common/src/Tribe/Log/Action_Logger.php new file mode 100644 index 0000000000..2d2dc07c09 --- /dev/null +++ b/tribe-common/src/Tribe/Log/Action_Logger.php @@ -0,0 +1,125 @@ +translate_log_level( $type ), $message ); + } + + /** + * Translates the log types used by `Tribe__Log` to those used by Monolog. + * + * @since 4.9.16 + * + * @param string $type The `Tribe__Log` log type. + * + * @return int The Monolog equivalent of the current level. + */ + protected function translate_log_level( $type ) { + switch ( $type ) { + case Tribe__Log::DEBUG: + return Logger::DEBUG; + case Tribe__Log::ERROR: + return Logger::ERROR; + case Tribe__Log::WARNING: + return Logger::WARNING; + case Tribe__Log::SUCCESS: + default: + return Logger::INFO; + } + } + + /** + * {@inheritDoc} + * + * @since 4.9.16 + */ + public function retrieve( $limit = 0, array $args = [] ) { + return [ + [ + 'message' => __( + 'The Action Logger will dispatch any logging message using the "tribe_log" action writing, by ' . + 'default, to the PHP error log.', + 'tribe-common' ) + ], + ]; + } + + /** + * {@inheritDoc} + * + * @since 4.9.16 + */ + public function list_available_logs() { + return []; + } + + /** + * Changes the Monolog logger channel to the specified one. + * + * @since 4.9.16 + * + * @param string $log_identifier The channel to switch to. + * @param bool $create Unused by this class. + * + * @return bool The exit status of the channel change. + * + * @uses \Tribe\Log\Monolog_Logger::set_channel(). + */ + public function use_log( $log_identifier, $create = false ) { + return tribe( 'monolog' )->set_global_channel( $log_identifier ); + } + + /** + * {@inheritDoc} + * + * @since 4.9.16 + */ + public function cleanup() { + return true; + } +} diff --git a/tribe-common/src/Tribe/Log/Admin.php b/tribe-common/src/Tribe/Log/Admin.php new file mode 100644 index 0000000000..4a60af9db8 --- /dev/null +++ b/tribe-common/src/Tribe/Log/Admin.php @@ -0,0 +1,270 @@ + Settings > Help screen. + * + * @return string + */ + public function display_log() { + $log_choices = $this->get_available_logs(); + $log_engines = $this->get_log_engines(); + $log_levels = $this->get_logging_levels(); + $log_entries = $this->get_log_entries(); + $download_url = $this->get_log_url(); + + ob_start(); + include trailingslashit( Tribe__Main::instance()->plugin_path ) . 'src/admin-views/event-log.php'; + return ob_get_clean(); + } + + /** + * Listens for changes to the event log settings updating and returning + * an appropriate response. + */ + public function listen() { + $fields = wp_parse_args( $_POST, [ + 'check' => '', + 'log-level' => '', + 'log-engine' => '', + ] ); + + foreach ( $fields as &$single_field ) { + $single_field = sanitize_text_field( $single_field ); + } + + if ( ! wp_verify_nonce( $fields['check'], 'logging-controls' ) ) { + return; + } + + /** + * Fires before log settings are committed. + * + * This will not happen unless a nonce check has already passed. + */ + do_action( 'tribe_common_update_log_settings' ); + + $this->update_logging_level( $fields['log-level'] ); + $this->update_logging_engine( $fields['log-engine'] ); + + /** + * Fires immediately after log settings have been committed. + */ + do_action( 'tribe_common_updated_log_settings' ); + + $data = [ + 'logs' => $this->get_available_logs(), + ]; + + if ( ! empty( $fields['log-view'] ) ) { + $data['entries'] = $this->get_log_entries( $fields['log-view'] ); + } + + wp_send_json_success( $data ); + } + + /** + * Sets the current logging level to the provided level (if it is a valid + * level, else will set the level to 'default'). + * + * @param string $level + */ + protected function update_logging_level( $level ) { + $this->log_manager()->set_level( $level ); + } + + /** + * Sets the current logging engine to the provided class (if it is a valid + * and currently available logging class, else will set this to null - ie + * no logging). + * + * @param string $engine + */ + protected function update_logging_engine( $engine ) { + try { + $this->log_manager()->set_current_logger( $engine ); + } + catch ( Exception $e ) { + // The class name did not relate to a valid logging engine + } + } + + /** + * Register our script early. + */ + public function register_script() { + tribe_asset( + Tribe__Main::instance(), + 'tribe-common-logging-controls', + 'admin-log-controls.js', + [ 'jquery' ], + 'admin_enqueue_scripts', + [ + 'conditionals' => [ Tribe__Admin__Help_Page::instance(), 'is_current_page' ], + 'localize' => (object) [ + 'name' => 'tribe_logger_data', + 'data' => [ + 'check' => wp_create_nonce( 'logging-controls' ), + ], + ], + ] + ); + } + + /** + * Returns a list of logs that are available for perusal. + * + * @return array + */ + protected function get_available_logs() { + $current_logger = $this->current_logger(); + + if ( $current_logger ) { + $available_logs = $this->current_logger()->list_available_logs(); + } + + if ( empty( $available_logs ) ) { + return [ '' => _x( 'None currently available', 'log selector', 'tribe-common' ) ]; + } + + return $available_logs; + } + + /** + * Returns a list of logging engines that are available for use. + * + * @return array + */ + protected function get_log_engines() { + $available_engines = $this->log_manager()->get_logging_engines(); + + if ( empty( $available_engines ) ) { + return [ '' => _x( 'None currently available', 'log engines', 'tribe-common' ) ]; + } + + $engine_list = []; + + foreach ( $available_engines as $class_name => $engine ) { + /** + * @var Tribe__Log__Logger $engine + */ + $engine_list[ $class_name ] = $engine->get_name(); + } + + return $engine_list; + } + + /** + * Returns all log entries for the current or specified log. + * + * @return array + */ + protected function get_log_entries( $log = null ) { + if ( $logger = $this->current_logger() ) { + $logger->use_log( $log ); + return (array) $logger->retrieve(); + } + + return []; + } + + /** + * Returns an array of logging levels arranged as key:value pairs, with + * each key being the level code and the value being the human-friendly + * description. + * + * @return array + */ + protected function get_logging_levels() { + $levels = []; + $available_levels = $this->log_manager()->get_logging_levels(); + + foreach ( $available_levels as $logging_level ) { + $levels[ $logging_level[0] ] = $logging_level[1]; + } + + return $levels; + } + + /** + * Provides a URL that can be used to download the current or specified + * log. + * + * @param $log + * + * @return string + */ + protected function get_log_url( $log = null ) { + $query = [ + 'tribe-common-log' => 'download', + 'check' => wp_create_nonce( 'download_log' ), + ]; + + $log_download_url = add_query_arg( $query, get_admin_url( null, 'edit.php' ) ); + + return esc_url( $log_download_url ); + } + + /** + * Facilitate downloading of logs. + */ + public function serve_log_downloads() { + if ( empty( $_GET['tribe-common-log'] ) || 'download' !== $_GET['tribe-common-log'] ) { + return; + } + + if ( ! wp_verify_nonce( @$_GET['check'], 'download_log' ) ) { + return; + } + + if ( empty( $_GET['log'] ) || ! in_array( $_GET['log'], $this->get_available_logs() ) ) { + return; + } + + $log_name = sanitize_file_name( $_GET['log'] ); + $this->current_logger()->use_log( $log_name ); + + /** + * Provides an opportunity to modify the recommended filename for a downloaded + * log file. + * + * @param string $log_name + */ + $log_name = apply_filters( 'tribe_common_log_download_filename', $log_name ); + + header( 'Content-Disposition: attachment; filename="tribe-log-' . $log_name . '"' ); + $output = fopen( 'php://output', 'w' ); + + foreach ( $this->current_logger()->retrieve() as $log_entry ) { + fputcsv( $output, $log_entry ); + } + + fclose( $output ); + exit(); + } + + /** + * Returns a reference to the main log management object. + * + * @return Tribe__Log + */ + protected function log_manager() { + return tribe( 'logger' ); + } + + /** + * Returns the currently enabled logging object or null if it is not + * available. + * + * @return Tribe__Log__Logger|null + */ + protected function current_logger() { + return tribe( 'logger' )->get_current_logger(); + } +} diff --git a/tribe-common/src/Tribe/Log/Canonical_Formatter.php b/tribe-common/src/Tribe/Log/Canonical_Formatter.php new file mode 100644 index 0000000000..52332c54e8 --- /dev/null +++ b/tribe-common/src/Tribe/Log/Canonical_Formatter.php @@ -0,0 +1,174 @@ +format_record_message( $record ); + $formatter = $this->get_context_formatter(); + } else { + // Fall-back on a standard format if the message does not have a context. + $formatter = $this->get_standard_formatter(); + } + + return $formatter->format( $record ); + } + + /** + * Gets a LineFormatter whose format is context aware. + * + * @since 4.12.13 + * + * @return LineFormatter + */ + public function get_context_formatter() { + if ( empty( $this->context_formatter ) ) { + $this->context_formatter = new LineFormatter( $this->context_format ); + } + + return $this->context_formatter; + } + + /** + * Gets a LineFormatter whose format is our standard logging format. + * + * @since 4.12.13 + * + * @return LineFormatter + */ + public function get_standard_formatter() { + if ( empty( $this->standard_formatter ) ) { + $this->standard_formatter = new LineFormatter( $this->standard_format ); + } + + return $this->standard_formatter; + } + + /** + * Formats a set of log records. + * + * This simply hands off the work of formatting Batches to the LineFormatter. + * + * @since 4.12.13 + * + * @param array $records A set of records to format + * @return mixed The formatted set of records + */ + public function formatBatch( array $records ) { + $line_formatter = new LineFormatter(); + + return $line_formatter->formatBatch( $records ); + } + + /** + * Formats the record to the canonical format. + * + * @since 4.9.16 + * + * @param array $record The record to process. + * + * @return string The formatted message, as built from the record context and message, in the format `=`. + */ + protected function format_record_message( array $record ) { + $message = []; + $extra = []; + + $extra['level'] = isset( $record['level_name'] ) ? strtolower( $record['level_name'] ) : 'debug'; + + if ( ! empty( $record['message'] ) ) { + // Use the message as the source. + $extra['source'] = $this->escape_quotes( $record['message'] ); + } + + $context = $record['context']; + $context = array_merge( $extra, $context ); + + foreach ( $context as $key => $value ) { + $escape = false; + + if ( is_bool( $value ) ) { + $value = $value ? 'true' : 'false'; + } elseif ( ! is_scalar( $value ) ) { + $value = json_encode( $value ); + if ( false === $value ) { + $value = 'malformed'; + } else { + $escape = true; + } + } + + if ( $escape || ( is_string( $value ) && preg_match( '~[\\\\/\\s]+~', $value ) ) ) { + $value = '"' . $this->escape_quotes( $value ) . '"'; + } + + $message[] = "{$key}={$value}"; + } + + return implode( ' ', $message ); + } + + /** + * Escapes the double quotes in a string. + * + * @since 4.9.16 + * + * @param string $string The string to escape the quotes in. + * + * @return string The string, with the quotes escaped. + */ + protected function escape_quotes( $string ) { + return str_replace( '"', '\\"', $string ) ; + } +} diff --git a/tribe-common/src/Tribe/Log/File_Logger.php b/tribe-common/src/Tribe/Log/File_Logger.php new file mode 100644 index 0000000000..ef69a7f38e --- /dev/null +++ b/tribe-common/src/Tribe/Log/File_Logger.php @@ -0,0 +1,314 @@ +set_log_dir(); + $this->set_log_file(); + } + + public function __destruct() { + $this->close_handle(); + } + + protected function set_log_dir() { + /** + * Controls the directory used for logging. + * + * @var string $log_dir + */ + $this->log_dir = apply_filters( 'tribe_file_logger_directory', get_temp_dir() ); + } + + /** + * Sets the path for the log file we're currently interested in using. + * + * @param string $date = null + */ + protected function set_log_file( $date = null ) { + $this->log_file = $this->get_log_file_name( $date ); + $this->obtain_handle(); + } + + /** + * Used to switch between contexts for reading ('r') and writing + * ('a' := append) modes. + * + * @see fopen() documentation + * + * @param string $context + */ + protected function set_context( $context ) { + $this->context = $context; + $this->close_handle(); + $this->obtain_handle(); + } + + /** + * Attempts to obtain a file handle for the current log file. + */ + protected function obtain_handle() { + $this->close_handle(); + + if ( ! file_exists( $this->log_file ) && $this->is_available() ) { + touch( $this->log_file ); + } + + // Bail if we're attempting to write but don't have permission. + if ( 'r' !== $this->context && ! is_writable( $this->log_file ) ) { + return; + } + + if ( is_readable( $this->log_file ) ) { + $this->handle = fopen( $this->log_file, $this->context ); + } + } + + /** + * Closes the current file handle, if one is open. + */ + protected function close_handle() { + // is_resource() only returns true for open resources + if ( is_resource( $this->handle ) ) { + fclose( $this->handle ); + } + } + + /** + * Returns the log name to be used for reading/writing events for a specified date + * (defaulting to today, if no date is specified). + * + * @param string $date = null + * + * @return string + */ + protected function get_log_file_name( $date = null ) { + if ( null === $date ) { + $date = date_i18n( 'Y-m-d' ); + } + + $filename = $this->log_dir . DIRECTORY_SEPARATOR . $this->get_log_file_basename() . $date . '.log'; + + /** + * Dictates the filename of the log used to record events for the specified date. + * + * @var string $filename + * @var string $date + */ + return apply_filters( 'tribe_file_logger_filename', $filename, $date ); + } + + protected function get_log_file_basename() { + /** + * Log files share a common prefix, which aids identifying archived/rotated logs. + * This filter allows a degree of control to be exercised over the prefix to avoid + * conflicts, etc. + * + * @var string $log_file_base_name + */ + return apply_filters( 'tribe_file_logger_file_prefix', $this->module_id . '_' ); + } + + /** + * Returns a 'human friendly' name for the logging implementation. + * + * @return string + */ + public function get_name() { + return __( 'Default (uses temporary files)', 'tribe-common' ); + } + + /** + * Indicates if the logger will work in the current environment. + * + * @return bool + */ + public function is_available() { + return is_writable( $this->log_dir ) && is_readable( $this->log_dir ); + } + + /** + * Responsible for commiting the entry to the log. + * + * @param string $entry + * @param string $type + * @param string $src + */ + public function log( $entry, $type = Tribe__Log::DEBUG, $src = '' ) { + // Ensure we're in 'append' mode before we try to write + if ( 'a' !== $this->context ) { + $this->set_context( 'a' ); + } + + // Couldn't obtain the file handle? We'll bail out without causing further disruption + if ( ! $this->handle ) { + return; + } + + fputcsv( $this->handle, [ date_i18n( 'Y-m-d H:i:s' ), $entry, $type, $src ] ); + } + + /** + * Retrieve up to $limit most recent log entries in reverse chronological + * order. If $limit is a negative or zero value, there is no limit. + * + * Supports passing a 'log' argument to recover + * + * @see Tribe__Log__Logger::list_available_logs() + * + * @param int $limit + * @param array $args + * + * @return array + */ + public function retrieve( $limit = 0, array $args = [] ) { + // Ensure we're in 'read' mode before we try to retrieve + if ( 'r' !== $this->context ) { + $this->set_context( 'r' ); + } + + // Couldn't obtain the file handle? We'll bail out without causing further disruption + if ( ! $this->handle ) { + return []; + } + + $rows = []; + + while ( $current_row = fgetcsv( $this->handle ) ) { + if ( $limit && $limit === count( $rows ) ) { + array_shift( $rows ); + } + + $rows[] = $current_row; + } + + return array_reverse( $rows ); + } + + /** + * Returns a list of currently accessible logs (current first, oldest last). + * Each is refered to by date. + * + * Example: + * + * [ '2016-12-31', + * '2016-12-30', + * '2016-12-30', + * '2016-12-30', + * '2016-12-30', ... ] + * + * @since 4.6.2 added extra safety checks before attempting to access log directory + * + * @return array + */ + public function list_available_logs() { + $logs = []; + + // This could be called when the log dir is not accessible. + if ( ! $this->is_available() ) { + return $logs; + } + + $basename = $this->get_log_file_basename(); + + /** + * Though the is_available() method tests to see if the log directory is + * readable and writeable there are situations where that isn't a + * sufficient check by itself, hence the try/catch block. + * + * @see https://central.tri.be/issues/90436 + */ + try { + $log_files_dir = new DirectoryIterator( $this->log_dir ); + + // Look through the log storage directory + foreach ( $log_files_dir as $node ) { + if ( ! $node->isReadable() ) { + continue; + } + + $name = $node->getFilename(); + $ext = $node->getExtension(); + + // Skip unless it is a .log file with the expected prefix + if ( 'log' !== $ext || 0 !== strpos( $name, $basename ) ) { + continue; + } + + if ( preg_match( '/([0-9]{4}\-[0-9]{2}\-[0-9]{2})/', $name, $matches ) ) { + $logs[] = $matches[1]; + } + } + + rsort( $logs ); + } catch ( Exception $e ) { + return $logs; + } + + return $logs; + } + + /** + * Switches to the specified log. The $log_identifier should take the + * form of a "yyyy-mm-dd" format date string. + * + * If optional param $create is true then it will try to create a log + * using the provided identifier. If the log does not exist, cannot be + * created or an invalid identifier has been passed in then boolean false + * will be returned, otherwise it will attempt to switch to the new log. + * + * @param mixed $log_identifier + * @param bool $create + * + * @return bool + */ + public function use_log( $log_identifier, $create = false ) { + $log_file = $this->get_log_file_name( $log_identifier ); + $exists = file_exists( $log_file ); + + if ( ! $exists && ! $create ) { + return false; + } + + if ( ! $exists && $create && preg_match( '/^([0-9]{4}\-[0-9]{2}\-[0-9]{2})$/', $log_file ) ) { + if ( false === file_put_contents( $log_file, '' ) ) { + return false; + } + } + + $this->set_log_file( $log_identifier ); + return true; + } + + /** + * Performs routine maintenance and cleanup work (such as log rotation) + * whenever it is called. + */ + public function cleanup() { + // Default to retaining 7 days worth of logs + $cutoff = date_i18n( 'Y-m-d', current_time( 'timestamp' ) - WEEK_IN_SECONDS ); + + /** + * Logs falling on or earlier than this date will be removed. + * + * @param string $cutoff 'Y-m-d' format date string + */ + $cutoff = apply_filters( 'tribe_file_logger_cutoff', $cutoff ); + + foreach ( $this->list_available_logs() as $available_log ) { + if ( $available_log <= $cutoff ) { + unlink( $this->get_log_file_name( $available_log ) ); + } + } + } +} diff --git a/tribe-common/src/Tribe/Log/Logger.php b/tribe-common/src/Tribe/Log/Logger.php new file mode 100644 index 0000000000..0ffeb09371 --- /dev/null +++ b/tribe-common/src/Tribe/Log/Logger.php @@ -0,0 +1,88 @@ +set_global_channel( static::DEFAULT_CHANNEL ); + } + + /** + * Clones this logger and replaces it in the `tribe` container. + * + * @since 4.9.16 + * + * @param string $channel The new logger name, also referred to as "channel" (hence the method name). + * + * @return bool Whether the channel change was successful or not. + */ + public function set_global_channel( $channel ) { + $new = $this->withName( $channel ); + tribe_register( Logger::class, $new ); + tribe_register( 'monolog', $new ); + + return $channel === tribe( 'monolog' )->getName(); + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Log/Null_Logger.php b/tribe-common/src/Tribe/Log/Null_Logger.php new file mode 100644 index 0000000000..953215731d --- /dev/null +++ b/tribe-common/src/Tribe/Log/Null_Logger.php @@ -0,0 +1,106 @@ + Pro tip: if you, as a developer, find yourself using `var_dump` and `error_log` a lot, then you should log instead. Someone, someday, will have your same issue. + +Worried about "spamming" the logs? [Read here](#logging-levels--or-stuff-does-not-appear-in-the-log). + +## This will deprecate the old logger, but not yet + +At first we're not replacing the "old" logger with this new one, we're just asking you **to stop using the old logger** in your code from now on and use the new, Monolog-based, one. +The old logger still offers file-based logging and connections to the UI the new logger is not yet offering; the current implementation will allow us, in the future, to log **everything** with the Monolog-based logger, but, currently, intercepting log messages from the "old" logger requires manual activation, see the following section. + +To be clear: this is what we mean by "old" or "legacy" logger: + +```php +log_debug( 'Some debug information', 'The source' ); +tribe( 'logger' )->log( 'Some information', Tribe__Log::DEBUG, 'The source' ); +``` + +### Intercepting legacy logger logs with the new Monolog logger + +The Monolog-based logger will handle logging coming from the legacy logger only if explicitly told so. + + You can activate this function with this code: + + ```php + 'updated', 'post_id' => $id, 'origin' => $origin ] +); +``` + +The logger listening on the action will consume three parameters: + +1. `level` - `debug` in the example; is the level of the log; available levels, in increasing value of urgency are: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`. Use each level wisely. +2. `source` - `ea_client` in this example; is the source of the log; this is a human-readable value; consistency is king here. +3. `context` - the array in this example; this is an associative array that will be logged to define the context of the log. Think of this as something that will provide the details required to unpack what **was** happening when the log entry was created. Provide enough context to make it clear, but avoid bloating it. + +## Where are my logs? + +The initial implementation of the new logger will write, by default, to the **PHP error** log. + +We're using Monolog to allow us, and third parties, to "attach" and "deatach" loggers as required. +By default we're formatting logs using canonical lines( read more [here](https://brandur.org/logfmt) and [here](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write/)) to make our log entries both human-readable and machine parsable (e.g. by a tool like [this](https://www.npmjs.com/package/logfmt)). + +The output format of the example above would be this: + +``` +[22-Aug-2019 15:50:42 UTC] tribe-canonical-line channel=default level=debug source=ea_client action=updated post_id=23 origin=ical +``` + +What about legacy logs? +Their format would not be formatted to the canonical line style: + +``` +[22-Aug-2019 16:03:33 UTC] tribe.default.DEBUG: The source: debug information +``` + +### Logging levels ( or "stuff does not appear in the log") + +By default we're only logging Warnings and above. +This means all your `debug` level logs are being ignored. + +In production we do not want to fill people logs with pointless information, but you can control the level of logging: any log equal or above the specified level will be logged. + +You can control the logging level with the `tribe_log_level` filter: + +```php +set_global_channel( 'my_channel' ); +do_action( 'tribe_log', 'debug', 'my_source', [ 'foo' => 'bar' ] ); +tribe( 'logger' )->log_debug( 'Some debug information', 'My source' ); +``` + +You can do the same using the legacy logger, [if enabled][0527-0003]: + +```php +use_log( 'my_channel' ); +``` + +Any log produced after the call will log to the `my_channel` channel; this will apply to the legacy logger too ([if redirected][0527-0003]): + +``` +[22-Aug-2019 15:50:42 UTC] tribe-canonical-line channel=default level=debug source=ea_client action=updated post_id=23 origin=ical +[22-Aug-2019 15:51:13 UTC] tribe-canonical-line channel=my_channel level=debug source=my_source foo=bar +[22-Aug-2019 16:03:33 UTC] tribe.my_channel.DEBUG: My source: Some debug information +``` + +## I want to use this right now to debug my code + +Copy and paste this in a plugin, or must-use plugin. +If you're using a plugin remember to activate it. + +```php +container->singleton( 'log', $this ); + $this->container->singleton( static::class, $this ); + $this->container->singleton( Logger::class, [ $this, 'build_logger' ] ); + $this->container->singleton( 'monolog', + function () { + return $this->container->make( Logger::class ); + } + ); + + add_action( 'tribe_log', [ $this, 'dispatch_log' ], 10, 3 ); + + /** + * Filters whether to make the Action Logger available as logger or not. + * + * @since 4.9.16 + * + * @param bool $use_action_logger Whether to allow logging messages from the \Tribe\Log\Logger class using the + * `tribe_log` action or not. + */ + $use_action_logger = apply_filters( 'tribe_log_use_action_logger', false ); + + if ( $use_action_logger ) { + add_filter( 'tribe_common_logging_engines', [ $this, 'add_logging_engine' ] ); + } + } + + /** + * Builds and returns the Monolog Logger instance that will listen to the `tribe_log` action. + * + * To avoid the over-head introduced by filtering the filters are applied here, only once, when the instance is + * first built. Any later call will use the singleton instance stored in the container. + * + * @since 4.9.16 + * + * @return Logger + */ + public function build_logger() { + /** + * Filters the level of the messages that will be logged. + * + * The threshold is inclusive of the level; it default to log any warning and above. + * + * @since 4.9.16 + * + * @param int The threshold level; if the level of a message is this level or above, then it will be logged. + * + * @see \Monolog\Logger for possible levels. + */ + $level_threshold = apply_filters( 'tribe_log_level', Logger::WARNING ); + + $error_log_handler = new ErrorLogHandler( ErrorLogHandler::OPERATING_SYSTEM, $level_threshold ); + + /** + * Filters whether to use canonical format for the logs or not. + * + * @since 4.9.16 + * + * @param bool $use_canonical_format Whether to use canonical format for the logs or not; defaults to `true`. + */ + $use_canonical_format = apply_filters( 'tribe_log_canonical', true ); + + if ( $use_canonical_format ) { + $error_log_handler->setFormatter( new Canonical_Formatter() ); + } + + $handlers = [ + 'default' => $error_log_handler + ]; + + /** + * Filters the list of handlers that will handle dispatched log messages. + * + * All handlers should implement the `\Monolog\Handler\HandlerInterface`. + * + * @since 4.9.16 + * + * @param array $handlers An array of default log handlers. + */ + $handlers = apply_filters( 'tribe_log_handlers', $handlers ); + + // Monolog will log to stderr when no handlers are set. + $logger = new Monolog_Logger( Monolog_Logger::DEFAULT_CHANNEL ); + + $logger->setHandlers( $handlers ); + + return $logger; + } + + /** + * Dispatch a message of a specific level. + * + * Available levels are: `debug`, `info`, `notice`, `warning`, `error`, `critical`, `alert`, `emergency`. + * + * @since 4.9.16 + * + * @param string|int $level Either the log level or the log pretty name, see long description. + * @param string $message The message to log. + * @param array $context An array of values to define the context. + * + * @see \Monolog\Logger for the log level constants and names. + */ + public function dispatch_log( $level = 'debug', $message = '', array $context = [] ) { + // Goes from something like `debug` to `100`. + $level = is_numeric( $level ) ? $level : Logger::toMonologLevel( $level ); + + /** @var Logger $logger */ + $logger = $this->container->make( Logger::class ); + + $logger->log( $level, $message, $context ); + } + + /** + * Makes the action-based logging engine available in the backend. + * + * @since 4.9.16 + * + * @param array $logging_engines An array of available logging engines. + * + * @return array The updated array of logging engines. + */ + public function add_logging_engine( array $logging_engines = [] ) { + $logging_engines[ Action_Logger::class ] = new Action_Logger(); + + return $logging_engines; + } + + /** + * Enables logging in the service provider, if not already enabled. + * + * @since 4.12.15 + */ + public function enable() { + if ( has_action( 'tribe_log', [ $this, 'dispatch_log' ] ) ) { + return; + } + + add_action( 'tribe_log', [ $this, 'dispatch_log' ] ); + } + + /** + * Disables the logging functions. + * + * @since 4.12.15 + */ + public function disable() { + if ( ! has_action( 'tribe_log', [ $this, 'dispatch_log' ] ) ) { + return; + } + + remove_action( 'tribe_log', [ $this, 'dispatch_log' ] ); + } +} diff --git a/tribe-common/src/Tribe/Main.php b/tribe-common/src/Tribe/Main.php new file mode 100644 index 0000000000..761576204e --- /dev/null +++ b/tribe-common/src/Tribe/Main.php @@ -0,0 +1,717 @@ +plugin_context = $context; + $this->plugin_context_class = get_class( $context ); + } + + $this->plugin_path = trailingslashit( dirname( dirname( dirname( __FILE__ ) ) ) ); + $this->plugin_dir = trailingslashit( basename( $this->plugin_path ) ); + $parent_plugin_dir = trailingslashit( plugin_basename( $this->plugin_path ) ); + $this->plugin_url = plugins_url( $parent_plugin_dir === $this->plugin_dir ? $this->plugin_dir : $parent_plugin_dir ); + + $this->promoter_connector(); + + add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 1 ); + add_action( 'tribe_common_loaded', [ $this, 'tribe_common_app_store' ], 10 ); + } + + /** + * + */ + public function plugins_loaded() { + + $this->init_autoloading(); + + $this->bind_implementations(); + $this->init_libraries(); + $this->add_hooks(); + + /** + * Runs once all common libs are loaded and initial hooks are in place. + * + * @since 4.3 + */ + do_action( 'tribe_common_loaded' ); + + /** + * Runs to register loaded plugins + * + * @since 4.9 + */ + do_action( 'tribe_plugins_loaded ' ); + } + + /** + * Setup the autoloader for common files + */ + protected function init_autoloading() { + if ( ! class_exists( 'Tribe__Autoloader' ) ) { + require_once dirname( __FILE__ ) . '/Autoloader.php'; + } + + $autoloader = Tribe__Autoloader::instance(); + + $prefixes = [ 'Tribe__' => dirname( __FILE__ ) ]; + $autoloader->register_prefixes( $prefixes ); + + foreach ( glob( $this->plugin_path . 'src/deprecated/*.php' ) as $file ) { + $class_name = str_replace( '.php', '', basename( $file ) ); + $autoloader->register_class( $class_name, $file ); + } + + $autoloader->register_autoloader(); + } + + public function tribe_common_app_store() { + Tribe__Extension_Loader::instance(); + } + + /** + * Gets the instantiated context of this class. I.e. the object that instantiated this one. + */ + public function context() { + return $this->plugin_context; + } + + /** + * Gets the class name of the instantiated plugin context of this class. I.e. the class name of the object that instantiated this one. + */ + public function context_class() { + return $this->plugin_context_class; + } + + /** + * initializes all required libraries + */ + public function init_libraries() { + require_once $this->plugin_path . 'src/functions/utils.php'; + require_once $this->plugin_path . 'src/functions/url.php'; + require_once $this->plugin_path . 'src/functions/query.php'; + require_once $this->plugin_path . 'src/functions/multibyte.php'; + require_once $this->plugin_path . 'src/functions/template-tags/general.php'; + require_once $this->plugin_path . 'src/functions/template-tags/date.php'; + require_once $this->plugin_path . 'src/functions/template-tags/html.php'; + require_once $this->plugin_path . 'src/functions/template-tags/post.php'; + + Tribe__Debug::instance(); + tribe( 'assets' ); + tribe( 'assets.pipeline' ); + tribe( 'settings.manager' ); + tribe( 'tracker' ); + tribe( 'plugins.api' ); + tribe( 'pue.notices' ); + tribe( 'ajax.dropdown' ); + tribe( 'logger' ); + } + + /** + * Registers resources that can/should be enqueued + */ + public function load_assets() { + // These ones are only registered + tribe_assets( + $this, + [ + [ 'tribe-accessibility-css', 'accessibility.css' ], + [ 'tribe-query-string', 'utils/query-string.js' ], + [ 'tribe-clipboard', 'vendor/clipboard/clipboard.js' ], + [ 'datatables', 'vendor/datatables/datatables.js', [ 'jquery' ] ], + [ 'tribe-select2', 'vendor/tribe-selectWoo/dist/js/selectWoo.full.js', [ 'jquery' ] ], + [ 'tribe-select2-css', 'vendor/tribe-selectWoo/dist/css/selectWoo.css' ], + [ 'tribe-utils-camelcase', 'utils-camelcase.js', [ 'underscore' ] ], + [ 'tribe-moment', 'vendor/momentjs/moment.js' ], + [ 'tribe-tooltipster', 'vendor/tooltipster/tooltipster.bundle.js', [ 'jquery' ] ], + [ 'tribe-tooltipster-css', 'vendor/tooltipster/tooltipster.bundle.css' ], + [ 'datatables-css', 'datatables.css' ], + [ 'tribe-datatables', 'tribe-datatables.js', [ 'datatables' ] ], + [ 'tribe-bumpdown', 'bumpdown.js', [ 'jquery', 'underscore', 'hoverIntent' ] ], + [ 'tribe-bumpdown-css', 'bumpdown.css' ], + [ 'tribe-buttonset-style', 'buttonset.css' ], + [ 'tribe-dropdowns', 'dropdowns.js', [ 'jquery', 'underscore', 'tribe-select2', 'tribe-common' ] ], + [ 'tribe-jquery-timepicker', 'vendor/jquery-tribe-timepicker/jquery.timepicker.js', [ 'jquery' ] ], + [ 'tribe-jquery-timepicker-css', 'vendor/jquery-tribe-timepicker/jquery.timepicker.css' ], + [ 'tribe-timepicker', 'timepicker.js', [ 'jquery', 'tribe-jquery-timepicker' ] ], + [ 'tribe-attrchange', 'vendor/attrchange/js/attrchange.js' ], + ] + ); + + tribe_assets( + $this, + [ + [ 'tribe-common-skeleton-style', 'common-skeleton.css' ], + [ 'tribe-common-full-style', 'common-full.css', [ 'tribe-common-skeleton-style' ] ], + ], + null + ); + + // These ones will be enqueued on `admin_enqueue_scripts` if the conditional method on filter is met + tribe_assets( + $this, + [ + [ 'tribe-ui', 'tribe-ui.css' ], + [ 'tribe-buttonset', 'buttonset.js', [ 'jquery', 'underscore' ] ], + [ 'tribe-common-admin', 'tribe-common-admin.css', [ 'tribe-dependency-style', 'tribe-bumpdown-css', 'tribe-buttonset-style', 'tribe-select2-css' ] ], + [ 'tribe-validation', 'validation.js', [ 'jquery', 'underscore', 'tribe-common', 'tribe-utils-camelcase', 'tribe-tooltipster' ] ], + [ 'tribe-validation-style', 'validation.css', [ 'tribe-tooltipster-css' ] ], + [ 'tribe-dependency', 'dependency.js', [ 'jquery', 'underscore', 'tribe-common' ] ], + [ 'tribe-dependency-style', 'dependency.css', [ 'tribe-select2-css' ] ], + [ 'tribe-pue-notices', 'pue-notices.js', [ 'jquery' ] ], + [ 'tribe-datepicker', 'datepicker.css' ], + ], + 'admin_enqueue_scripts', + [ + 'conditionals' => [ $this, 'should_load_common_admin_css' ], + 'priority' => 5, + ] + ); + + tribe_asset( + $this, + 'tribe-common', + 'tribe-common.js', + [], + 'admin_enqueue_scripts', + [ + 'priority' => 0, + ] + ); + + tribe_asset( + $this, + 'tribe-admin-url-fragment-scroll', + 'admin/url-fragment-scroll.js', + [ 'tribe-common' ], + 'admin_enqueue_scripts', + [ + 'conditionals' => [ $this, 'should_load_common_admin_css' ], + 'priority' => 5, + ] + ); + + tribe( Tribe__Admin__Help_Page::class )->register_assets(); + } + + /** + * Load Common's text domain, then fire the hook for other plugins to do the same. + * + * Make sure this fires on 'init', per WordPress best practices. + * + * @since 4.12.0 + * + * @return bool + */ + public function hook_load_text_domain() { + $loaded = $this->load_text_domain( + 'tribe-common', + basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/' + ); + + /** + * After attempting (hopefully successfully) to load Common's text domain. + * + * Load other plugin text domains on this hook, but make sure they're setup on this hook prior to 'init'. + * + * @since 4.12.0 + * + * @param bool $loaded Whether or not Common's text domain was loaded. + * + * @return bool + */ + do_action( 'tribe_load_text_domains', $loaded ); + + return $loaded; + } + + /** + * Load All localization data create by `asset.data` + * + * @since 4.7 + * + * @return void + */ + public function load_localize_data() { + $datepicker_months = array_values( Tribe__Date_Utils::get_localized_months_full() ); + + tribe( 'asset.data' )->add( 'tribe_l10n_datatables', [ + 'aria' => [ + 'sort_ascending' => __( ': activate to sort column ascending', 'tribe-common' ), + 'sort_descending' => __( ': activate to sort column descending', 'tribe-common' ), + ], + 'length_menu' => __( 'Show _MENU_ entries', 'tribe-common' ), + 'empty_table' => __( 'No data available in table', 'tribe-common' ), + 'info' => __( 'Showing _START_ to _END_ of _TOTAL_ entries', 'tribe-common' ), + 'info_empty' => __( 'Showing 0 to 0 of 0 entries', 'tribe-common' ), + 'info_filtered' => __( '(filtered from _MAX_ total entries)', 'tribe-common' ), + 'zero_records' => __( 'No matching records found', 'tribe-common' ), + 'search' => __( 'Search:', 'tribe-common' ), + 'all_selected_text' => __( 'All items on this page were selected. ', 'tribe-common' ), + 'select_all_link' => __( 'Select all pages', 'tribe-common' ), + 'clear_selection' => __( 'Clear Selection.', 'tribe-common' ), + 'pagination' => [ + 'all' => __( 'All', 'tribe-common' ), + 'next' => __( 'Next', 'tribe-common' ), + 'previous' => __( 'Previous', 'tribe-common' ), + ], + 'select' => [ + 'rows' => [ + 0 => '', + '_' => __( ': Selected %d rows', 'tribe-common' ), + 1 => __( ': Selected 1 row', 'tribe-common' ), + ], + ], + 'datepicker' => [ + 'dayNames' => Tribe__Date_Utils::get_localized_weekdays_full(), + 'dayNamesShort' => Tribe__Date_Utils::get_localized_weekdays_short(), + 'dayNamesMin' => Tribe__Date_Utils::get_localized_weekdays_initial(), + 'monthNames' => $datepicker_months, + 'monthNamesShort' => $datepicker_months, // We deliberately use full month names here, + 'monthNamesMin' => array_values( Tribe__Date_Utils::get_localized_months_short() ), + 'nextText' => esc_html__( 'Next', 'the-events-calendar' ), + 'prevText' => esc_html__( 'Prev', 'the-events-calendar' ), + 'currentText' => esc_html__( 'Today', 'the-events-calendar' ), + 'closeText' => esc_html__( 'Done', 'the-events-calendar' ), + 'today' => esc_html__( 'Today', 'the-events-calendar' ), + 'clear' => esc_html__( 'Clear', 'the-events-calendar' ), + ], + ] ); + } + + /** + * Adds core hooks + */ + public function add_hooks() { + add_action( 'plugins_loaded', [ 'Tribe__App_Shop', 'instance' ] ); + add_action( 'plugins_loaded', [ $this, 'tribe_plugins_loaded' ], PHP_INT_MAX ); + + // Register for the assets to be available everywhere + add_action( 'tribe_common_loaded', [ $this, 'load_assets' ], 1 ); + add_action( 'init', [ $this, 'hook_load_text_domain' ] ); + add_action( 'init', [ $this, 'load_localize_data' ] ); + add_action( 'plugins_loaded', [ 'Tribe__Admin__Notices', 'instance' ], 1 ); + add_action( 'admin_enqueue_scripts', [ $this, 'store_admin_notices' ] ); + + add_filter( 'body_class', [ $this, 'add_js_class' ] ); + add_action( 'wp_footer', [ $this, 'toggle_js_class' ] ); + } + + /** + * Adds `tribe-no-js` class to all pages when common is active. + * + * @since 4.3.4 + * + * @param array|string $classes Previous classes on body. + * + * @return array All classes that will be printed on ``. + */ + public function add_js_class( $classes = [] ) { + if ( ! is_array( $classes ) ) { + $classes = explode( ' ', $classes ); + } + + $classes[] = 'tribe-no-js'; + + return array_filter( array_unique( $classes ) ); + } + + /** + * Removes `tribe-no-js` and replaces with `tribe-js` when the Javascript of the page is enabled. + * + * @since 4.3.4 + * + * @return void This method only prints HTML to the screen no return. + */ + public function toggle_js_class() { + ?> + + is_post_type_screen(); + + // Are we on the Plugins page? + $is_plugins = $helper->is_screen( 'plugins' ); + + // Are we on the Widgets page? + $is_widgets = $helper->is_screen( 'widgets' ); + + // Are we viewing a generic Tribe screen? + // Includes: Events > Settings, Events > Help, App Shop page, and more. + $is_tribe_screen = $helper->is_screen(); + + return $is_post_type || $is_plugins || $is_widgets || $is_tribe_screen; + } + + /** + * A Helper method to load text domain + * First it tries to load the wp-content/languages translation then if falls to the try to load $dir language files. + * + * @since 4.0.1 Introduced. + * @since 4.2 Included $domain and $dir params. + * + * @param string $domain The text domain that will be loaded. + * @param string|false $dir What directory should be used to try to load if the default doesn't work. + * + * @return bool If it was able to load the text domain. + */ + public function load_text_domain( $domain, $dir = false ) { + // Added safety just in case this runs twice... + if ( is_textdomain_loaded( $domain ) && ! $GLOBALS['l10n'][ $domain ] instanceof NOOP_Translations ) { + return true; + } + + $locale = get_locale(); + $plugin_rel_path = WP_LANG_DIR . '/plugins/'; + + /** + * Allows users to filter the file location for a given text domain.. + * Be careful when using this filter, it will apply across the whole plugin suite. + * + * @param string $plugin_rel_path The relative path for the language files. + * @param string $domain Which plugin domain we are trying to load. + * @param string $locale Which Language we will load. + * @param string|bool $dir If there was a custom directory passed on the method call. + */ + $plugin_rel_path = apply_filters( 'tribe_load_text_domain', $plugin_rel_path, $domain, $locale, $dir ); + + $loaded = load_plugin_textdomain( $domain, false, $plugin_rel_path ); + + if ( $dir !== false && ! $loaded ) { + return load_plugin_textdomain( $domain, false, $dir ); + } + + return $loaded; + } + + /** + * Returns the post types registered by Tribe plugins. + * + * @since 4.0.1 Introduced the method. + * + * @return array Slugs for all Post Types registered. + */ + public static function get_post_types() { + /** + * We default the post type array to empty in tribe-common. Plugins like TEC add to it. + * + * @since 4.0.1 + * + * @param array Slugs for all Post Types registered. + */ + return apply_filters( 'tribe_post_types', [] ); + } + + /** + * Insert an array after a specified key within another array. + * + * @param $key + * @param $source_array + * @param $insert_array + * + * @return array + */ + public static function array_insert_after_key( $key, $source_array, $insert_array ) { + if ( array_key_exists( $key, $source_array ) ) { + $position = array_search( $key, array_keys( $source_array ) ) + 1; + $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true ); + } else { + // If no key is found, then add it to the end of the array. + $source_array += $insert_array; + } + + return $source_array; + } + + /** + * Insert an array immediately before a specified key within another array. + * + * @param $key + * @param $source_array + * @param $insert_array + * + * @return array + */ + public static function array_insert_before_key( $key, $source_array, $insert_array ) { + if ( array_key_exists( $key, $source_array ) ) { + $position = array_search( $key, array_keys( $source_array ) ); + $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true ); + } else { + // If no key is found, then add it to the end of the array. + $source_array += $insert_array; + } + + return $source_array; + } + + /** + * Get the Post ID from a passed integer, a passed WP_Post object, or the current post. + * + * Helper function for getting Post ID. Accepts `null` or a Post ID. If attempting + * to detect $post object and it is not found, returns `false` to avoid a PHP Notice. + * + * @param null|int|WP_Post $candidate Post ID or object, `null` to get the ID of the global post object. + * + * @return int|false The ID of the passed or global post, `false` if the passes object is not a post or the global + * post is not set. + */ + public static function post_id_helper( $candidate = null ) { + $candidate_post = get_post( $candidate ); + + return $candidate_post instanceof WP_Post ? $candidate_post->ID : false; + } + + /** + * Adds a hook + * + */ + public function store_admin_notices( $page ) { + if ( 'plugins.php' !== $page ) { + return; + } + $notices = apply_filters( 'tribe_plugin_notices', [] ); + wp_localize_script( 'tribe-pue-notices', 'tribe_plugin_notices', $notices ); + } + + /** + * Runs tribe_plugins_loaded action, should be hooked to the end of plugins_loaded + */ + public function tribe_plugins_loaded() { + tribe( 'admin.notice.php.version' ); + tribe( 'cache' ); + tribe_singleton( 'feature-detection', 'Tribe__Feature_Detection' ); + tribe_register_provider( 'Tribe__Service_Providers__Processes' ); + + if ( ! defined( 'TRIBE_HIDE_MARKETING_NOTICES' ) ) { + tribe( 'admin.notice.marketing' ); + } + + tribe( \Tribe\Admin\Notice\WP_Version::class ); + + /** + * Runs after all plugins including Tribe ones have loaded + * + * @since 4.3 + */ + do_action( 'tribe_plugins_loaded' ); + } + + /** + * Registers the slug bound to the implementations in the container. + * + * @since 4.4 + * + * @return void Implementation of components loader doesn't return anything. + */ + public function bind_implementations() { + tribe_singleton( 'settings.manager', 'Tribe__Settings_Manager' ); + tribe_singleton( 'settings', 'Tribe__Settings', [ 'hook' ] ); + tribe_singleton( 'ajax.dropdown', 'Tribe__Ajax__Dropdown', [ 'hook' ] ); + tribe_singleton( 'assets', 'Tribe__Assets' ); + tribe_singleton( 'assets.pipeline', 'Tribe__Assets_Pipeline', [ 'hook' ] ); + tribe_singleton( 'asset.data', 'Tribe__Asset__Data', [ 'hook' ] ); + tribe_singleton( 'admin.helpers', 'Tribe__Admin__Helpers' ); + tribe_singleton( 'tracker', 'Tribe__Tracker', [ 'hook' ] ); + tribe_singleton( 'chunker', 'Tribe__Meta__Chunker', [ 'set_post_types', 'hook' ] ); + tribe_singleton( 'cache', 'Tribe__Cache', [ 'hook' ] ); + tribe_singleton( 'languages.locations', 'Tribe__Languages__Locations' ); + tribe_singleton( 'plugins.api', new Tribe__Plugins_API ); + tribe_singleton( 'logger', 'Tribe__Log' ); + tribe_singleton( 'cost-utils', [ 'Tribe__Cost_Utils', 'instance' ] ); + tribe_singleton( 'post-duplicate.strategy-factory', 'Tribe__Duplicate__Strategy_Factory' ); + tribe_singleton( 'post-duplicate', 'Tribe__Duplicate__Post' ); + tribe_singleton( 'context', 'Tribe__Context' ); + tribe_singleton( 'post-transient', 'Tribe__Post_Transient' ); + tribe_singleton( 'db', 'Tribe__Db' ); + tribe_singleton( 'db-lock', DB_Lock::class ); + tribe_singleton( 'freemius', 'Tribe__Freemius' ); + tribe_singleton( 'customizer', 'Tribe__Customizer' ); + + tribe_singleton( Tribe__Dependency::class, Tribe__Dependency::class ); + + tribe_singleton( 'callback', 'Tribe__Utils__Callback' ); + tribe_singleton( 'pue.notices', 'Tribe__PUE__Notices' ); + + tribe_singleton( Tribe__Admin__Help_Page::class, Tribe__Admin__Help_Page::class ); + + tribe_singleton( 'admin.notice.php.version', 'Tribe__Admin__Notice__Php_Version', [ 'hook' ] ); + tribe_singleton( 'admin.notice.marketing', 'Tribe__Admin__Notice__Marketing', [ 'hook' ] ); + tribe_singleton( \Tribe\Admin\Notice\WP_Version::class, \Tribe\Admin\Notice\WP_Version::class, [ 'hook' ] ); + + tribe_register_provider( Tribe__Editor__Provider::class ); + tribe_register_provider( Tribe__Service_Providers__Debug_Bar::class ); + tribe_register_provider( Tribe__Service_Providers__Promoter::class ); + tribe_register_provider( Tribe\Service_Providers\Tooltip::class ); + tribe_register_provider( Tribe\Service_Providers\Dialog::class ); + tribe_register_provider( Tribe\Service_Providers\PUE::class ); + tribe_register_provider( Tribe\Service_Providers\Shortcodes::class ); + tribe_register_provider( Tribe\Service_Providers\Body_Classes::class ); + tribe_register_provider( Tribe\Log\Service_Provider::class ); + tribe_register_provider( Tribe\Service_Providers\Crons::class ); + tribe_register_provider( Tribe\Service_Providers\Widgets::class ); + } + + /** + * Create the Promoter connector singleton early to allow hook into the filters early. + * + * Add a filter to determine_current_user during the setup of common library. + * + * @since 4.9.20 + * + * @return void Internal method without any return. + */ + public function promoter_connector() { + tribe_singleton( 'promoter.connector', 'Tribe__Promoter__Connector' ); + + add_filter( + 'determine_current_user', + tribe_callback( 'promoter.connector', 'authenticate_user_with_connector' ) + ); + } + + + /************************ + * * + * Deprecated Methods * + * * + ************************/ + // @codingStandardsIgnoreStart + + /** + * Helper function to indicate whether the current execution context is AJAX + * + * This method exists to allow us test code that behaves differently depending on the execution + * context. + * + * @since 4.0 + * + * @todo Add warning with '_deprecated_function' + * + * @param bool $doing_ajax An injectable status to override the `DOING_AJAX` check. + * + * @deprecated 4.7.12 + * + * @return boolean + */ + public function doing_ajax( $doing_ajax = null ) { + return tribe( 'context' )->doing_ajax( $doing_ajax ); + } + + /** + * Manages PUE license key notifications. + * + * It's important for the sanity of our users that only one instance of this object + * be created. However, multiple Tribe__Main objects can and will be instantiated, hence + * why for the time being we need to make this field static. + * + * @see https://central.tri.be/issues/65755 + * + * @deprecated 4.7.10 + * + * @return Tribe__PUE__Notices + */ + public function pue_notices() { + return tribe( 'pue.notices' ); + } + + /** + * + * @deprecated 4.7.10 + * + * @return Tribe__Log + */ + public function log() { + return tribe( 'logger' ); + } + // @codingStandardsIgnoreEnd +} diff --git a/tribe-common/src/Tribe/Meta/Chunker.php b/tribe-common/src/Tribe/Meta/Chunker.php new file mode 100644 index 0000000000..f24018d649 --- /dev/null +++ b/tribe-common/src/Tribe/Meta/Chunker.php @@ -0,0 +1,965 @@ +register_for_chunking( $post_id, 'my_meta_key' ); + * + * // ... some code later... + * + * // data will be transparently chunked if needed... + * update_meta( $post_id, 'my_meta_key', $some_looooooooooong_string ); + * + * // ...and glued back together when reading + * get_post_meta( $post_id, 'my_meta_key', true ); + * + * By default the Chunker supports the `post` post type only, filter the `tribe_meta_chunker_post_types` to add yours: + * + * add_filter( 'tribe_meta_chunker_post_types`, 'my_chunkable_post_types' ); + * function my_chunkable_post_types( $post_types ) { + * $post_types[] = 'book'; + * + * return $post_types; + * } + * + * or filter the `tribe_meta_chunker_post_types` filter. + */ +class Tribe__Meta__Chunker { + /** + * @var string The key used to cache the class results in the WordPress object cache. + */ + protected $cache_group = 'post_meta'; + + /** + * @var string + */ + protected $chunked_keys_option_name = '_tribe_chunker_chunked_keys'; + + /** + * @var array The cache that will store chunks to avoid middleware operations from fetching the database. + */ + protected $chunks_cache = null; + + /** + * @var array The cache that will store the IDs of the posts that have at least one meta key registered + * for chunking. + */ + protected $post_ids_cache = null; + + /** + * @var string The separator that's used to mark the start of each chunk. + */ + protected $chunk_separator = '{{{TCSEP}}}'; + + /** + * @var array The post types supported by the Chunker. + */ + protected $post_types = []; + + /** + * @var int The filter priority at which Chunker will operate on meta CRUD operations. + */ + protected $filter_priority = - 1; + + /** + * @var string The meta key prefix applied ot any Chunker related post meta. + */ + protected $meta_key_prefix = '_tribe_chunker_'; + + /** + * @var int The largest size allowed by the Chunker. + */ + protected $max_chunk_size; + + /** + * Hooks the chunker on metadata operations for each supported post types. + * + * When changing post types unhook and rehook it like: + * + * $chunker = tribe( 'chunker' ); + * $chunker->set_post_types( array_merge( $my_post_types, $chunker->get_post_types() ); + * $chunker->unhook(); + * $chunker->hook(); + */ + public function hook() { + if ( empty( $this->post_types ) ) { + return; + } + + add_filter( 'update_post_metadata', [ $this, 'filter_update_metadata' ], $this->filter_priority, 4 ); + add_filter( 'delete_post_metadata', [ $this, 'filter_delete_metadata' ], $this->filter_priority, 3 ); + add_filter( 'add_post_metadata', [ $this, 'filter_add_metadata' ], $this->filter_priority, 4 ); + add_filter( 'get_post_metadata', [ $this, 'filter_get_metadata' ], $this->filter_priority, 4 ); + add_action( 'deleted_post', [ $this, 'remove_post_entry' ] ); + } + + /** + * Primes the chunked cache. + * + * This will just fetch the keys for the supported post types, not the values. + * + * @param bool $force Whether the cache should be reprimed even if already primed. + */ + public function prime_chunks_cache( $force = false ) { + if ( false === $force && null !== $this->chunks_cache ) { + return; + } + + $this->chunks_cache = []; + $this->post_ids_cache = []; + + $chunked_keys = get_option( $this->chunked_keys_option_name ); + + if ( empty( $chunked_keys ) ) { + return; + } + + foreach ( $chunked_keys as $post_id => $keys ) { + if ( ! is_array( $keys ) || empty( $keys ) ) { + continue; + } + $this->post_ids_cache[] = $post_id; + foreach ( $keys as $key ) { + $this->chunks_cache[ $this->get_key( $post_id, $key ) ] = null; + } + } + } + + /** + * Gets the key used to identify a post ID and meta key in the chunks cache. + * + * @param int $post_id + * @param string $meta_key + * @return string + */ + public function get_key( $post_id, $meta_key ) { + return "{$post_id}::{$meta_key}"; + } + + /** + * Register a post ID and meta key to be chunked if needed. + * + * @param int $post_id + * @param string $meta_key + * + * @return bool `false` if the post type is not supported, `true` otherwise + */ + public function register_chunking_for( $post_id, $meta_key ) { + if ( ! $this->is_supported_post_type( $post_id ) ) { + return false; + } + + $this->tag_as_chunkable( $post_id, $meta_key ); + + return true; + } + + /** + * Whether a post type is supported or not. + * + * @param int $object_id + * + * @return bool + */ + protected function is_supported_post_type( $object_id ) { + $post = get_post( $object_id ); + if ( empty( $post ) || ! in_array( $post->post_type, $this->post_types ) ) { + return false; + } + + return true; + } + + /** + * Tags a post ID and meta key couple as "chunkable" if needed. + * + * @param $post_id + * @param $meta_key + */ + protected function tag_as_chunkable( $post_id, $meta_key ) { + $key = $this->get_key( $post_id, $meta_key ); + + $this->prime_chunks_cache(); + + if ( ! array_key_exists( $key, $this->chunks_cache ) ) { + $this->chunks_cache[ $key ] = null; + } + + $this->post_ids_cache[] = $post_id; + + $option = (array) get_option( $this->chunked_keys_option_name ); + + if ( ! isset( $option[ $post_id ] ) ) { + $option[ $post_id ] = [ $meta_key ]; + } else { + $option[ $post_id ][] = $meta_key; + } + + update_option( $this->chunked_keys_option_name, array_filter( $option ), true ); + } + + /** + * Returns the meta key used to indicate if a meta key for a post is marked as chunkable. + * + * @param string $meta_key + * + * @return string + */ + public function get_chunkable_meta_key( $meta_key ) { + return $this->meta_key_prefix . $meta_key; + } + + /** + * Filters the add operations. + * + * Due to how the system works no more than one chunked entry can be stored. + * + * @param mixed $check + * @param int $object_id + * @param string $meta_key + * @param string $meta_value + * + * @see add_metadata() + * + * @return bool + */ + public function filter_add_metadata( $check, $object_id, $meta_key, $meta_value ) { + return $this->filter_update_metadata( $check, $object_id, $meta_key, $meta_value ); + } + + /** + * Filters the updated operations. + * + * @param mixed $check + * @param int $object_id + * @param string $meta_key + * @param string $meta_value + * + * @see update_metadata() + * + * @return bool + */ + public function filter_update_metadata( $check, $object_id, $meta_key, $meta_value ) { + if ( ! $this->applies( $object_id, $meta_key ) ) { + return $check; + } + + /** + * Filters the chunked meta update operation. + * + * Returning a non null value here will make the function return that value immediately. + * + * @param mixed $updated + * @param int $object_id The post ID + * @param string $meta_key + * @param mixed $meta_value + * + * @since 4.5.6 + */ + $updated = apply_filters( 'tribe_meta_chunker_update_meta', null, $object_id, $meta_key, $meta_value ); + if ( null !== $updated ) { + return $updated; + } + + $this->delete_chunks( $object_id, $meta_key ); + $this->remove_checksum_for( $object_id, $meta_key ); + wp_cache_delete( $object_id, $this->cache_group ); + + if ( $this->should_be_chunked( $object_id, $meta_key, $meta_value ) ) { + $this->insert_chunks( $object_id, $meta_key ); + + return true; + } else { + $this->cache_delete( $object_id, $meta_key ); + $this->insert_meta( $object_id, $meta_key, $meta_value ); + + return true; + } + + return $check; + } + + /** + * Whether the chunker should operate on this post ID and meta key couple or not. + * + * @param int $object_id + * @param string $meta_key + * + * @return bool + */ + protected function applies( $object_id, $meta_key ) { + $applies = ! $this->is_chunker_logic_meta_key( $meta_key ) + && $this->is_supported_post_type( $object_id ) + && $this->is_chunkable( $object_id, $meta_key ); + + /** + * Filters whether the meta chunker will apply to a post ID and meta key or not. + * + * The `$meta_key` parameter might be empty. + * + * @param bool $applies + * @param int $object_id + * @param string $meta_key + * + * @since 4.5.6 + */ + return apply_filters( 'tribe_meta_chunker_applies', $applies, $object_id, $meta_key ); + } + + /** + * Whether the meta key is one used by the chunker to keep track of its operations or not. + * + * @param string $meta_key + * + * @return bool + */ + protected function is_chunker_logic_meta_key( $meta_key ) { + if ( ! is_string( $meta_key ) ) { + return false; + } + + return 0 === strpos( $meta_key, $this->meta_key_prefix ); + } + + /** + * Whether a post ID and meta key couple is registered as chunkable or not. + * + * If no meta key is passed then the function will check if there is at least + * one meta key registered for chunking for the specified post ID. + * + * @param int $post_id + * @param string $meta_key + * + * @return bool + */ + public function is_chunkable( $post_id, $meta_key = null ) { + $this->prime_chunks_cache(); + + return ! empty( $meta_key ) + ? array_key_exists( $this->get_key( $post_id, $meta_key ), $this->chunks_cache ) + : in_array( $post_id, $this->post_ids_cache ); + } + + /** + * Deletes all the chunks for a post ID and meta key couple. + * + * @param int $object_id + * @param string $meta_key + */ + protected function delete_chunks( $object_id, $meta_key ) { + /** @var wpdb $wpdb */ + global $wpdb; + $chunk_meta_key = $this->get_chunk_meta_key( $meta_key ); + $delete = "DELETE FROM {$wpdb->postmeta} WHERE (meta_key = %s OR meta_key = %s) AND post_id = %d"; + $wpdb->query( $wpdb->prepare( $delete, $chunk_meta_key, $meta_key, $object_id ) ); + } + + /** + * Returns the meta key used to indicate a chunk for a meta key. + * + * @param string $meta_key + * + * @return string + */ + public function get_chunk_meta_key( $meta_key ) { + return $this->get_chunkable_meta_key( $meta_key ) . '_chunk'; + } + + /** + * Removes the checksum used to verify the integrity of the chunked values. + * + * @param int $object_id + * @param string $meta_key + */ + protected function remove_checksum_for( $object_id, $meta_key ) { + /** @var wpdb $wpdb */ + global $wpdb; + $data = [ + 'post_id' => $object_id, + 'meta_key' => $this->get_checksum_key( $meta_key ), + ]; + $wpdb->delete( $wpdb->postmeta, $data ); + } + + /** + * Returns the meta_key used to store the chunked meta checksum for a specified meta key. + * + * @param string $meta_key + * + * @return string + */ + public function get_checksum_key( $meta_key ) { + return $this->meta_key_prefix . $meta_key . '_checksum'; + } + + /** + * Whether a value should be chunked or not. + * + * @param int $post_id + * @param string $meta_key + * @param mixed $meta_value + * + * @return bool + */ + public function should_be_chunked( $post_id, $meta_key, $meta_value ) { + $should_be_chunked = false; + + $max_allowed_packet = $this->get_max_chunk_size(); + $serialized = maybe_serialize( $meta_value ); + $byte_size = $this->get_byte_size( $serialized ); + + $this->prime_chunks_cache(); + + // we use .8 and not 1 to allow for MySQL instructions to use 20% of the string size + if ( $byte_size > .8 * $max_allowed_packet ) { + $chunk_size = ceil( $max_allowed_packet * 0.75 ); + $key = $this->get_key( $post_id, $meta_key ); + $this->chunks_cache[ $key ] = $this->prefix_chunks( $this->chunk( $serialized, $chunk_size ) ); + $should_be_chunked = true; + } + + return $should_be_chunked; + } + + /** + * Returns the max chunk size in bytes. + * + * @return array|int|null|object + */ + public function get_max_chunk_size() { + if ( ! empty( $this->max_chunk_size ) ) { + return $this->max_chunk_size; + } + + $max_size = tribe( 'db' )->get_max_allowed_packet_size(); + + /** + * Filters the max size of the of the chunks in bytes. + * + * @param int $max_size By default the `max_allowed_packet` from the database. + */ + $this->max_chunk_size = apply_filters( 'tribe_meta_chunker_max_size', $max_size ); + + return $max_size; + } + + /** + * Sets the max chunk size. + * + * @param int $max_chunk_size The max chunk size in bytes. + */ + public function set_max_chunk_size( $max_chunk_size ) { + $this->max_chunk_size = $max_chunk_size; + } + + /** + * Gets the size in bytes of something. + * + * @param mixed $data + * + * @return int + */ + public function get_byte_size( $data ) { + return strlen( utf8_decode( maybe_serialize( $data ) ) ); + } + + /** + * Prefixes each chunk with a sequence number. + * + * @param array $chunks + * + * @return array An array of chunks each prefixed with sequence number. + */ + protected function prefix_chunks( array $chunks ) { + $count = count( $chunks ); + $prefixed = []; + for ( $i = 0; $i < $count; $i ++ ) { + $prefixed[] = "{$i}{$this->chunk_separator}{$chunks[$i]}"; + } + + return $prefixed; + } + + /** + * Chunks a string. + * + * The chunks are not prefixed! + * + * @param string $serialized + * @param int $chunk_size + * + * @return array An array of unprefixed chunks. + */ + protected function chunk( $serialized, $chunk_size ) { + $sep = $this->chunk_separator; + $chunks = array_filter( explode( $sep, chunk_split( $serialized, $chunk_size, $sep ) ) ); + + return $chunks; + } + + /** + * Inserts the chunks for a post ID and meta key couple in the database. + * + * The chunks are read from the array cache. + * + * @param int $object_id + * @param string $meta_key + */ + protected function insert_chunks( $object_id, $meta_key ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $this->prime_chunks_cache(); + + $key = $this->get_key( $object_id, $meta_key ); + $chunks = $this->chunks_cache[ $key ]; + $chunk_meta_key = $this->get_chunk_meta_key( $meta_key ); + $this->insert_meta( $object_id, $meta_key, $chunks[0] ); + foreach ( $chunks as $chunk ) { + $wpdb->insert( $wpdb->postmeta, [ + 'post_id' => $object_id, + 'meta_key' => $chunk_meta_key, + 'meta_value' => $chunk, + ] ); + } + + $glued = $this->glue_chunks( $this->get_chunks_for( $object_id, $meta_key ) ); + $checksum_key = $this->get_checksum_key( $meta_key ); + $wpdb->delete( $wpdb->postmeta, [ 'post_id' => $object_id, 'meta_key' => $checksum_key ] ); + $wpdb->insert( $wpdb->postmeta, [ + 'post_id' => $object_id, + 'meta_key' => $checksum_key, + 'meta_value' => md5( $glued ), + ] ); + } + + /** + * Inserts a meta value in the database. + * + * Convenience method to avoid infinite loop in hooks. + * + * @param int $object_id + * @param string $meta_key + * @param mixed $meta_value + */ + protected function insert_meta( $object_id, $meta_key, $meta_value ) { + /** @var wpdb $wpdb */ + global $wpdb; + $data = [ + 'post_id' => $object_id, + 'meta_key' => $meta_key, + 'meta_value' => maybe_serialize( $meta_value ), + ]; + $wpdb->insert( $wpdb->postmeta, $data ); + } + + /** + * Glues the provided chunks. + * + * This method is sequence aware and should be used with what the `get_chunks_for` method returns. + * + * @param array $chunks + * + * @return string + * + * @see Tribe__Meta__Chunker::get_chunks_for() + */ + public function glue_chunks( array $chunks ) { + $ordered_chunks = []; + foreach ( $chunks as $chunk ) { + preg_match( '/(\\d+)' . preg_quote( $this->chunk_separator ) . '(.*)/', $chunk, $matches ); + $ordered_chunks[ $matches[1] ] = $matches[2]; + } + ksort( $ordered_chunks ); + + return implode( '', array_values( $ordered_chunks ) ); + } + + /** + * Returns the chunks stored in the database for a post ID and meta key couple. + * + * The chunks are returned as they are with prefix. + * + * @param int $object_id + * @param string $meta_key + * + * @return array|mixed + */ + public function get_chunks_for( $object_id, $meta_key ) { + $key = $this->get_key( $object_id, $meta_key ); + + $this->prime_chunks_cache(); + + if ( ! empty( $this->chunks_cache[ $key ] ) ) { + return $this->chunks_cache[ $key ]; + } + + /** @var wpdb $wpdb */ + global $wpdb; + + $chunk_meta_key = $this->get_chunk_meta_key( $meta_key ); + + $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM {$wpdb->postmeta} + WHERE post_id = %d + AND meta_key = %s", + $object_id, $chunk_meta_key + ) ); + + $meta_values = []; + foreach ( $meta_ids as $meta_id ) { + $query = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_id = %d", $meta_id ); + $meta_values[] = $wpdb->get_var( $query ); + } + + if ( ! empty( $meta_values ) ) { + $this->chunks_cache[ $this->get_key( $object_id, $meta_key ) ] = $meta_values; + } else { + $this->chunks_cache[ $this->get_key( $object_id, $meta_key ) ] = null; + } + + return $meta_values; + } + + /** + * Resets a post ID and meta key couple cache. + * + * @param int $object_id + * @param string $meta_key + */ + protected function cache_delete( $object_id, $meta_key ) { + $key = $this->get_key( $object_id, $meta_key ); + + $this->prime_chunks_cache(); + + if ( isset( $this->chunks_cache[ $key ] ) ) { + $this->chunks_cache[ $key ] = null; + } + } + + /** + * Filters the delete operations. + * + * @param mixed $check + * @param int $object_id + * @param string $meta_key + * + * @return bool + * + * @see delete_metadata() + */ + public function filter_delete_metadata( $check, $object_id, $meta_key ) { + if ( ! $this->applies( $object_id, $meta_key ) ) { + return $check; + } + + /** + * Filters the value returned when deleting a specific meta for a post. + * + * Returning a non null value here will make the function return that value immediately. + * + * @param mixed $deleted + * @param int $object_id The post ID + * @param string $meta_key The requested meta key + * + * @since 4.5.6 + */ + $deleted = apply_filters( 'tribe_meta_chunker_delete_meta', null, $object_id, $meta_key ); + if ( null !== $deleted ) { + return $deleted; + } + + $has_chunked_meta = $this->is_chunked( $object_id, $meta_key ); + if ( ! $has_chunked_meta ) { + return $check; + } + $this->cache_delete( $object_id, $meta_key ); + $this->delete_chunks( $object_id, $meta_key ); + wp_cache_delete( $object_id, $this->cache_group ); + + return true; + } + + /** + * Whether a post ID and meta key couple has chunked meta or not. + * + * @param int $object_id + * @param string $meta_key + * @param bool $check_db Do verify the chunking state on the database. + * + * @return mixed + */ + public function is_chunked( $object_id, $meta_key, $check_db = false ) { + $key = $this->get_key( $object_id, $meta_key ); + + $this->prime_chunks_cache(); + + $chunked_in_cache = array_key_exists( $key, $this->chunks_cache ) && is_array( $this->chunks_cache[ $key ] ); + + return $chunked_in_cache; + } + + /** + * Returns the checksum for the stored meta key to spot meta value corruption malforming. + * + * @param int $object_id + * @param string $meta_key + * + * @return string + */ + public function get_checksum_for( $object_id, $meta_key ) { + /** @var wpdb $wpdb */ + global $wpdb; + + $query = "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = %s"; + $checksum = $wpdb->get_var( $wpdb->prepare( $query, $object_id, $this->get_checksum_key( $meta_key ) ) ); + + return ! empty( $checksum ) ? $checksum : ''; + } + + /** + * Handles the object destruction cycle to leave no traces behind. + */ + public function __destruct() { + $this->unhook(); + } + + /** + * Unhooks the Chunker from the metadata operations. + */ + public function unhook() { + remove_filter( 'update_post_metadata', [ $this, 'filter_update_metadata' ], $this->filter_priority ); + remove_filter( 'delete_post_metadata', [ $this, 'filter_delete_metadata' ], $this->filter_priority ); + remove_filter( 'add_post_metadata', [ $this, 'filter_add_metadata' ], $this->filter_priority ); + remove_filter( 'get_post_metadata', [ $this, 'filter_get_metadata' ], $this->filter_priority ); + remove_action( 'deleted_post', [ $this, 'remove_post_entry' ] ); + } + + /** + * Filters the get operations. + * + * @param mixed $check + * @param int $object_id + * @param string $meta_key + * @param bool $single + * + * @return array|mixed + * + * @see get_metadata() + */ + public function filter_get_metadata( $check, $object_id, $meta_key, $single ) { + if ( ! $this->applies( $object_id, $meta_key ) ) { + return $check; + } + + $all_meta = wp_cache_get( $object_id, $this->cache_group ); + + if ( ! $all_meta ) { + $all_meta = $this->get_all_meta_for( $object_id ); + wp_cache_set( $object_id, $all_meta, $this->cache_group ); + } + + // getting all the meta + if ( empty( $meta_key ) ) { + return $all_meta; + } + + // why not take $single into account? See condition check on the filter to understand. + $meta_value = isset( $all_meta[ $meta_key ] ) + ? array_map( 'maybe_unserialize', $all_meta[ $meta_key ] ) + : ''; + + /** + * Filters the value returned when getting a specific meta for a post. + * + * Returning a non null value here will make the function return that value immediately. + * + * @param mixed $meta_value + * @param int $object_id The post ID + * @param string $meta_key The requested meta key + * + * @since 4.5.6 + */ + $meta_value = apply_filters( 'tribe_meta_chunker_get_meta', $meta_value, $object_id, $meta_key ); + + if ( $single ) { + return (array) $meta_value; + } else { + return ! empty( $meta_value ) ? $meta_value : ''; + } + } + + /** + * Returns all the meta for a post ID. + * + * The meta includes the chunked one but not the chunker logic meta keys. + * The return format is the same used by the `get_post_meta( $post_id )` function. + * + * @param int $object_id + * + * @return array An array containing all meta including the chunked one. + * + * @see get_post_meta() with empty `$meta_key` argument. + */ + public function get_all_meta_for( $object_id ) { + $all_meta = $this->get_all_meta( $object_id ); + + if ( empty( $all_meta ) ) { + return []; + } + + $grouped = []; + foreach ( $all_meta as $entry ) { + if ( ! isset( $grouped[ $entry['meta_key'] ] ) ) { + $grouped[ $entry['meta_key'] ] = [ $entry['meta_value'] ]; + } else { + $grouped[ $entry['meta_key'] ][] = $entry['meta_value']; + } + } + + $chunker_meta_keys = array_filter( array_keys( $grouped ), [ $this, 'is_chunker_logic_meta_key' ] ); + + if ( empty( $chunker_meta_keys ) ) { + return $grouped; + } + + $checksum_keys = array_filter( $chunker_meta_keys, [ $this, 'is_chunker_checksum_key' ] ); + + if ( empty( $checksum_keys ) ) { + return $grouped; + } + + $chunker_meta = array_intersect_key( $grouped, array_combine( $chunker_meta_keys, $chunker_meta_keys ) ); + $normal_meta = array_diff_key( $grouped, array_combine( $chunker_meta_keys, $chunker_meta_keys ) ); + foreach ( $checksum_keys as $checksum_key ) { + $normal_meta_key = str_replace( [ $this->meta_key_prefix, '_checksum' ], '', $checksum_key ); + $chunk_meta_key = $this->get_chunk_meta_key( $normal_meta_key ); + + if ( empty( $chunker_meta[ $chunk_meta_key ] ) ) { + continue; + } + + $normal_meta[ $normal_meta_key ] = [ $this->glue_chunks( $chunker_meta[ $chunk_meta_key ] ) ]; + } + + return $normal_meta; + } + + /** + * Fetches all the meta for a post. + * + * @param int $object_id + * + * @return array|null|object + */ + protected function get_all_meta( $object_id ) { + /** + * Filters the value returned when getting all the meta for a post. + * + * Returning a non null value here will make the function return that value immediately. + * + * @param mixed $all_meta + * @param int $object_id The post ID + * + * @since 4.5.6 + */ + $all_meta = apply_filters( 'tribe_meta_chunker_get_all_meta', null, $object_id ); + if ( null !== $all_meta ) { + return $all_meta; + } + + /** @var wpdb $wpdb */ + global $wpdb; + $query = $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $object_id ); + $results = $wpdb->get_results( $query, ARRAY_A ); + + return ! empty( $results ) && is_array( $results ) ? $results : []; + } + + /** + * Returns the post types supported by the chunker. + * + * @return array + */ + public function get_post_types() { + return $this->post_types; + } + + /** + * Sets the post types the Chunker should support. + * + * @param array $post_types + */ + public function set_post_types( array $post_types = null ) { + if ( null === $post_types ) { + /** + * Filters the chunk-able post types. + * + * @param array $post_types + */ + $this->post_types = apply_filters( 'tribe_meta_chunker_post_types', $this->post_types ); + + return; + } + + $this->post_types = $post_types; + } + + /** + * Returns the name of the option that stores the keys registered for chunking for each post. + * + * @return string + */ + public function get_key_option_name() { + return $this->chunked_keys_option_name; + } + + /** + * Returns the cache group used by the meta chunker. + * + * @return string + */ + public function get_cache_group() { + return $this->cache_group; + } + + /** + * Asserts that a meta key is not a chunk meta key. + * + * @param string $meta_key + * + * @return bool + */ + protected function is_chunker_checksum_key( $meta_key ) { + return preg_match( "/^{$this->meta_key_prefix}.*_checksum$/", $meta_key ); + } + + /** + * Removes the entries associated with a deleted post from the cache and the database option. + * + * @param int $post_id A post ID + */ + public function remove_post_entry( $post_id ) { + $this->prime_chunks_cache(); + + foreach ( $this->chunks_cache as $key => $value ) { + if ( 0 === strpos( $key, (string) $post_id ) ) { + unset( $this->chunks_cache[ $key ] ); + } + } + + if ( ! empty( $this->chunks_cache ) ) { + update_option( $this->chunked_keys_option_name, $this->chunks_cache ); + } else { + delete_option( $this->chunked_keys_option_name ); + } + } +} diff --git a/tribe-common/src/Tribe/Models/Post_Types/Base.php b/tribe-common/src/Tribe/Models/Post_Types/Base.php new file mode 100644 index 0000000000..176e3f22c5 --- /dev/null +++ b/tribe-common/src/Tribe/Models/Post_Types/Base.php @@ -0,0 +1,206 @@ +post = $post; + + return $instance; + } + + /** + * Returns the slug that will be prefixed to the cache key for the model. + * + * @since 4.9.18 + * + * @return string The slug that will be prefixed to the cache key for the model. + */ + abstract protected function get_cache_slug(); + + /** + * Returns the cached model properties for the specified filter, if any. + * + * @since 4.9.18 + * + * @param string $filter Type of filter to apply, used here as the stored post values might change. + * + * @return array|false An array of model properties, or `false` if not found. + */ + protected function get_cached_properties( $filter ) { + $cache_slug = $this->get_cache_slug(); + + if ( empty( $cache_slug ) ) { + return false; + } + + // Cache by post ID and filter. + $cache_key = $cache_slug . '_' . $this->post->ID . '_' . $filter; + + return ( new Cache() )->get( $cache_key, Cache_Listener::TRIGGER_SAVE_POST ); + } + + /** + * Builds and returns the properties for the model. + * + * In this method child classes should also implement any caching trigger mechanism, if any. + * + * @since 4.9.18 + * + * @param string $filter The type of filter to build the properties for. + * + * @return array An array of built properties. + */ + abstract protected function build_properties( $filter ); + + /** + * Returns an array of the model properties. + * + * @since 4.9.18 + * + * @param string $filter The type of filter to get the properties for. + * + * @return array The model properties. This value might be cached. + */ + protected function get_properties( $filter ) { + $cached = $this->get_cached_properties( $filter); + + if ( false !== $cached ) { + return $cached; + } + + $props = $this->build_properties( $filter ); + + $cache_slug = $this->get_cache_slug(); + + /** + * Filters the array of properties that will be used to decorate the post object handled by the class. + * + * @since 4.9.18 + * + * @param array $props An associative array of all the properties that will be set on the "decorated" post + * object. + * @param \WP_Post $post The post object handled by the class. + */ + $props = apply_filters( "tribe_post_type_{$cache_slug}_properties", $props, $this->post ); + + return $props; + } + + /** + * Returns the WP_Post version of this model. + * + * @since 4.9.18 + * + * @param string $output The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to a WP_Post + * object,an associative array, or a numeric array, respectively. + * @param string $filter Type of filter to apply. Accepts 'raw', 'edit', 'db', or 'display' and other formats + * supported by the specific type implementation. + * + * @return \WP_Post|array|null The post object version of this post type model or `null` if the post is not valid. + */ + public function to_post( $output = OBJECT, $filter = 'raw' ) { + $properties = $this->get_properties( $filter ); + + // Clone the post to avoid side effects. + $post = clone $this->post; + + // And decorate the clone with the properties. + foreach ( $properties as $key => $value ) { + $post->{$key} = $value; + } + + switch ( $output ) { + case ARRAY_A: + return (array) $post; + case ARRAY_N: + return array_values( (array) $post ); + case OBJECT: + default; + return $post; + } + } + + /** + * Returns the closure that should be used to cache the post type model when, and if, caching it is required. + * + * @since 4.9.18 + * + * @param string $filter The kind of filter applied to the model. + * + * @return callable The closure, or callable, that should be used to cache this model when, and if, required. + */ + protected function get_caching_callback( $filter ) { + $cache_slug = $this->get_cache_slug(); + + if ( empty( $cache_slug ) ) { + return '__return_true'; + } + + $callback = null; + + if ( wp_using_ext_object_cache() ) { + /* + * If any real caching is in place , then define a function to cache this event when, and if, one of the + * lazy properties is loaded. + * Cache by post ID and filter. + */ + $cache_key = $cache_slug . '_' . $this->post->ID . '_' . $filter; + $cache = new Cache(); + $callback = function () use ( $cache, $cache_key, $filter ) { + $properties = $this->get_properties( $filter ); + + /* + * Cache without expiration, but only until a post of the types managed by The Events Calendar is + * updated or created. + */ + $cache->set( $cache_key, $properties, 0, Cache_Listener::TRIGGER_SAVE_POST ); + }; + } + + return $callback; + } +} diff --git a/tribe-common/src/Tribe/Models/Post_Types/Nothing.php b/tribe-common/src/Tribe/Models/Post_Types/Nothing.php new file mode 100644 index 0000000000..90e24a44eb --- /dev/null +++ b/tribe-common/src/Tribe/Models/Post_Types/Nothing.php @@ -0,0 +1,44 @@ +notices[ $key ] = $notice; + + return true; + } + + /** + * Check to see if an admin notice exists + * + * @param string $key + * + * @return bool + */ + public static function is_notice( $key ) { + return ! empty( self::instance()->notices[ $key ] ) ? true : false; + } + + /** + * Remove an admin notice + * + * @param string $key + * + * @return bool + */ + public static function remove_notice( $key ) { + if ( self::is_notice( $key ) ) { + unset( self::instance()->notices[ $key ] ); + + return true; + } else { + return false; + } + } + + /** + * Get the admin notices + * + * @return array + */ + public static function get() { + return self::instance()->notices; + } + + /** + * Static Singleton Factory Method + * + * @return Tribe__Notices + */ + public static function instance() { + static $instance; + + if ( ! $instance ) { + $class_name = __CLASS__; + $instance = new $class_name; + } + + return $instance; + } +} diff --git a/tribe-common/src/Tribe/PUE/Checker.php b/tribe-common/src/Tribe/PUE/Checker.php new file mode 100755 index 0000000000..a5ae6e6e50 --- /dev/null +++ b/tribe-common/src/Tribe/PUE/Checker.php @@ -0,0 +1,1774 @@ +set_slug( $slug ); + $this->set_plugin_file( $plugin_file ); + $this->set_options( $options ); + $this->hooks(); + } + + /** + * Install the hooks required to run periodic update checks and inject update info + * into WP data structures. + * Also other hooks related to the automatic updates (such as checking agains API and what not (@from Darren) + */ + public function hooks() { + // Override requests for plugin information + add_filter( 'plugins_api', [ $this, 'inject_info' ], 10, 3 ); + + // Check for updates when the WP updates are checked and inject our update if needed. + // Only add filter if the TRIBE_DISABLE_PUE constant is not set as true and where + // the context is not 'service' + if ( ( ! defined( 'TRIBE_DISABLE_PUE' ) || true !== TRIBE_DISABLE_PUE ) && 'service' !== $this->context ) { + add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'check_for_updates' ] ); + } + + add_filter( 'tribe_licensable_addons', [ $this, 'build_addon_list' ] ); + add_action( 'tribe_license_fields', [ $this, 'do_license_key_fields' ] ); + add_action( 'tribe_settings_after_content_tab_licenses', [ $this, 'do_license_key_javascript' ] ); + add_action( 'tribe_settings_success_message', [ $this, 'do_license_key_success_message' ], 10, 2 ); + add_action( 'load-plugins.php', [ $this, 'remove_default_inline_update_msg' ], 50 ); + + // Key validation + add_filter( 'tribe_settings_save_field_value', [ $this, 'check_for_api_key_error' ], 10, 3 ); + add_action( 'wp_ajax_pue-validate-key_' . $this->get_slug(), [ $this, 'ajax_validate_key' ] ); + add_filter( 'tribe-pue-install-keys', [ $this, 'return_install_key' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'maybe_display_json_error_on_plugins_page' ], 1 ); + add_action( 'admin_init', [ $this, 'general_notifications' ] ); + + // Package name + add_filter( 'upgrader_pre_download', [ Tribe__PUE__Package_Handler::instance(), 'filter_upgrader_pre_download' ], 5, 3 ); + } + + /********************** Getter / Setter Functions **********************/ + + /** + * Get the slug + * + * @return string + */ + public function get_slug() { + return apply_filters( 'pue_get_slug', $this->slug ); + } + + /** + * Set the slug + * + * @param string $slug + */ + private function set_slug( $slug = '' ) { + $this->slug = $slug; + $clean_slug = str_replace( '-', '_', $this->slug ); + $this->dismiss_upgrade = 'pu_dismissed_upgrade_' . $clean_slug; + $this->pue_install_key = 'pue_install_key_' . $clean_slug; + } + + /** + * Get the PUE update API endpoint url + * + * @return string + */ + public function get_pue_update_url() { + $pue_update_url = 'https://pue.theeventscalendar.com'; + + if ( defined( 'PUE_UPDATE_URL' ) ) { + $pue_update_url = PUE_UPDATE_URL; + } + + $pue_update_url = apply_filters( 'pue_get_update_url', $pue_update_url, $this->get_slug() ); + + $pue_update_url = untrailingslashit( $pue_update_url ); + + return $pue_update_url; + } + + /** + * Get the plugin file path + * + * @return string + */ + public function get_plugin_file() { + return apply_filters( 'pue_get_plugin_file', $this->plugin_file, $this->get_slug() ); + } + + /** + * Set the plugin file path + * + * @param string $plugin_file + */ + private function set_plugin_file( $plugin_file = '' ) { + + if ( ! empty( $plugin_file ) ) { + $this->plugin_file = $plugin_file; + + return; + } + + $slug = $this->get_slug(); + if ( ! empty( $slug ) ) { + $this->plugin_file = $slug . '/' . $slug . '.php'; + } + } + + /** + * Set the plugin name + * + * @param string $plugin_name + */ + private function set_plugin_name( $plugin_name = '' ) { + if ( ! empty( $plugin_name ) ) { + $this->plugin_name = $plugin_name; + } else { + //get name from plugin file itself + if ( ! function_exists( 'get_plugins' ) ) { + require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); + } + + // Prevents get_plugins from throwing a weird notice + if ( ! file_exists( WP_PLUGIN_DIR . '/' . $this->get_plugin_file() ) ) { + return; + } + + $plugin_details = explode( '/', $this->get_plugin_file() ); + $plugin_folder = get_plugins( '/' . $plugin_details[0] ); + $this->plugin_name = isset( $plugin_details[1] ) && isset( $plugin_folder[ $plugin_details[1] ] ) ? $plugin_folder[ $plugin_details[1] ]['Name'] : null; + } + } + + /** + * Get the plugin name + * + * @return string + */ + public function get_plugin_name() { + if ( empty( $this->plugin_name ) ) { + $this->set_plugin_name(); + } + + return apply_filters( 'pue_get_plugin_name', $this->plugin_name, $this->get_slug() ); + } + + /** + * Set all the PUE instantiation options + * + * @param array $options + */ + private function set_options( $options = [] ) { + + $options = wp_parse_args( + $options, [ + 'pue_option_name' => 'external_updates-' . $this->get_slug(), + 'apikey' => '', + 'check_period' => 12, + 'context' => 'component', + 'plugin_name' => '', + ] + ); + + $this->pue_option_name = $options['pue_option_name']; + $this->check_period = (int) $options['check_period']; + $this->context = $options['context']; + $this->plugin_name = $options['plugin_name']; + + } + + /** + * Set all the download query array + * + * @param array $download_query + */ + private function set_download_query( $download_query = [] ) { + + if ( ! empty( $download_query ) ) { + $this->download_query = $download_query; + + return; + } + + // plugin slug + $this->download_query['plugin'] = sanitize_text_field( $this->get_slug() ); + + // include current version + $this->download_query['installed_version'] = sanitize_text_field( $this->get_installed_version() ); + + $this->download_query['domain'] = sanitize_text_field( $this->get_domain() ); + + // get general stats + $stats = $this->get_stats(); + + $this->download_query['multisite'] = $stats['network']['multisite']; + $this->download_query['network_activated'] = $stats['network']['network_activated']; + $this->download_query['active_sites'] = $stats['network']['active_sites']; + $this->download_query['wp_version'] = $stats['versions']['wp']; + + // the following is for install key inclusion (will apply later with PUE addons.) + $this->download_query['key'] = sanitize_text_field( $this->get_key() ); + $this->download_query['dk'] = sanitize_text_field( $this->get_key( 'default' ) ); + $this->download_query['o'] = sanitize_text_field( $this->get_key( 'any', 'origin' ) ); + + } + + /** + * Get the download_query args + * + * @return array + */ + public function get_download_query() { + if ( empty( $this->download_query ) ) { + $this->set_download_query(); + } + + return apply_filters( 'pue_get_download_query', $this->download_query, $this->get_slug() ); + } + + /** + * Set all the validate query array + * + * @param array $validate_query + */ + private function set_validate_query( $validate_query = [] ) { + + if ( ! empty( $validate_query ) ) { + $this->validate_query = $validate_query; + + return; + } + + // the following is for install key inclusion (will apply later with PUE addons.) + $this->validate_query['key'] = sanitize_text_field( $this->get_key() ); + + // include default key + $this->validate_query['default_key'] = sanitize_text_field( $this->get_key( 'default' ) ); + + // include license origin + $this->validate_query['license_origin'] = sanitize_text_field( $this->get_key( 'any', 'origin' ) ); + + // plugin slug + $this->validate_query['plugin'] = sanitize_text_field( $this->get_slug() ); + + // include current version + $this->validate_query['version'] = sanitize_text_field( $this->get_installed_version() ); + + // include current domain + $this->validate_query['domain'] = sanitize_text_field( $this->get_domain() ); + + // include plugin stats + $this->validate_query['stats'] = $this->get_stats(); + + } + + /** + * Get the validate_query args + * + * @return array + */ + public function get_validate_query() { + if ( empty( $this->validate_query ) ) { + $this->set_validate_query(); + } + + return apply_filters( 'pue_get_validate_query', $this->validate_query, $this->get_slug() ); + } + + /** + * Get current domain + * + * @return string + */ + public function get_domain() { + + $domain = self::$domain; + + if ( empty( $domain ) ) { + if ( isset( $_SERVER['SERVER_NAME'] ) ) { + $domain = $_SERVER['SERVER_NAME']; + } + + if ( is_multisite() ) { + // For multisite, return the network-level siteurl + $domain = $this->get_network_domain(); + } + + self::$domain = $domain; + } + + return $domain; + + } + + + /********************** General Functions **********************/ + + /** + * Compile a list of addons + * + * @param array $addons list of addons + * + * @return array list of addons + */ + public function build_addon_list( $addons = [] ) { + $addons[] = $this->get_plugin_name(); + + return $addons; + } + + /** + * Inserts license key fields on license key page + * + * @param array $fields List of fields + * + * @return array Modified list of fields. + */ + public function do_license_key_fields( $fields ) { + // common fields whether licenses should be hidden or not + $to_insert = [ + $this->pue_install_key . '-heading' => [ + 'type' => 'heading', + 'label' => $this->get_plugin_name(), + ], + ]; + + $no_license_tooltip = esc_html__( 'A valid license key is required for support and updates', 'tribe-common' ); + if ( 'event-aggregator' === $this->get_slug() ) { + $no_license_tooltip = sprintf( + esc_html__( '%1$sBuy a license%2$s for the Event Aggregator service to access additional import features.', 'tribe-common' ), + '
          ', + '' + ); + } + + // we want to inject the following license settings at the end of the licenses tab + if ( $this->should_show_network_editable_license() ) { + $to_insert[ $this->pue_install_key ] = [ + 'type' => 'license_key', + 'size' => 'large', + 'validation_type' => 'license_key', + 'label' => sprintf( esc_attr__( 'License Key', 'tribe-common' ) ), + 'default' => $this->get_key( 'default' ), + 'tooltip' => $no_license_tooltip, + 'parent_option' => false, + 'network_option' => true, + ]; + } elseif ( $this->should_show_subsite_editable_license() ) { + $to_insert[ $this->pue_install_key ] = [ + 'type' => 'license_key', + 'size' => 'large', + 'validation_type' => 'license_key', + 'label' => sprintf( esc_attr__( 'License Key', 'tribe-common' ) ), + 'default' => $this->get_key( 'default' ), + 'tooltip' => $no_license_tooltip, + 'parent_option' => false, + 'network_option' => false, + ]; + } elseif ( $this->should_show_overrideable_license() ) { + $to_insert[ $this->pue_install_key . '-state' ] = [ + 'type' => 'html', + 'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ), + 'label_attributes' => [ 'style' => 'width:auto;' ], + 'html' => sprintf( '

          %s

          ', $this->get_network_license_state_string() ), + ]; + + $override_id = $this->pue_install_key . '-override'; + + $to_insert[ $override_id ] = [ + 'type' => 'checkbox_bool', + 'label' => esc_html__( 'Override network license key', 'tribe-common' ), + 'tooltip' => esc_html__( 'Check this box if you wish to override the network license key with your own', 'tribe-common' ), + 'default' => false, + 'validation_type' => 'boolean', + 'parent_option' => false, + 'attributes' => [ 'id' => $override_id . '-field' ], + ]; + + $to_insert[ $this->pue_install_key ] = [ + 'type' => 'license_key', + 'size' => 'large', + 'validation_type' => 'license_key', + 'label' => sprintf( esc_attr__( 'Site License Key', 'tribe-common' ) ), + 'tooltip' => $no_license_tooltip, + 'parent_option' => false, + 'network_option' => false, + 'class' => 'tribe-dependent', + 'fieldset_attributes' => [ + 'data-depends' => '#' . $override_id . '-field', + 'data-condition-checked' => true, + ], + ]; + } else { + $to_insert[ $this->pue_install_key . '-state' ] = [ + 'type' => 'html', + 'label' => sprintf( esc_attr__( 'License Key Status:', 'tribe-common' ) ), + 'label_attributes' => [ 'style' => 'width:auto;' ], + 'html' => sprintf( '

          %s

          ', $this->get_network_license_state_string() ), + ]; + } + + $fields = self::array_insert_after_key( 'tribe-form-content-start', $fields, $to_insert ); + + return $fields; + } + + /** + * Inserts the javascript that makes the ajax checking + * work on the license key page + * + */ + public function do_license_key_javascript() { + ?> + +

          ' . esc_html__( 'License key(s) updated.', 'tribe-common' ) . '

          '; + + } + + /** + * Build stats for endpoints + * + * @return array + */ + public function build_stats() { + + global $wpdb; + + $stats = [ + 'versions' => [ + 'wp' => sanitize_text_field( $GLOBALS['wp_version'] ), + ], + 'network' => [ + 'multisite' => 0, + 'network_activated' => 0, + 'active_sites' => 1, + ], + ]; + + if ( is_multisite() ) { + $sql_count = " + SELECT COUNT( `blog_id` ) + FROM `{$wpdb->blogs}` + WHERE + `public` = '1' + AND `archived` = '0' + AND `spam` = '0' + AND `deleted` = '0' + "; + + $stats['network']['multisite'] = 1; + $stats['network']['network_activated'] = (int) $this->is_plugin_active_for_network(); + $stats['network']['active_sites'] = (int) $wpdb->get_var( $sql_count ); + } + + self::$stats = $stats; + + return $stats; + + } + + /** + * Build full stats for endpoints + * + * @param array $stats Initial stats + * + * @return array + */ + public function build_full_stats( $stats ) { + + global $wpdb; + + $theme = wp_get_theme(); + + $current_offset = (int) get_option( 'gmt_offset', 0 ); + $tzstring = get_option( 'timezone_string' ); + + // Remove old Etc mappings. Fallback to gmt_offset. + if ( false !== strpos( $tzstring, 'Etc/GMT' ) ) { + $timezone = ''; + } + + // Create a UTC+- zone if no timezone string exists + if ( empty( $tzstring ) ) { + if ( 0 === $current_offset ) { + $timezone = 'UTC+0'; + } elseif ( $current_offset < 0 ) { + $timezone = 'UTC' . $current_offset; + } else { + $timezone = 'UTC+' . $current_offset; + } + } + + $stats['versions'] = [ + 'wp' => sanitize_text_field( $GLOBALS['wp_version'] ), + 'php' => sanitize_text_field( phpversion() ), + 'mysql' => sanitize_text_field( $wpdb->db_version() ), + ]; + + $stats['theme'] = [ + 'name' => sanitize_text_field( $theme->get( 'Name' ) ), + 'version' => sanitize_text_field( $theme->get( 'Version' ) ), + 'stylesheet' => sanitize_text_field( $theme->get_stylesheet() ), + 'template' => sanitize_text_field( $theme->get_template() ), + ]; + + $stats['site_language'] = sanitize_text_field( get_locale() ); + $stats['user_language'] = sanitize_text_field( get_user_locale() ); + $stats['is_public'] = (int) get_option( 'blog_public', 0 ); + $stats['wp_debug'] = (int) ( defined( 'WP_DEBUG' ) && WP_DEBUG ); + $stats['site_timezone'] = sanitize_text_field( $timezone ); + + $stats['totals'] = [ + 'all_post_types' => (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$wpdb->posts}`" ), + 'events' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_events' ) ), + 'venues' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_venue' ) ), + 'organizers' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->posts}` WHERE post_type = %s", 'tribe_organizer' ) ), + 'event_categories' => (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->term_taxonomy}` WHERE taxonomy = %s", 'tribe_events_cat' ) ), + ]; + + self::$stats_full = $stats; + + return $stats; + + } + + /** + * Build and get the stats + * + * @return array + */ + public function get_stats() { + + $stats = self::$stats; + + if ( empty( $stats ) ) { + $stats = $this->build_stats(); + } + + /** + * Allow full stats data to be built and sent. + * + * @param boolean $use_full_stats Whether to send full stats + * + * @since 4.5.1 + */ + $use_full_stats = apply_filters( 'pue_use_full_stats', false ); + + if ( $use_full_stats ) { + $stats_full = self::$stats_full; + + if ( empty( $stats_full ) ) { + $stats = $this->build_full_stats( $stats ); + } + } + + /** + * Filter stats and allow plugins to add their own stats + * for tracking specific points of data. + * + * @param array $stats Stats gathered by PUE Checker class + * @param boolean $use_full_stats Whether to send full stats + * @param \Tribe__PUE__Checker $checker PUE Checker class object + * + * @since 4.5.1 + */ + $stats = apply_filters( 'pue_stats', $stats, $use_full_stats, $this ); + + return $stats; + } + + /** + * Get current license key, optionally of a specific type. + * + * @param string $type The type of key to get (any, network, local, default) + * @param string $return_type The type of data to return (key, origin) + * + * @return string + */ + public function get_key( $type = 'any', $return_type = 'key' ) { + + $license_key = ''; + $license_origin = 'm'; + + /* + * Even if we have a network key if the plugin is not active on the network then it should + * not be used. + */ + if ( + ( 'network' === $type || 'any' === $type ) + && is_multisite() + && $this->is_plugin_active_for_network() + ) { + $license_key = get_network_option( null, $this->pue_install_key, '' ); + } + + if ( ( 'local' === $type || 'any' === $type ) && empty( $license_key ) ) { + $license_key = get_option( $this->pue_install_key, '' ); + } + + if ( empty( $license_key ) && ( 'default' === $type || 'any' === $type ) ) { + $autoloader = Tribe__Autoloader::instance(); + + $class_name = $autoloader->get_prefix_by_slug( $this->get_slug() ); + + if ( $class_name ) { + $is_namespaced = false !== strpos( $class_name, '\\' ); + + if ( $is_namespaced ) { + // Handle class prefixes like Tribe\Plugin\. + $class_name .= 'PUE\Helper'; + } else { + // Handle class prefixes like Tribe__Plugin__. + $class_name .= 'PUE__Helper'; + } + + if ( constant( $class_name . '::DATA' ) ) { + $license_key = constant( $class_name . '::DATA' ); + + $license_origin = 'e'; + } + } + } + + if ( 'origin' === $return_type ) { + if ( 'm' === $license_origin ) { + $default_key = $this->get_key( 'default' ); + + if ( $license_key !== $default_key ) { + $license_origin = 'o'; + } + } + + return $license_origin; + } + + return $license_key; + + } + + /** + * Update license key for specific type of license. + * + * @param string $license_key The new license key value + * @param string $type The type of key to update (network or local) + */ + public function update_key( $license_key, $type = 'local' ) { + + if ( 'network' === $type && is_multisite() ) { + update_network_option( null, $this->pue_install_key, sanitize_text_field( $license_key ) ); + } elseif ( 'local' === $type ) { + update_option( $this->pue_install_key, sanitize_text_field( $license_key ) ); + } + + } + + /** + * Checks for the license key status with MT servers. + * + * @param string $key + * @param bool $network Whether the key to check for is a network one or not. + * + * @return array An associative array containing the license status response. + */ + public function validate_key( $key, $network = false ) { + $response = []; + $response['status'] = 0; + + if ( ! $key ) { + $response['message'] = sprintf( esc_html__( 'Hmmm... something\'s wrong with this validator. Please contact %ssupport%s.', 'tribe-common' ), '', '' ); + return $response; + } + + $query_args = $this->get_validate_query(); + + $query_args['key'] = sanitize_text_field( $key ); + + // This method is primarily used during when validating keys by ajax, before they are + // formally committed or saved by the user: for that reason we call request_info() + // rather than license_key_status() as at this stage invalid or missing keys should + // not result in admin notices being generated + $plugin_info = $this->request_info( $query_args ); + $expiration = isset( $plugin_info->expiration ) ? $plugin_info->expiration : __( 'unknown date', 'tribe-common' ); + + $pue_notices = Tribe__Main::instance()->pue_notices(); + $plugin_name = $this->get_plugin_name(); + + if ( empty( $plugin_info ) ) { + $response['message'] = __( 'Sorry, key validation server is not available.', 'tribe-common' ); + } elseif ( isset( $plugin_info->api_expired ) && 1 === (int) $plugin_info->api_expired ) { + $response['message'] = $this->get_license_expired_message(); + $response['api_expired'] = true; + } elseif ( isset( $plugin_info->api_upgrade ) && 1 === (int) $plugin_info->api_upgrade ) { + $response['message'] = $this->get_api_message( $plugin_info ); + $response['api_upgrade'] = true; + } elseif ( isset( $plugin_info->api_invalid ) && 1 === (int) $plugin_info->api_invalid ) { + $response['message'] = $this->get_api_message( $plugin_info ); + $response['api_invalid'] = true; + } else { + $key_type = 'local'; + + if ( $network ) { + $key_type = 'network'; + } + + $current_install_key = $this->get_key( $key_type ); + + if ( $current_install_key && $current_install_key === $query_args['key'] ) { + $default_success_msg = esc_html( sprintf( __( 'Valid Key! Expires on %s', 'tribe-common' ), $expiration ) ); + } else { + // Set the key + $this->update_key( $query_args['key'], $key_type ); + + $default_success_msg = esc_html( sprintf( __( 'Thanks for setting up a valid key. It will expire on %s', 'tribe-common' ), $expiration ) ); + + //Set SysInfo Key on Tec.com After Successful Validation of License + $optin_key = get_option( 'tribe_systeminfo_optin' ); + if ( $optin_key ) { + Tribe__Support::send_sysinfo_key( $optin_key, $query_args['domain'], false, true ); + } + } + + $pue_notices->clear_notices( $plugin_name ); + + $response['status'] = isset( $plugin_info->api_message ) ? 2 : 1; + $response['message'] = isset( $plugin_info->api_message ) ? $plugin_info->api_message : $default_success_msg; + $response['expiration'] = esc_html( $expiration ); + + if ( isset( $plugin_info->daily_limit ) ) { + $response['daily_limit'] = intval( $plugin_info->daily_limit ); + } + } + + $response['message'] = wp_kses( $response['message'], 'data' ); + + return $response; + } + + public function get_license_expired_message() { + return '' . + __( 'Renew Your License Now', 'tribe-common' ) . + '' . + __( ' (opens in a new window)', 'tribe-common' ) . + ''; + } + + /** + * Echo JSON results for key validation + */ + public function ajax_validate_key() { + $key = isset( $_POST['key'] ) ? wp_unslash( $_POST['key'] ) : null; + $nonce = isset( $_POST['_wpnonce'] ) ? wp_unslash( $_POST['_wpnonce'] ) : null; + + if ( + empty( $nonce ) + || false === wp_verify_nonce( $nonce, 'pue-validate-key_' . $this->get_slug() ) + ) { + $response = [ + 'status' => 0, + 'message' => __( 'Please refresh the page and try your request again.', 'tribe-common' ), + ]; + } else { + $response = $this->validate_key( $key ); + } + + echo json_encode( $response ); + exit; + } + + /** + * Processes variable substitutions for server-side API message. + * + * @param Tribe__PUE__Plugin_Info $info + * + * @return string + */ + private function get_api_message( $info ) { + // this default message should never show, but is here as a fallback just in case. + $message = sprintf( + esc_html__( 'There is an update for %s. You\'ll need to %scheck your license%s to have access to updates, downloads, and support.', 'tribe-common' ), + $this->get_plugin_name(), + '', + '' + ); + + if ( ! empty( $info->api_inline_invalid_message ) ) { + $message = wp_kses( $info->api_inline_invalid_message, 'post' ); + } + + $message = str_replace( '%plugin_name%', $this->get_plugin_name(), $message ); + $message = str_replace( '%plugin_slug%', $this->get_slug(), $message ); + $message = str_replace( '%update_url%', $this->get_pue_update_url() . '/', $message ); + $message = str_replace( '%version%', $info->version, $message ); + $message = str_replace( '%changelog%', 'what\'s new', $message ); + + return $message; + } + + /** + * Whether the plugin is network activated and licensed or not. + * + * @return bool + */ + public function is_network_licensed() { + $is_network_licensed = false; + + if ( ! is_network_admin() && $this->is_plugin_active_for_network() ) { + $network_key = $this->get_key( 'network' ); + $local_key = $this->get_key( 'local' ); + + // Check whether the network is licensed and NOT overridden by local license + if ( $network_key && ( empty( $local_key ) || $local_key === $network_key ) ) { + $is_network_licensed = true; + } + } + + return $is_network_licensed; + } + + /** + * Returns tet name of the option that stores the license key. + * + * @return string + */ + public function get_license_option_key() { + return $this->pue_install_key; + } + + private function get_api_update_message() { + $plugin_info = $this->plugin_info; + + if ( ! isset( $plugin_info->api_invalid_message ) ) { + return false; + } + + $message = sprintf( + esc_html__( 'There is an update for %s. %sRenew your license%s to get access to bug fixes, security updates, and new features.', 'tribe-common' ), + $this->get_plugin_name(), + '', + '' + ); + + return $message; + } + + /** + * Displays a PUE message on the page if it is relevant + * + * @param string $page + */ + public function maybe_display_json_error_on_plugins_page( $page ) { + if ( 'plugins.php' !== $page ) { + return; + } + + $state = $this->get_state(); + $messages = []; + $plugin_updates = get_plugin_updates(); + $update_available = isset( $plugin_updates[ $this->plugin_file ] ); + + // Check to see if there is an licensing error or update message we should show + if ( ! empty( $state->update->license_error ) ) { + $messages[] = $state->update->license_error; + } elseif ( $update_available && current_user_can( 'update_plugins' ) ) { + // A plugin update is available + $update_now = sprintf( + esc_html__( 'Update now to version %s.', 'tribe-common' ), + $state->update->version + ); + + $update_now_link = sprintf( + ' %2$s', + wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->plugin_file, 'upgrade-plugin_' . $this->plugin_file ), + $update_now + ); + + $update_message = sprintf( + esc_html__( 'There is a new version of %1$s available. %2$s', 'tribe-common' ), + $this->plugin_name, + $update_now_link + ); + + $messages[] = sprintf( + '

          %s

          ', + $update_message + ); + } + + if ( empty( $messages ) ) { + return; + } + + $message_row_html = ''; + + foreach ( $messages as $message ) { + $message_row_html .= sprintf( + '
          %s
          ', + $message + ); + } + + $message_row_html = sprintf( + '%s', + $message_row_html + ); + + $this->plugin_notice = [ + 'slug' => $this->plugin_file, + 'message_row_html' => $message_row_html, + ]; + + add_filter( 'tribe_plugin_notices', [ $this, 'add_notice_to_plugin_notices' ] ); + + } + + public function add_notice_to_plugin_notices( $notices ) { + if ( ! $this->plugin_notice || $this->is_network_licensed() ) { + return $notices; + } + + $notices[ $this->plugin_notice['slug'] ] = $this->plugin_notice; + + return $notices; + } + + /** + * Returns plugin/license key data based on the provided query arguments. + * + * Calling this method will also take care of setting up admin notices for any + * keys that are invalid or have expired, etc. + * + * @see Tribe__PUE__Checker::request_info() + * + * @param $query_args + * + * @return Tribe__PUE__Plugin_Info|null + */ + public function license_key_status( $query_args ) { + $pue_notices = Tribe__Main::instance()->pue_notices(); + $plugin_info = $this->request_info( $query_args ); + $plugin_name = empty( $this->plugin_name ) ? $this->get_plugin_name() : $this->plugin_name; + + if ( empty( $plugin_name ) ) { + return $plugin_info; + } + + $install_key = $this->get_key(); + + // Check for expired keys + if ( ! empty( $plugin_info->api_expired ) ) { + $pue_notices->add_notice( Tribe__PUE__Notices::EXPIRED_KEY, $plugin_name ); + } elseif ( ! empty( $plugin_info->api_upgrade ) ) { + // Check for keys that are out of installs (*must* happen before the api_invalid test) + $pue_notices->add_notice( Tribe__PUE__Notices::UPGRADE_KEY, $plugin_name ); + } elseif ( + // Check for invalid keys last of all (upgrades/empty keys will be flagged as invalid) + ! empty( $plugin_info->api_invalid ) + && ( + 'component' === $this->context + || ( + 'service' === $this->context + && $install_key + ) + ) + ) { + $pue_notices->add_notice( Tribe__PUE__Notices::INVALID_KEY, $plugin_name ); + } else { + // If none of the above were satisfied we can assume the key is valid + $pue_notices->clear_notices( $plugin_name ); + } + + return $plugin_info; + } + + /** + * Sets up and manages those license key notifications which don't depend on communicating with a remote + * PUE server, etc. + */ + public function general_notifications() { + $plugin_name = empty( $this->plugin_name ) ? $this->get_plugin_name() : $this->plugin_name; + + // Register our plugin name for use in messages (thus if we're deactivated, any previously + // added persistent messaging can be cleared) + Tribe__Main::instance()->pue_notices()->register_name( $plugin_name ); + + // Detect and setup notices for missing keys + $install_key = $this->get_key(); + + if ( empty( $install_key ) && 'service' !== $this->context ) { + Tribe__Main::instance()->pue_notices()->add_notice( Tribe__PUE__Notices::INVALID_KEY, $plugin_name ); + } + } + + /** + * Retrieve plugin info from the configured API endpoint. + * + * In general, this method should not be called directly and it is preferable to call + * the license_key_status() method instead. That method returns the same result, but + * also analyses each response to set up appropriate license key notifications in the + * admin environment. + * + * @uses wp_remote_get() + * @see Tribe__PUE__Checker::license_key_status() + * + * @param array $query_args Additional query arguments to append to the request. Optional. + * + * @return string $plugin_info + */ + public function request_info( $query_args = [] ) { + $query_args = apply_filters( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $query_args ); + + // Cache the API call so it only needs to be made once per plugin per page load. + static $plugin_info_cache; + + // Sort parameter keys + $hash_data = $query_args; + + ksort( $hash_data ); + + // Flatten hashed data + $hash_data = json_encode( $hash_data ); + + // Generate unique hash + $key = hash( 'sha256', $hash_data ); + + if ( isset( $plugin_info_cache[ $key ] ) ) { + return $plugin_info_cache[ $key ]; + } + + //Various options for the wp_remote_get() call. Plugins can filter these, too. + $options = [ + 'body' => $query_args, + 'timeout' => 15, //seconds + 'headers' => [ + 'Accept' => 'application/json', + ], + ]; + $options = apply_filters( 'tribe_puc_request_info_options-' . $this->get_slug(), $options ); + + $url = sprintf( '%s/api/plugins/v2/license/validate', $this->get_pue_update_url() ); + + $result = wp_remote_post( + $url, + $options + ); + + // Try to parse the response + $plugin_info = null; + if ( ! is_wp_error( $result ) && isset( $result['response']['code'] ) && ( 200 === (int) $result['response']['code'] ) && ! empty( $result['body'] ) ) { + $plugin_info = Tribe__PUE__Plugin_Info::from_json( $result['body'] ); + } + $plugin_info = apply_filters( 'tribe_puc_request_info_result-' . $this->get_slug(), $plugin_info, $result ); + + $plugin_info_cache[ $key ] = $plugin_info; + + return $plugin_info; + } + + /** + * Returns the domain contained in the network's siteurl option (not the full URL). + * + * @return string + */ + public function get_network_domain() { + $site_url = wp_parse_url( get_site_option( 'siteurl' ) ); + if ( ! $site_url || ! isset( $site_url['host'] ) ) { + return ''; + } else { + return strtolower( $site_url['host'] ); + } + } + + /** + * Retrieve the latest update (if any) from the configured API endpoint. + * + * @uses Tribe__PUE__Checker::request_info() + * + * @return Tribe__PUE__Utility An instance of Tribe__PUE__Utility, or NULL when no updates are available. + */ + public function request_update() { + // For the sake of simplicity, this function just calls request_info() + // and transforms the result accordingly. + $query_args = $this->get_validate_query(); + + if ( ! empty( $_POST['key'] ) ) { + $query_args['key'] = sanitize_text_field( $_POST['key'] ); + } elseif ( ! empty( $_POST[ $this->pue_install_key ] ) ) { + $query_args['key'] = sanitize_text_field( $_POST[ $this->pue_install_key ] ); + } + + $this->plugin_info = $plugin_info = $this->license_key_status( $query_args ); + + if ( null === $plugin_info ) { + return null; + } + + // admin display for if the update check reveals that there is a new version but the API key isn't valid. + if ( isset( $plugin_info->api_invalid ) ) { + $plugin_info = Tribe__PUE__Utility::from_plugin_info( $plugin_info ); + $plugin_info->license_error = $this->get_api_message( $plugin_info ); + + return $plugin_info; + } + + if ( ! empty( $plugin_info->new_install_key ) ) { + $this->update_key( $plugin_info->new_install_key ); + } + + // Need to correct the download url so it contains the custom user data (e.g. api and any other parameters). + $download_query = $this->get_download_query(); + + if ( ! empty( $download_query ) ) { + $plugin_info->download_url = esc_url_raw( add_query_arg( $download_query, $plugin_info->download_url ) ); + } + + // Add plugin dirname/file (this will be expected by WordPress when it builds the plugin list table) + $plugin_info->plugin = $this->get_plugin_file(); + + return Tribe__PUE__Utility::from_plugin_info( $plugin_info ); + } + + /** + * Display a changelog when the api key is missing. + */ + public function display_changelog() { + //contents of changelog display page when api-key is invalid or missing. It will ONLY show the changelog (hook into existing thickbox?) + } + + /** + * Get the currently installed version of the plugin. + * + * @return string Version number. + */ + public function get_installed_version() { + if ( function_exists( 'get_plugins' ) ) { + $all_plugins = get_plugins(); + if ( array_key_exists( $this->get_plugin_file(), $all_plugins ) && array_key_exists( 'Version', $all_plugins[ $this->get_plugin_file() ] ) ) { + return $all_plugins[ $this->get_plugin_file() ]['Version']; + } + } + } + + /** + * Get plugin update state + * + * @param boolean $force_recheck + * + * @return object + */ + public function get_state( $force_recheck = false ) { + + $state = null; + + if ( ! $force_recheck ) { + $state = get_site_option( $this->pue_option_name, false, false ); + } + + if ( empty( $state ) ) { + $state = new stdClass; + $state->lastCheck = 0; + $state->checkedVersion = ''; + $state->update = null; + } + + return $state; + + } + + /** + * Update plugin update state + * + * @param object $value + */ + public function update_state( $value ) { + + update_site_option( $this->pue_option_name, $value ); + + } + + /** + * Check for plugin updates. + * + * The results are stored in the DB option specified in $pue_option_name. + * + * @param array $updates + * @param boolean $force_recheck + * + * @return array + */ + public function check_for_updates( $updates = [], $force_recheck = false ) { + $state = $this->get_state( $force_recheck ); + + $state->lastCheck = time(); + $state->checkedVersion = $this->get_installed_version(); + + // Save before checking in case something goes wrong + $this->update_state( $state ); + + $state->update = $this->request_update(); + + // If a null update was returned, skip to the end of the function. + if ( null !== $state->update ) { + // Is there an update to insert? + if ( version_compare( $state->update->version, $this->get_installed_version(), '>' ) ) { + if ( empty( $updates ) ) { + $updates = (object) [ 'response' => [] ]; + } + + $updates->response[ $this->get_plugin_file() ] = $state->update->to_wp_format(); + + // If the key has expired we should register an appropriate admin notice + if ( $this->plugin_info->api_expired ) { + Tribe__Main::instance()->pue_notices()->add_notice( Tribe__PUE__Notices::EXPIRED_KEY, $this->plugin_name ); + } + } + } + + $this->update_state( $state ); + + return $updates; + } + + /** + * Clears out the site external site option and re-checks the license key + * + * @param string $value + * @param string $field_id + * @param string $validated_field + * + * @return string + */ + public function check_for_api_key_error( $value, $field_id, $validated_field ) { + + // Only hook into our option + if ( $this->pue_install_key !== $field_id ) { + return $value; + } + + if ( 'service' !== $this->context ) { + $this->check_for_updates( [], true ); + } + + $network_option = false; + + if ( ! empty( $validated_field->field['network_option'] ) ) { + $network_option = (boolean) $validated_field->field['network_option']; + } + + $key_type = 'local'; + + if ( $network_option ) { + $key_type = 'network'; + } + + $current_key = $this->get_key( $key_type ); + + // if we are saving this PUE key, we need to make sure we update the license key notices + // appropriately. Otherwise, we could have an invalid license key in place but the notices + // aren't being thrown globally + + $query_args = $this->get_validate_query(); + + $query_args['key'] = sanitize_text_field( $value ); + + $this->license_key_status( $query_args ); + + return $value; + + } + + /** + * Intercept plugins_api() calls that request information about our plugin and + * use the configured API endpoint to satisfy them. + * + * @see plugins_api() + * + * @param mixed $result + * @param string $action + * @param array|object $args + * + * @return mixed + */ + public function inject_info( $result, $action = null, $args = null ) { + $relevant = ( 'plugin_information' === $action ) && isset( $args->slug ) && ( $args->slug === $this->slug ); + if ( ! $relevant ) { + return $result; + } + + $query_args = $this->get_validate_query(); + + $plugin_info = $this->license_key_status( $query_args ); + + if ( $plugin_info ) { + return $plugin_info->to_wp_format(); + } + + return $result; + } + + /** + * Register a callback for filtering query arguments. + * + * The callback function should take one argument - an associative array of query arguments. + * It should return a modified array of query arguments. + * + * @uses add_filter() This method is a convenience wrapper for add_filter(). + * + * @param callback $callback + * + */ + public function add_query_arg_filter( $callback ) { + add_filter( 'tribe_puc_request_info_query_args-' . $this->get_slug(), $callback ); + } + + /** + * Register a callback for filtering arguments passed to wp_remote_get(). + * + * The callback function should take one argument - an associative array of arguments - + * and return a modified array or arguments. See the WP documentation on wp_remote_get() + * for details on what arguments are available and how they work. + * + * @uses add_filter() This method is a convenience wrapper for add_filter(). + * + * @param callback $callback + * + */ + public function add_http_request_arg_filter( $callback ) { + add_filter( 'tribe_puc_request_info_options-' . $this->get_slug(), $callback ); + } + + /** + * Register a callback for filtering the plugin info retrieved from the external API. + * + * The callback function should take two arguments. If the plugin info was retrieved + * successfully, the first argument passed will be an instance of Tribe__PUE__Plugin_Info. Otherwise, + * it will be NULL. The second argument will be the corresponding return value of + * wp_remote_get (see WP docs for details). + * + * The callback function should return a new or modified instance of Tribe__PUE__Plugin_Info or NULL. + * + * @uses add_filter() This method is a convenience wrapper for add_filter(). + * + * @param callback $callback + * + */ + public function add_result_filter( $callback ) { + add_filter( 'tribe_puc_request_info_result-' . $this->get_slug(), $callback, 10, 2 ); + } + + /** + * Insert an array after a specified key within another array. + * + * @param $key + * @param $source_array + * @param $insert_array + * + * @return array + * + */ + public static function array_insert_after_key( $key, $source_array, $insert_array ) { + if ( array_key_exists( $key, $source_array ) ) { + $position = array_search( $key, array_keys( $source_array ), true ) + 1; + $source_array = array_slice( $source_array, 0, $position, true ) + $insert_array + array_slice( $source_array, $position, null, true ); + } else { + // If no key is found, then add it to the end of the array. + $source_array += $insert_array; + } + + return $source_array; + } + + /** + * Add this plugin key to the list of keys + * + * @param array $keys + * + * @return array $keys + * + */ + public function return_install_key( $keys = [] ) { + $key = $this->get_key(); + + if ( ! empty( $key ) ) { + $keys[ $this->get_slug() ] = $key; + } + + return $keys; + } + + /** + * Prevent the default inline update-available messages from appearing, as we + * have implemented our own. + * + * @see resources/js/pue-notices.js + */ + public function remove_default_inline_update_msg() { + remove_action( "after_plugin_row_{$this->plugin_file}", 'wp_plugin_update_row' ); + } + + /** + * Returns the domain of the single site installation + * + * Will try to read it from the $_SERVER['SERVER_NAME'] variable + * and fall back on the one contained in the siteurl option. + * + * @return string + */ + protected function get_site_domain() { + if ( isset( $_SERVER['SERVER_NAME'] ) ) { + return $_SERVER['SERVER_NAME']; + } + $site_url = wp_parse_url( get_option( 'siteurl' ) ); + if ( ! $site_url || ! isset( $site_url['host'] ) ) { + return ''; + } else { + return strtolower( $site_url['host'] ); + } + } + + /** + * Check whether the current plugin is active for the network or not. + * + * @return boolean Whether the plugin is network activated + */ + protected function is_plugin_active_for_network() { + + if ( ! is_multisite() ) { + return false; + } + + $map = [ + 'event-aggregator/event-aggregator.php' => 'the-events-calendar/the-events-calendar.php', + ]; + + $plugin_file = $this->get_plugin_file(); + + if ( isset( $map[ $this->plugin_file ] ) ) { + $plugin_file = $map[ $this->plugin_file ]; + } + + if ( function_exists( 'is_plugin_active_for_network' ) ) { + // If is_plugin_active_for_network() is available, let's use it! + return is_plugin_active_for_network( $plugin_file ); + } else { + // When this method is called sufficiently early in the request, + // is_plugin_active_for_network() may not be available (#115826) + $plugins = get_site_option( 'active_sitewide_plugins' ); + return isset( $plugins[ $plugin_file ] ); + } + } + + /** + * Returns the localized string for a plugin or component license state. + * + * @return string The localized state string. + */ + protected function get_network_license_state_string() { + $states = [ + 'licensed' => esc_html__( 'A valid license has been entered by your network administrator.', 'tribe-common' ), + 'not-licensed' => esc_html__( 'No license entered. Consult your network administrator.', 'tribe-common' ), + 'expired' => esc_html__( 'Expired license. Consult your network administrator.', 'tribe-common' ), + ]; + + $response = $this->validate_key( $this->get_key( 'network' ), true ); + + if ( isset( $response['status'] ) && 1 === (int) $response['status'] ) { + $state = 'licensed'; + } elseif ( isset( $response['api_expired'] ) && true === (boolean) $response['api_expired'] ) { + $state = 'expired'; + } else { + $state = 'not-licensed'; + } + + return $states[ $state ]; + } + + /** + * Whether the user should be shown the fully editable subsite license field or not. + * + * This check will happen in the context of the plugin administration area; checks on the user + * capability to edit the plugin settings have been made before. + * + * @return bool + */ + public function should_show_subsite_editable_license() { + if ( ! is_multisite() ) { + return true; + } + + if ( is_network_admin() ) { + return false; + } + + if ( $this->is_plugin_active_for_network() && ! is_super_admin() ) { + return false; + } + + return true; + } + + /** + * Whether the user should be shown the override control to override the network license key or not. + * + * This check will happen in the context of the plugin administration area; checks on the user + * capability to edit the plugin settings have been made before. + * + * @return bool + */ + public function should_show_overrideable_license() { + if ( is_network_admin() ) { + return false; + } + + if ( is_super_admin() ) { + return false; + } + + if ( ! $this->is_plugin_active_for_network() ) { + return false; + } + + return true; + } + + /** + * Whether the user should be shown the fully editable network license field or not. + * + * This check will happen in the context of the network plugin administration area; checks on the user + * capability to edit the network plugin settings have been made before. + * + * @return bool + */ + public function should_show_network_editable_license() { + return is_network_admin() && is_super_admin(); + } + } +} diff --git a/tribe-common/src/Tribe/PUE/Notices.php b/tribe-common/src/Tribe/PUE/Notices.php new file mode 100644 index 0000000000..8946c9ac7a --- /dev/null +++ b/tribe-common/src/Tribe/PUE/Notices.php @@ -0,0 +1,506 @@ + 'Event Tickets Plus', + 'pue_install_key_events_community' => 'The Events Calendar: Community Events', + 'pue_install_key_events_community_tickets' => 'The Events Calendar: Community Events Tickets', + 'pue_install_key_image_widget_plus' => 'Image Widget Plus', + 'pue_install_key_tribe_eventbrite' => 'The Events Calendar: Eventbrite Tickets', + 'pue_install_key_tribe_filterbar' => 'The Events Calendar: Filter Bar', + 'pue_install_key_event_aggregator' => 'Event Aggregator', + 'pue_install_key_events_calendar_pro' => 'The Events Calendar PRO', + ]; + + /** + * Sets up license key related admin notices. + */ + public function __construct() { + $this->populate(); + add_action( 'current_screen', [ $this, 'setup_notices' ] ); + add_action( 'tribe_pue_notices_save_notices', [ $this, 'maybe_undismiss_notices' ] ); + } + + /** + * Registers a plugin name that should be used in license key notifications. + * + * If, on a given request, the name is not registered then the plugin name will not + * feature in any notifications. The benefit is that if a plugin is suddenly removed, + * it's name can be automatically dropped from any pre-registered persistent + * notifications. + * + * @param string $plugin_name + */ + public function register_name( $plugin_name ) { + $this->registered[] = $plugin_name; + } + + /** + * Restores plugins added on previous requests to the relevant notification + * groups. + */ + protected function populate() { + $this->saved_notices = (array) get_option( self::STORE_KEY, [] ); + + if ( empty( $this->saved_notices ) ) { + return; + } + + $this->notices = array_merge_recursive( $this->notices, $this->saved_notices ); + + // Cleanup + foreach ( $this->notices as $key => &$plugin_lists ) { + // Purge any elements that are not arrays + if ( ! is_array( $plugin_lists ) ) { + unset( $this->notices[ $key ] ); + continue; + } + } + } + + /** + * Saves any license key notices already added. + */ + public function save_notices() { + update_option( self::STORE_KEY, $this->notices ); + + /** + * Fires after PUE license key notices have been saved. + * + * @param array $current_notices + * @param array $previously_saved_notices + */ + do_action( 'tribe_pue_notices_save_notices', $this->notices, $this->saved_notices ); + } + + /** + * Undismisses license key notifications where appropriate. + * + * The idea is that if an invalid key is detected for one or more plugins, we show a notification + * until a user dismisses it. That user will not then see the notification again unless or until + * an additional plugin name is added to the invalid key list. + * + * Example: + * + * - Notification listing "Eventbrite" and "Pro" keys as invalid shows + * - User X dismisses the notification + * - The "Pro" license is fixed/corrected - notification remains in a "dismissed" status for User X + * - "Filter Bar" is added to the list of invalid keys + * - The invalid key notification is undismissed, to make all users (including User X) aware of + * the problem re Filter Bar + */ + public function maybe_undismiss_notices() { + foreach ( $this->notices as $notice_type => $plugin_list ) { + if ( is_array( $this->saved_notices ) && ! empty( $this->saved_notices[ $notice_type ] ) ) { + $new_plugins = array_diff_key( $this->notices[ $notice_type ], $this->saved_notices[ $notice_type ] ); + } else { + $new_plugins = $this->notices[ $notice_type ]; + } + + if ( ! empty( $new_plugins ) ) { + Tribe__Admin__Notices::instance()->undismiss_for_all( 'pue_key-' . $notice_type ); + } + } + } + + /** + * Used to include a plugin in a notification. + * + * For example, this could be used to add "My Plugin" to the expired license key + * notification by passing Tribe__PUE__Notices::EXPIRED_KEY as the second param. + * + * Plugins can only be added to one notification group at a time, so if a plugin + * was already added to the MISSING_KEY group and is subsequently added to the + * INVALID_KEY group, the previous entry (under MISSING_KEY) will be cleared. + * + * @param string $notice_type + * @param string $plugin_name + */ + public function add_notice( $notice_type, $plugin_name ) { + $this->clear_notices( $plugin_name, true ); + $this->notices[ $notice_type ][ $plugin_name ] = true; + $this->save_notices(); + } + + /** + * Returns whether or not a given plugin name has a specific notice + * + * @param string $plugin_name + * @param string|null $notice_type + * + * @return boolean + */ + public function has_notice( $plugin_name, $notice_type = null ) { + // If we match a pue key we use that value + if ( isset( $this->plugin_names[ $plugin_name ] ) ) { + $plugin_name = $this->plugin_names[ $plugin_name ]; + } + + if ( $notice_type ) { + return ! empty( $this->notices[ $notice_type ][ $plugin_name ] ); + } + + foreach ( $this->notices as $notice_type => $plugins ) { + if ( ! empty( $plugins[ $plugin_name ] ) ) { + return true; + } + } + + return false; + } + + /** + * Removes any notifications for the specified plugin. + * + * Useful when a valid license key is detected for a plugin, where previously + * it might have been included under a warning notification. + * + * If the optional second param is set to true then this change will not + * immediately be committed to storage (useful if we know this will happen in + * any case later on in the same request). + * + * @param string $plugin_name + * @param bool $defer_saving_change = false + */ + public function clear_notices( $plugin_name, $defer_saving_change = false ) { + foreach ( $this->notices as $notice_type => &$list_of_plugins ) { + unset( $list_of_plugins[ $plugin_name ] ); + } + + if ( ! $defer_saving_change ) { + $this->save_notices(); + } + } + + /** + * Tests to see if there are any extant notifications and renders them if so. + * + * This must run prior to Tribe__Admin__Notices::hook() (which currently runs during + * "current_screen" priority 20). + */ + public function setup_notices() { + // Don't allow this to run multiple times + remove_action( 'current_screen', [ $this, 'setup_notices' ] ); + + // No need to display license key notices to users without appropriate capabilities + if ( ! current_user_can( 'install_plugins' ) ) { + return; + } + + foreach ( $this->notices as $notice_type => $plugin_names ) { + if ( empty( $plugin_names ) ) { + continue; + } + + $callback = [ $this, 'render_' . $notice_type ]; + + if ( is_callable( $callback ) ) { + tribe_notice( 'pue_key-' . $notice_type, $callback, 'dismiss=1&type=warning' ); + } + } + } + + /** + * Select all products with empty license keys + * and format their names + * + * This information will be used to remove products + * with no license keys from $this->notices['invalid_key'] + * + * @since 4.8 + * + * @return array + */ + public function select_empty_keys() { + /** @var $wpdb */ + global $wpdb; + + $sql = " + SELECT option_name + FROM {$wpdb->options} + WHERE option_name LIKE 'pue_install_key_%' + AND option_value='' + "; + + $empty_keys = $wpdb->get_results( $sql, ARRAY_N ); + + $formatted_empty_keys = []; + foreach ( $empty_keys as $empty_key ) { + $empty_key = Tribe__Utils__Array::get( $empty_key, [ 0 ] ); + $formatted_empty_keys[] = Tribe__Utils__Array::get( $this->plugin_names, $empty_key ); + } + + return $formatted_empty_keys; + } + + /** + * Generate a notice listing any plugins for which license keys have been entered but + * are invalid (in the sense of not matching PUE server records or having been revoked + * rather than having expired which is handled separately). + * + * In the context of the plugin admin screen, will not render if the key-has-expired + * notice is also scheduled to display. + */ + public function render_invalid_key() { + global $pagenow; + + $empty_keys = $this->select_empty_keys(); + + if ( empty( $empty_keys ) ) { + return; + } + + // Remove the invalid_key notice for products with an empty license key + foreach ( $empty_keys as $empty_key ) { + if ( array_key_exists( $empty_key, $this->notices['invalid_key'] ) ) { + unset( $this->notices['invalid_key'][ $empty_key ] ); + } + } + + if ( 'plugins.php' === $pagenow && ! empty( $this->notices[ self::EXPIRED_KEY ] ) ) { + return; + } + + $plugin_names = $this->get_formatted_plugin_names( self::INVALID_KEY ); + + if ( empty( $plugin_names ) ) { + return; + } + + $prompt = sprintf( + _n( + "It looks like you're using %1\$s, but the license key is invalid. Please download the latest version %2\$sfrom your account%3\$s.", + "It looks like you're using %1\$s, but the license keys are invalid. Please download the latest versions %2\$sfrom your account%3\$s.", + count( $this->notices[ self::INVALID_KEY ] ), + 'tribe-common' + ), + $plugin_names, + '', + '' + ); + + /** + * Filters the actions that can be taken if an invalid key is present + * + * @param string $actions Actions + * @param array $plugin_names Plugin names the message applies to + */ + $action_steps = apply_filters( 'tribe_notice_invalid_key_actions', $this->find_your_key_text(), $plugin_names ); + + if ( $action_steps ) { + $action_steps = "

          {$action_steps}

          "; + } + + $this->render_notice( 'pue_key-' . self::INVALID_KEY, "

          {$prompt}

          {$action_steps}" ); + } + + /** + * Generate a notice listing any plugins for which license keys have expired. + * + * This notice should only appear at the top of the plugin admin screen and "trumps" + * the missing/invalid key notice on that screen only. + */ + public function render_expired_key() { + global $pagenow; + + if ( 'plugins.php' !== $pagenow ) { + return; + } + + $plugin_names = $this->get_formatted_plugin_names( self::EXPIRED_KEY ); + + if ( empty( $plugin_names ) ) { + return; + } + + $prompt = sprintf( _n( + 'There is an update available for %1$s but your license has expired. %2$sVisit the Events Calendar website to renew your license.%3$s', + 'Updates are available for %1$s but your license keys have expired. %2$sVisit the Events Calendar website to renew your licenses.%3$s', + count( $this->notices[ self::EXPIRED_KEY ] ), + 'tribe-common' + ), + $plugin_names, + '', + '' + ); + + $renew_action = + '' . + __( 'Renew Your License Now', 'tribe-common' ) . + '' . + __( ' (opens in a new window)', 'tribe-common' ) . + ''; + + $this->render_notice( 'pue_key-' . self::EXPIRED_KEY, "

          $prompt

          $renew_action

          " ); + } + + /** + * Generate a notice listing any plugins which have valid license keys, but those keys + * have met or exceeded the permitted number of installations they can be applied to. + */ + public function render_upgrade_key() { + $plugin_names = $this->get_formatted_plugin_names( self::UPGRADE_KEY ); + + if ( empty( $plugin_names ) ) { + return; + } + + $prompt = sprintf( _n( + 'You have a license key for %1$s but the key is out of installs. %2$sVisit the Events Calendar website%3$s to manage your installs, upgrade your license, or purchase a new one.', + 'You have license keys for %1$s but your keys are out of installs. %2$sVisit the Events Calendar website%3$s to manage your installs, upgrade your licenses, or purchase new ones.', count( $this->notices[ self::UPGRADE_KEY ] ), + 'tribe-common' + ), + $plugin_names, + '', + '' + ); + + $this->render_notice( 'pue_key-' . self::UPGRADE_KEY, "

          $prompt

          " ); + } + + /** + * Renders the notice itself (the provided HTML will be wrapped in a suitable container div). + * + * @param string $slug + * @param string $inner_html + */ + protected function render_notice( $slug, $inner_html ) { + + // Enqueue the notice CSS. + tribe( 'assets' )->enqueue( [ 'tribe-common-admin' ] ); + + $mascot = esc_url( Tribe__Main::instance()->plugin_url . 'src/resources/images/mascot.png' ); + + $html = + '
          +
          + +
          +
          ' . $inner_html . '
          +
          '; + + Tribe__Admin__Notices::instance()->render( $slug, $html, false ); + } + + /** + * @return string + */ + protected function find_your_key_text() { + return sprintf( + __( 'You can always check the status of your licenses by logging in to %1$syour account on theeventscalendar.com%2$s.', 'tribe-common' ), + '', + '' + ); + } + + /** + * Transforms a list of plugins into human readable string. + * + * Examples of output: + * + * # One name + * "Ticket Pro" + * + * # Two names + * "Ticket Pro and Calendar Legend" + * + * # Three names + * "Ticket Pro, Calendar Legend and Date Stars" + * + * + * @since 4.9.12 + * + * @param array|string $plugins Array of plugin classes. + * + * @return string|false + */ + public function get_formatted_plugin_names_from_classes( $plugins ) { + $plugin_list = []; + + foreach ( (array) $plugins as $class_name ) { + $pue = tribe( Tribe__Dependency::class )->get_pue_from_class( $class_name ); + + if ( ! $pue ) { + continue; + } + + if ( ! isset( $this->plugin_names[ $pue->pue_install_key ] ) ) { + continue; + } + + $plugin_list[] = $this->plugin_names[ $pue->pue_install_key ]; + } + + $num_plugins = count( $plugin_list ); + + if ( 0 === $num_plugins ) { + return false; + } + + if ( 1 === $num_plugins ) { + $html = current( $plugin_list ); + } elseif ( 1 < $num_plugins ) { + $all_but_last = join( ', ', array_slice( $plugin_list, 0, count( $plugin_list ) - 1 ) ); + $last = current( array_slice( $plugin_list, count( $plugin_list ) - 1, 1 ) ); + $html = sprintf( _x( '%1$s and %2$s', 'formatted plugin list', 'tribe-common' ), $all_but_last, $last ); + } + + return '' . $html . ''; + } + + /** + * Transforms the array referenced by group into a human readable, + * comma delimited list. + * + * Examples of output: + * + * # One name + * "Ticket Pro" + * + * # Two names + * "Ticket Pro and Calendar Legend" + * + * # Three names + * "Ticket Pro, Calendar Legend and Date Stars" + * + * # Fallback + * "Unknown Plugin(s)" + * + * @param string $group + * + * @return string + */ + protected function get_formatted_plugin_names( $group ) { + if ( ! count( $this->notices[ $group ] ) ) { + return ''; + } + + $plugin_list = array_intersect( $this->registered, array_keys( $this->notices[ $group ] ) ); + $num_plugins = count( $plugin_list ); + + if ( 0 === $num_plugins ) { + return ''; + } elseif ( 1 === $num_plugins ) { + $html = current( $plugin_list ); + } elseif ( 1 < $num_plugins ) { + $all_but_last = join( ', ', array_slice( $plugin_list, 0, count( $plugin_list ) - 1 ) ); + $last = current( array_slice( $plugin_list, count( $plugin_list ) - 1, 1 ) ); + $html = sprintf( _x( '%1$s and %2$s', 'formatted plugin list', 'tribe-common' ), $all_but_last, $last ); + } + + return '' . $html . ''; + } +} diff --git a/tribe-common/src/Tribe/PUE/Package_Handler.php b/tribe-common/src/Tribe/PUE/Package_Handler.php new file mode 100644 index 0000000000..960d471f56 --- /dev/null +++ b/tribe-common/src/Tribe/PUE/Package_Handler.php @@ -0,0 +1,157 @@ +filesystem = $wp_filesystem; + } + + /** + * @return Tribe__PUE__Package_Handler + */ + public static function instance() { + if ( empty( self::$instance ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Filters the package download step to store the downloaded file with a shorter file name. + * + * @param bool $reply Whether to bail without returning the package. + * Default false. + * @param string $package The package file name or URL. + * @param WP_Upgrader $upgrader The WP_Upgrader instance. + */ + public function filter_upgrader_pre_download( $reply, $package, WP_Upgrader $upgrader ) { + if ( $this->is_mt_package( $package ) ) { + $this->upgrader = $upgrader; + + return $this->download( $package ); + } + + return $reply; + } + + /** + * Whether the current package is an MT plugin package or not. + * + * @param string $package The package file name or URL. + * + * @return bool + */ + protected function is_mt_package( $package ) { + if ( + empty( $package ) + || ! preg_match( '!^(http|https|ftp)://!i', $package ) + ) { + return false; + } + + $query_vars = parse_url( $package, PHP_URL_QUERY ); + + if ( empty( $query_vars ) ) { + return false; + } + + wp_parse_str( $query_vars, $parsed ); + + return isset( $parsed['pu_get_download'] ) && $parsed['pu_get_download'] == 1; + } + + /** + * A mimic of the `WP_Upgrader::download_package` method that adds a step to store the temp file with a shorter + * file name. + * + * @see WP_Upgrader::download_package() + * + * @param string $package The URI of the package. If this is the full path to an + * existing local file, it will be returned untouched. + * + * @return string|WP_Error The full path to the downloaded package file, or a WP_Error object. + */ + protected function download( $package ) { + if ( empty( $this->filesystem ) ) { + // try to connect + $this->upgrader->fs_connect( [ WP_CONTENT_DIR, WP_PLUGIN_DIR ] ); + + global $wp_filesystem; + + // still empty? + if ( empty( $wp_filesystem ) ) { + // bail + return false; + } + + $this->filesystem = $wp_filesystem; + } + + $this->upgrader->skin->feedback( 'downloading_package', $package ); + + $download_file = download_url( $package ); + + if ( is_wp_error( $download_file ) ) { + return new WP_Error( 'download_failed', $this->upgrader->strings['download_failed'], + $download_file->get_error_message() ); + } + + $file = $this->get_short_filename( $download_file ); + + $moved = $this->filesystem->move( $download_file, $file ); + + if ( empty( $moved ) ) { + // we tried, we failed, we bail and let WP do its job + return false; + } + + return $file; + } + + /** + * Returns the absolute path to a shorter filename version of the original download temp file. + * + * The path will point to the same temp dir (WP handled) but shortening the filename to a + * 6 chars hash to cope with OSes limiting the max number of chars in a file path. + * The original filename would be a sanitized version of the URL including query args. + * + * @param string $download_file The absolute path to the original download file. + * + * @return string The absolute path to a shorter name version of the downloaded file. + */ + protected function get_short_filename( $download_file ) { + $extension = pathinfo( $download_file, PATHINFO_EXTENSION ); + $filename = substr( md5( $download_file ), 0, 5 ); + $file = dirname( $download_file ) . '/' . $filename . '.' . $extension; + + return $file; + } +} diff --git a/tribe-common/src/Tribe/PUE/Plugin_Info.php b/tribe-common/src/Tribe/PUE/Plugin_Info.php new file mode 100755 index 0000000000..a3dc71592b --- /dev/null +++ b/tribe-common/src/Tribe/PUE/Plugin_Info.php @@ -0,0 +1,141 @@ +results ) ) { + $apiResponse = current( $apiResponse->results ); + } + + if ( empty( $apiResponse ) || ! is_object( $apiResponse ) ) { + return null; + } + + //Very, very basic validation. + $valid = ( isset( $apiResponse->name ) && ! empty( $apiResponse->name ) && isset( $apiResponse->version ) && ! empty( $apiResponse->version ) ) || ( isset( $apiResponse->api_invalid ) || isset( $apiResponse->no_api ) ); + if ( ! $valid ) { + return null; + } + + $info = new Tribe__PUE__Plugin_Info(); + + foreach ( get_object_vars( $apiResponse ) as $key => $value ) { + $key = str_replace( 'plugin_', '', $key ); // let's strip out the "plugin_" prefix we've added in plugin-updater-classes. + $info->$key = $value; + } + + return $info; + } + + /** + * Transform plugin info into the format used by the native WordPress.org API + * + * @return object + */ + public function to_wp_format() { + $info = new StdClass; + + // The custom update API is built so that many fields have the same name and format + // as those returned by the native WordPress.org API. These can be assigned directly. + $sameFormat = [ + 'name', + 'slug', + 'version', + 'requires', + 'tested', + 'rating', + 'upgrade_notice', + 'num_ratings', + 'downloaded', + 'homepage', + 'last_updated', + 'api_expired', + 'api_upgrade', + 'api_invalid', + ]; + + foreach ( $sameFormat as $field ) { + if ( isset( $this->$field ) ) { + $info->$field = $this->$field; + } else { + $info->$field = null; + } + } + + //Other fields need to be renamed and/or transformed. + $info->download_link = $this->download_url; + + if ( ! empty( $this->author_homepage ) ) { + $info->author = sprintf( '%s', esc_url( $this->author_homepage ), $this->author ); + } else { + $info->author = $this->author; + } + + if ( is_object( $this->sections ) ) { + $info->sections = get_object_vars( $this->sections ); + } elseif ( is_array( $this->sections ) ) { + $info->sections = $this->sections; + } else { + $info->sections = [ 'description' => '' ]; + } + + return $info; + } + } +} diff --git a/tribe-common/src/Tribe/PUE/Update_Prevention.php b/tribe-common/src/Tribe/PUE/Update_Prevention.php new file mode 100644 index 0000000000..c5164b44f6 --- /dev/null +++ b/tribe-common/src/Tribe/PUE/Update_Prevention.php @@ -0,0 +1,199 @@ + version ] or empty if it didn't find it. + */ + public function get_dependencies( $content ) { + $regex = "/'(?[^']*)'(?:[^']*)'(?[^']*)',/"; + + if ( ! preg_match_all( $regex, $content, $matches ) ) { + return []; + } + + $dependencies = array_combine( $matches['plugin'], $matches['version'] ); + + return $dependencies; + } + + /** + * Checks for the list of constants associate with plugin to make sure we are dealing + * with a plugin owned by The Events Calendar. + * + * @since 4.9.12 + * + * @param string $plugin Plugin file partial path, folder and main php file. + * + * @return bool + */ + public function is_tribe_plugin( $plugin ) { + $path_constants_list = [ + // The Events Calendar + 'TRIBE_EVENTS_FILE', + + // Events Pro + 'EVENTS_CALENDAR_PRO_FILE', + + // Filter bar + 'TRIBE_EVENTS_FILTERBAR_FILE', + + // Eventbrite Tickets + 'EVENTBRITE_PLUGIN_FILE', + ]; + + foreach ( $path_constants_list as $constant_name ) { + if ( ! defined( $constant_name ) ) { + continue; + } + + if ( false === strpos( constant( $constant_name ), $plugin ) ) { + continue; + } + + return true; + } + + return false; + } + + /** + * Filters the source file location for the upgrade package for the PUE Update_Prevention engine. + * + * @since 4.9.12 + * + * @param string $source File source location. + * @param string $remote_source Remote file source location. + * @param WP_Upgrader $upgrader WP_Upgrader instance. + * @param array $extra Extra arguments passed to hooked filters. + */ + public function filter_upgrader_source_selection( $source, $remote_source, $upgrader, $extras ) { + if ( ! isset( $extras['plugin'] ) ) { + return $source; + } + + $plugin = $extras['plugin']; + + // Bail if we are not dealing with a plugin we own. + if ( ! $this->is_tribe_plugin( $plugin ) ) { + return $source; + } + + $register_path = $source . '/src/Tribe/Plugin_Register.php'; + + // Bail when the Plugin Register file doesn't exist. + if ( ! file_exists( $register_path ) ) { + return $source; + } + + $register_contents = file_get_contents( $register_path ); + + $dependencies = $this->get_dependencies( $register_contents ); + $incompatible_plugins = []; + + foreach ( $dependencies as $class_name => $required_version ) { + // Skip inactive plugin checks. + if ( ! class_exists( $class_name ) ) { + continue; + } + + $constant_name = $class_name . '::VERSION'; + + // Skip if we can't find the version constant. + if ( ! defined( $constant_name ) ) { + continue; + } + + $current_version = constant( $constant_name ); + + // Skip when the version is equal or higher than the required. + if ( version_compare( $current_version, $required_version, '>=' ) ) { + continue; + } + + $pue = tribe( Dependency::class )->get_pue_from_class( $class_name ); + $has_pue_notice = $pue ? tribe( 'pue.notices' )->has_notice( $pue->pue_install_key ) : false; + + // Only throw warning for customers with notices of invalid/expired licenses. + if ( ! $has_pue_notice ) { + continue; + } + + // Flag that we should prevent the Update + $incompatible_plugins[ $class_name ] = $required_version; + } + + // Bail when there are no incompatible plugins. + if ( empty( $incompatible_plugins ) ) { + return $source; + } + + /** + * Filter the if we should prevent the update. + * + * @since 4.9.12 + * + * @param bool $should_revent Flag false to skip the prevention. + * @param array $incompatible_plugins Which plugins were incompatible with new version of the plugin. + * @param string $source File source location. + * @param string $remote_source Remote file source location. + * @param WP_Upgrader $upgrader WP_Upgrader instance. + * @param array $extra Extra arguments passed to hooked filters. + */ + $should_prevent_update = apply_filters( + 'tribe_pue_should_prevent_update_without_license', + true, + $incompatible_plugins, + $source, + $remote_source, + $upgrader, + $extras + ); + + // Bail if the filter above returns anything but true. + if ( true !== $should_prevent_update ) { + return $source; + } + + $full_plugin_path = $remote_source . '/' . $plugin; + $plugin_data = get_plugin_data( $full_plugin_path ); + + $plugins_classes = array_keys( $incompatible_plugins ); + $plugins_list_html = tribe( 'pue.notices' )->get_formatted_plugin_names_from_classes( $plugins_classes ); + + $link_read_more = '' . esc_html__( 'Read more', 'tribe-common' ) . '.'; + + $message = sprintf( + esc_html__( 'Your update failed due to an incompatibility between the version (%1$s) of the %2$s you tried to update to and the version of %3$s that you are using. %4$s', 'tribe-common' ), + esc_html( $plugin_data['Version'] ), + esc_html( $plugin_data['Name'] ), + $plugins_list_html, + $link_read_more + ); + + $error = new WP_Error( + 'tribe-updater-failed-prevention', + $message, + [] + ); + + return $error; + } +} diff --git a/tribe-common/src/Tribe/PUE/Utility.php b/tribe-common/src/Tribe/PUE/Utility.php new file mode 100755 index 0000000000..07b6bbf5d8 --- /dev/null +++ b/tribe-common/src/Tribe/PUE/Utility.php @@ -0,0 +1,126 @@ +$field ) ) { + continue; + } + + $update->$field = $info->$field; + } + + return $update; + } + + /** + * Transform the update into the format used by WordPress native plugin API. + * + * @return object + */ + public function to_wp_format() { + $update = new StdClass; + + $update->id = $this->id; + $update->plugin = $this->plugin; + $update->slug = $this->slug; + $update->new_version = $this->version; + $update->url = $this->homepage; + $update->package = $this->download_url; + if ( ! empty( $this->upgrade_notice ) ) { + $update->upgrade_notice = $this->upgrade_notice; + } + + // Support custom $update properties coming straight from PUE + if ( ! empty( $this->custom_update ) ) { + $custom_update = get_object_vars( $this->custom_update ); + + foreach ( $custom_update as $field => $custom_value ) { + if ( is_object( $custom_value ) ) { + $custom_value = get_object_vars( $custom_value ); + } + + $update->$field = $custom_value; + } + } + + return $update; + } + } +} diff --git a/tribe-common/src/Tribe/Plugin_Meta_Links.php b/tribe-common/src/Tribe/Plugin_Meta_Links.php new file mode 100644 index 0000000000..48269df78f --- /dev/null +++ b/tribe-common/src/Tribe/Plugin_Meta_Links.php @@ -0,0 +1,147 @@ + Plugins list + */ +class Tribe__Plugin_Meta_Links { + /** + * Class instance + * + * @var Tribe__Plugin_Meta_Links The singleton instance. + */ + private static $instance; + + /** + * The various meta links that will be added + * + * @var array { + * Each plugin that will be filtered. + * + * @type array $plugin_basename { + * Meta links added to this plugin. + * + * @type array { + * Each individual link. + * + * @type string $html The full HTML for this link. + * @type bool $remove Whether we are adding or removing this link. + * } + * } + * } + */ + private $meta_links = []; + + /** + * Returns the singleton instance of this class. + * + * @return Tribe__Plugin_Meta_Links instance. + */ + public static function instance() { + return null === self::$instance ? new self() : self::$instance; + } + + private function __construct() { + add_action( 'plugin_row_meta', [ $this, 'filter_meta_links' ], 10, 2 ); + } + + /** + * Adds an link to the meta list + * + * @param string $plugin Path to plugin file. + * @param string $text Inner text for HTML element. + * @param string $href URL for the link. + * @param array $attributes Key => value attributes for element. + */ + public function add_link( $plugin, $title, $href, $attributes = [] ) { + $attributes['href'] = $href; + + // Build the element. + $html = ' $val ) { + $html .= ' ' . $att . '="' . esc_attr( $val ) . '"'; + } + + $html .= '>' . esc_html( $title ) . ''; + + $this->set( $plugin, $html, false ); + } + + /** + * Adds or removes the specified HTML link + * + * @param string $plugin Path to plugin file. + * @param string $html Full HTML for this link. + * @param bool $remove Whether to add this HTML/link or match and remove it. + */ + public function set( $plugin, $html, $remove = false ) { + $basename = plugin_basename( $plugin ); + + // Get any current links for this plugin. + $cur_links = Tribe__Utils__Array::get( $this->meta_links, $basename, [] ); + + $cur_links[] = [ + 'html' => $html, + 'remove' => $remove, + ]; + + $this->meta_links = Tribe__Utils__Array::set( $this->meta_links, $basename, $cur_links ); + } + + /** + * Filters meta links on the plugins list page + * + * @param array $links The current plugin's links. + * @param string $basename The plugin currently being filtered. + * + * @return array Filtered action links array. + */ + public function filter_meta_links( $links, $basename ) { + // Gets any links that are set for this plugin, defaults to an empty array. + $set_links = Tribe__Utils__Array::get( $this->meta_links, $basename, [] ); + + foreach ( $set_links as $link ) { + + if ( true === $link['remove'] ) { + // Remove a link. + $pos = array_search( $link['html'], $links ); + + if ( false !== $pos ) { + unset( $links[ $pos ] ); + } + } else { + // Add a link. + $links[] = $link['html']; + } + } + + return $links; + } + + /** + * Prevent cloning the singleton with 'clone' operator + * + * @return void + */ + final private function __clone() { + _doing_it_wrong( + __FUNCTION__, + 'Can not use this method on singletons.', + '4.3' + ); + } + + /** + * Prevent unserializing the singleton instance + * + * @return void + */ + final private function __wakeup() { + _doing_it_wrong( + __FUNCTION__, + 'Can not use this method on singletons.', + '4.3' + ); + } +} diff --git a/tribe-common/src/Tribe/Plugins.php b/tribe-common/src/Tribe/Plugins.php new file mode 100644 index 0000000000..a790a45ec4 --- /dev/null +++ b/tribe-common/src/Tribe/Plugins.php @@ -0,0 +1,167 @@ + Common name for the plugin, used in places such as WP Admin messages + * 'class' => Main plugin class + * 'thickbox_url' => Download or purchase URL for plugin from within /wp-admin/ thickbox + * ] + */ + private $tribe_plugins = [ + [ + 'short_name' => 'Event Tickets', + 'class' => 'Tribe__Tickets__Main', + 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=event-tickets&TB_iframe=true', + ], + [ + 'short_name' => 'Event Tickets Plus', + 'class' => 'Tribe__Tickets_Plus__Main', + 'thickbox_url' => 'https://theeventscalendar.com/product/wordpress-event-tickets-plus/?TB_iframe=true', + ], + [ + 'short_name' => 'The Events Calendar', + 'class' => 'Tribe__Events__Main', + 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=the-events-calendar&TB_iframe=true', + ], + [ + 'short_name' => 'Events Calendar Pro', + 'class' => 'Tribe__Events__Pro__Main', + 'thickbox_url' => 'https://theeventscalendar.com/product/wordpress-events-calendar-pro/?TB_iframe=true', + ], + [ + 'short_name' => 'Community Events', + 'class' => 'Tribe__Events__Community__Main', + 'thickbox_url' => 'https://theeventscalendar.com/product/wordpress-community-events/?TB_iframe=true', + ], + [ + 'short_name' => 'Community Tickets', + 'class' => 'Tribe__Events__Community__Tickets__Main', + 'thickbox_url' => 'https://theeventscalendar.com/product/community-tickets/?TB_iframe=true', + ], + [ + 'short_name' => 'Filter Bar', + 'class' => 'Tribe__Events__Filterbar__View', + 'thickbox_url' => 'https://theeventscalendar.com/product/wordpress-events-filterbar/?TB_iframe=true', + ], + [ + 'short_name' => 'Facebook Events', + 'class' => 'Tribe__Events__Facebook__Importer', + 'thickbox_url' => 'https://theeventscalendar.com/product/facebook-events/?TB_iframe=true', + ], + [ + 'short_name' => 'iCal Importer', + 'class' => 'Tribe__Events__Ical_Importer__Main', + 'thickbox_url' => 'https://theeventscalendar.com/product/ical-importer/?TB_iframe=true', + ], + [ + 'short_name' => 'Eventbrite Tickets', + 'class' => 'Tribe__Events__Tickets__Eventbrite__Main', + 'thickbox_url' => 'https://theeventscalendar.com/product/wordpress-eventbrite-tickets/?TB_iframe=true', + ], + [ + 'short_name' => 'Advanced Post Manager', + 'class' => 'Tribe_APM', + 'thickbox_url' => 'plugin-install.php?tab=plugin-information&plugin=advanced-post-manager&TB_iframe=true', + ], + ]; + + /** + * Searches the plugin list for key/value pair and return the full details for that plugin + * + * @param string $search_key The array key this value will appear in + * @param string $search_val The value itself + * + * @return array|null + */ + public function get_plugin_by_key( $search_key, $search_val ) { + foreach ( $this->get_list() as $plugin ) { + if ( isset( $plugin[ $search_key ] ) && $plugin[ $search_key ] === $search_val ) { + return $plugin; + } + } + + return null; + } + + /** + * Retrieves plugins details by plugin name + * + * @param string $name Common name for the plugin, not necessarily the lengthy name in the WP Admin Plugins list + * + * @return array|null + */ + public function get_plugin_by_name( $name ) { + return $this->get_plugin_by_key( 'short_name', $name ); + } + + /** + * Retrieves plugins details by class name + * + * @param string $main_class Main/base class for this plugin + * + * @return array|null + */ + public function get_plugin_by_class( $main_class ) { + return $this->get_plugin_by_key( 'class', $main_class ); + } + + /** + * Retrieves the entire list + * + * @return array + */ + public function get_list() { + /** + * Gives an opportunity to filter the list of tribe plugins + * + * @since 4.7.18 + * + * @param array Contains a list of all tribe plugins + */ + return apply_filters( 'tribe_plugins_get_list', $this->tribe_plugins ); + } + + /** + * Checks if given plugin is active. Usually a The Events Calendar plugin. + * + * @param string $plugin_name The name of the plugin. Each plugin defines their name upon hooking on the filter. + * + * @since 4.12.1 + * + * @return bool True if plugin is active. False if plugin is not active. + */ + public static function is_active( $plugin_name ) { + if ( ! did_action( "plugins_loaded" ) ) { + _doing_it_wrong( + __METHOD__, + __( 'Using this function before "plugins_loaded" action has fired can return unreliable results.', 'tribe-common' ), + '4.12.6' + ); + } + + /** + * Filters the array that each Tribe plugin overrides to + * set itself as active when this function is called. + * + * @example [ 'the-events-calendar' => true, 'event-tickets' => true ] + * + * @since 4.12.1 + * + * @return array Plugin slugs as keys and bool as value for whether it's active or not. + */ + $plugins = apply_filters( 'tribe_active_plugins', [] ); + + return isset( $plugins[ $plugin_name ] ) && tribe_is_truthy( $plugins[ $plugin_name ] ); + } + } +} diff --git a/tribe-common/src/Tribe/Plugins_API.php b/tribe-common/src/Tribe/Plugins_API.php new file mode 100644 index 0000000000..27e57a4a47 --- /dev/null +++ b/tribe-common/src/Tribe/Plugins_API.php @@ -0,0 +1,233 @@ + [ + 'title' => __( 'The Events Calendar', 'tribe-common' ), + 'slug' => 'the-events-calendar', + 'link' => 'https://evnt.is/1ai-', + 'description' => __( 'Our flagship free calendar', 'tribe-common' ), + 'features' => [ + __( 'Customizable', 'tribe-common' ), + __( 'Import & export events', 'tribe-common' ), + __( 'Timezone support', 'tribe-common' ), + __( 'Multiple views', 'tribe-common' ), + ], + 'image' => 'images/shop/calendar.jpg', + 'logo' => 'images/logo/the-events-calendar.svg', + 'is_installed' => class_exists( 'Tribe__Events__Main' ), + 'free' => true, + 'active_installs' => 800000, + ], + 'event-aggregator' => [ + 'title' => __( 'Event Aggregator', 'tribe-common' ), + 'slug' => 'event-aggregator', + 'link' => 'https://evnt.is/1aj0', + 'description' => __( 'Automated imports for your calendar', 'tribe-common' ), + 'features' => [ + __( 'Schedule automated imports', 'tribe-common' ), + __( 'Customizable', 'tribe-common' ), + __( 'Works with Google Calendar, Meetup, and more', 'tribe-common' ), + __( 'Refine by date, location, or keyword', 'tribe-common' ), + ], + 'image' => 'images/shop/aggregator.jpg', + 'logo' => 'images/logo/event-aggregator.svg', + 'is_installed' => class_exists( 'Tribe__Events__Aggregator' ) && Tribe__Events__Aggregator::is_service_active(), + 'free' => false, + 'active_installs' => 20000, + ], + 'events-calendar-pro' => [ + 'title' => __( 'Events Calendar Pro', 'tribe-common' ), + 'slug' => 'events-calendar-pro', + 'link' => 'https://evnt.is/1ai-', + 'description' => __( 'Power up your calendar with Pro', 'tribe-common' ), + 'features' => [ + __( 'Premium support', 'tribe-common' ), + __( 'Recurring events', 'tribe-common' ), + __( 'Additional views', 'tribe-common' ), + __( 'Shortcodes', 'tribe-common' ), + ], + 'image' => 'images/shop/pro.jpg', + 'logo' => 'images/logo/events-calendar-pro.svg', + 'is_installed' => class_exists( 'Tribe__Events__Pro__Main' ), + 'free' => false, + 'active_installs' => 100000, + ], + 'event-tickets' => [ + 'title' => __( 'Event Tickets', 'tribe-common' ), + 'slug' => 'event-tickets', + 'link' => 'https://evnt.is/1aj1', + 'description' => __( 'Manage ticketing and RSVPs', 'tribe-common' ), + 'features' => [ + __( 'Add tickets and RSVP to any post', 'tribe-common' ), + __( 'Paypal integration', 'tribe-common' ), + __( 'Attendee reports', 'tribe-common' ), + __( 'Customizable ticket template', 'tribe-common' ), + ], + 'image' => 'images/shop/tickets.jpg', + 'logo' => 'images/logo/event-tickets.svg', + 'is_installed' => class_exists( 'Tribe__Tickets__Main' ), + 'free' => true, + 'active_installs' => 20000, + ], + 'event-tickets-plus' => [ + 'title' => __( 'Event Tickets Plus', 'tribe-common' ), + 'slug' => 'event-tickets-plus', + 'link' => 'http://evnt.is/1aj1', + 'description' => __( 'Monetize your events', 'tribe-common' ), + 'features' => [ + __( 'Custom registration fields', 'tribe-common' ), + __( 'WooCommerce compatibility', 'tribe-common' ), + __( 'Ticket scanning with mobile app', 'tribe-common' ), + __( 'Custom attendee registration fields', 'tribe-common' ), + ], + 'image' => 'images/shop/tickets-plus.jpg', + 'logo' => 'images/logo/event-tickets-plus.svg', + 'is_installed' => class_exists( 'Tribe__Tickets_Plus__Main' ), + 'free' => false, + 'active_installs' => 10000, + ], + 'promoter' => [ + 'title' => __( 'Promoter', 'tribe-common' ), + 'slug' => 'promoter', + 'link' => 'https://evnt.is/1acy', + 'description' => __( 'An email marketing solution for events and the people running them', 'tribe-common' ), + 'features' => [ + __( 'Automate email touchpoints', 'tribe-common' ), + __( 'Customize email templates', 'tribe-common' ), + __( 'Streamline your email process', 'tribe-common' ), + __( 'Segment your attendee lists', 'tribe-common' ), + ], + 'image' => 'images/shop/promoter.jpg', + 'logo' => 'images/logo/promoter.svg', + 'is_installed' => tribe( 'promoter.pue' )->has_license_key(), + 'free' => false, + 'active_installs' => 1000, + ], + 'tribe-filterbar' => [ + 'title' => __( 'Filter Bar', 'tribe-common' ), + 'slug' => 'tribe-filterbar', + 'link' => 'https://evnt.is/19o6', + 'description' => __( 'Help users find exactly the right event', 'tribe-common' ), + 'features' => [ + __( 'Configurable set of filters', 'tribe-common' ), + __( 'Horizontal or vertical', 'tribe-common' ), + __( 'Filter category, price, and more', 'tribe-common' ), + __( 'Filter distance (for Events Calendar Pro)', 'tribe-common' ), + ], + 'image' => 'images/shop/filter-bar.jpg', + 'logo' => 'images/logo/filterbar.svg', + 'is_installed' => class_exists( 'Tribe__Events__Filterbar__View' ), + 'free' => false, + 'active_installs' => 20000, + ], + 'events-community' => [ + 'title' => __( 'Community Events', 'tribe-common' ), + 'slug' => 'events-community', + 'link' => 'https://evnt.is/19o7', + 'description' => __( 'Users submit events to your calendar', 'tribe-common' ), + 'features' => [ + __( 'Publishing Control', 'tribe-common' ), + __( 'Event Submission Form', 'tribe-common' ), + __( 'Registered User Settings', 'tribe-common' ), + __( 'Email notifications', 'tribe-common' ), + ], + 'image' => 'images/shop/community.jpg', + 'logo' => 'images/logo/community-events.svg', + 'is_installed' => class_exists( 'Tribe__Events__Community__Main' ), + 'free' => false, + 'active_installs' => 20000, + ], + 'events-community-tickets' => [ + 'title' => __( 'Community Tickets', 'tribe-common' ), + 'slug' => 'events-community-tickets', + 'link' => 'https://evnt.is/19o8', + 'description' => __( 'Run your own events marketplace', 'tribe-common' ), + 'features' => [ + __( 'Users submit events and sell tickets', 'tribe-common' ), + __( 'Split commission with users', 'tribe-common' ), + __( 'No admin access required', 'tribe-common' ), /* code review: fail this */ + __( 'Sales reporting', 'tribe-common' ), + ], + 'requires' => _x( 'Event Tickets Plus and Community Events', 'Names of required plugins for Community Tickets', 'tribe-common' ), + 'image' => 'images/shop/community-tickets.jpg', + 'logo' => 'images/logo/community-tickets.svg', + 'is_installed' => class_exists( 'Tribe__Events__Community__Tickets__Main' ), + 'free' => false, + 'active_installs' => 10000, + ], + 'tribe-eventbrite' => [ + 'title' => __( 'Eventbrite Tickets', 'tribe-common' ), + 'slug' => 'tribe-eventbrite', + 'link' => 'https://evnt.is/19o9', + 'description' => __( 'Unite the power of TEC with the ticketing of Eventbrite', 'tribe-common' ), + 'features' => [ + __( 'Manage tickets from WordPress', 'tribe-common' ), + __( 'Ticket availability automatically updates', 'tribe-common' ), + __( 'Integrated with your events on Eventbrite', 'tribe-common' ), + __( 'Automatically import your events', 'tribe-common' ), + ], + 'image' => 'images/shop/eventbrite.jpg', + 'logo' => 'images/logo/eventbrite-tickets.svg', + 'is_installed' => class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' ), + 'free' => false, + 'active_installs' => 20000, + ], + 'image-widget-plus' => [ + 'title' => __( 'Image Widget Plus', 'tribe-common' ), + 'slug' => 'image-widget-plus', + 'link' => 'https://evnt.is/19nv', + 'description' => __( 'Beautiful display options for your favorite photos.', 'tribe-common' ), + 'features' => [ + __( 'Multi-Image Support', 'tribe-common' ), + __( 'Lightbox', 'tribe-common' ), + __( 'Slideshow', 'tribe-common' ), + __( 'Random Images', 'tribe-common' ), + ], + 'image' => 'images/shop/image-widget-plus.jpg', + 'logo' => 'images/logo/image-widget-plus.svg', + 'is_installed' => class_exists( 'Tribe__Image__Plus__Main' ), + 'free' => false, + 'active_installs' => 2500, + ], + 'events-virtual' => [ + 'title' => __( 'Virtual Events', 'tribe-common' ), + 'slug' => 'events-virtual', + 'link' => 'http://evnt.is/virtual-events', + 'description' => __( 'Features to optimize your calendar for virtual events.', 'tribe-common' ), + 'features' => [ + __( 'Zoom integration', 'tribe-common' ), + __( 'Virtual event labels', 'tribe-common' ), + __( 'Status control for canceled or postponed events', 'tribe-common' ), + __( 'Embed livestreams and videos', 'tribe-common' ), + ], + 'image' => 'images/shop/virtual-events.jpg', + 'logo' => 'images/logo/virtual-events.svg', + 'is_installed' => defined( 'EVENTS_VIRTUAL_FILE' ), + 'free' => false, + 'active_installs' => 2500, + ], + ]; + + return $products; + } +} diff --git a/tribe-common/src/Tribe/Post_History.php b/tribe-common/src/Tribe/Post_History.php new file mode 100644 index 0000000000..fc21e25b84 --- /dev/null +++ b/tribe-common/src/Tribe/Post_History.php @@ -0,0 +1,134 @@ +post_id = $post_id; + } + + /** + * Records a new history entry for the current post. + * + * @param string $message + * @param array $data + */ + public function add_entry( $message, array $data = [] ) { + $datetime = current_time( 'mysql' ); + $checksum = uniqid( substr( hash( 'md5', $datetime . $message . serialize( $data ) ), 0, 8 ) . '_' ); + + $log_entry = wp_slash( json_encode( [ + 'datetime' => $datetime, + 'message' => $message, + 'data' => $data, + 'checksum' => $checksum, + ] ) ); + + add_post_meta( $this->post_id, self::HISTORY_KEY, $log_entry ); + } + + /** + * Indicates if any history exists for the current post. + * + * @return bool + */ + public function has_entries() { + $first_available_entry = get_post_meta( $this->post_id, self::HISTORY_KEY, true ); + return ! empty( $first_available_entry ); + } + + /** + * Returns all historical records for the current post as an array + * of objects, each object taking the form: + * + * { + * "datetime": "yyyy-mm-dd hh:ii:ss", + * "message": "...", + * "data": [] + * } + * + * @return array + */ + public function get_entries() { + $entries = []; + + foreach ( get_post_meta( $this->post_id, self::HISTORY_KEY ) as $log_entry ) { + $log_entry = json_decode( $log_entry ); + + if ( ! $log_entry ) { + continue; + } + + $entries[] = $log_entry; + } + + return $entries; + } + + /** + * Deletes all entries for the current post that match the provided datetime + * string and (optionally) also match the provided checksum. + * + * Returns the total number of deleted entries, which may be zero if none were matched; + * can also be more than one if multiple entries were logged at the same time and no + * checksum is provided. + * + * @param string $datetime + * @param string $checksum optional value to more precisely specify the entry to be deleted + * + * @return int + */ + public function delete_entry( $datetime, $checksum = null ) { + $deleted = 0; + + foreach ( $this->get_entries() as $entry ) { + if ( $entry->datetime !== $datetime ) { + continue; + } + + if ( null !== $checksum && $entry->checksum !== $checksum ) { + continue; + } + + if ( delete_post_meta( $this->post_id, self::HISTORY_KEY, json_encode( $entry ) ) ) { + $deleted++; + } + } + + return $deleted; + } +} diff --git a/tribe-common/src/Tribe/Post_Transient.php b/tribe-common/src/Tribe/Post_Transient.php new file mode 100644 index 0000000000..65655ffa77 --- /dev/null +++ b/tribe-common/src/Tribe/Post_Transient.php @@ -0,0 +1,214 @@ +ID; + } + + if ( has_filter( 'tribe_pre_post_meta_transient_' . $transient ) ) { + /** + * Attach an action before getting the new Transient + * + * @since 4.1 + * + * @param int $post_id Post ID + * @param string $transient The Post Meta Key + */ + $pre = apply_filters( 'tribe_pre_post_meta_transient_' . $transient, $post_id, $transient ); + if ( false !== $pre ) { + return $pre; + } + } + + if ( $_wp_using_ext_object_cache ) { + $value = wp_cache_get( "tribe_{$transient}-{$post_id}", "tribe_post_meta_transient-{$post_id}" ); + } else { + $meta_timeout = '_transient_timeout_' . $transient; + $meta = '_transient_' . $transient; + $value = get_post_meta( $post_id, $meta, false ); + + // if there aren't any values, communicate that it did not fetch data from post transient + if ( ! is_array( $value ) || 0 === count( $value ) ) { + return false; + } + + // grab the first value, because that's all we care about + $value = current( $value ); + + if ( $value && ! defined( 'WP_INSTALLING' ) ) { + if ( get_post_meta( $post_id, $meta_timeout, true ) < time() ) { + $this->delete( $post_id, $transient ); + + return false; + } + } + } + + /** + * Attach an action after getting the new Transient + * + * @since 4.1 + * + * @param int $post_id Post ID + * @param string $transient The Post Meta Key + */ + return has_filter( 'tribe_post_meta_transient_' . $transient ) + ? apply_filters( 'tribe_post_meta_transient_' . $transient, $value, $post_id ) + : $value; + } + + /** + * Delete a post meta transient. + * + * @since 4.1 + * + * @param int $post_id The Post ID, can also be a WP_Post. + * @param string $transient Post Meta to Delete. + * @param string $value Only delete if the value Matches. + * + * @return boolean If we were able to delete the transient. + */ + public function delete( $post_id, $transient, $value = null ) { + global $_wp_using_ext_object_cache; + + if ( is_numeric( $post_id ) ) { + $post_id = (int) $post_id; + } else { + $post = get_post( $post_id ); + $post_id = $post->ID; + } + + /** + * Use this to pre attach an action to deleting a Post Transient + * + * @since 4.1 + * + * @param int $post_id Post ID + * @param string $transient The Post Meta Key + */ + do_action( 'tribe_delete_post_meta_transient_' . $transient, $post_id, $transient ); + + if ( $_wp_using_ext_object_cache ) { + $result = wp_cache_delete( "tribe_{$transient}-{$post_id}", "tribe_post_meta_transient-{$post_id}" ); + } else { + $meta_timeout = '_transient_timeout_' . $transient; + $meta = '_transient_' . $transient; + $result = delete_post_meta( $post_id, $meta, $value ); + if ( $result ) { + delete_post_meta( $post_id, $meta_timeout, $value ); + } + } + + if ( $result ) { + /** + * Use this to attach an Action to when the Transient is deleted + * + * @since 4.1 + * + * @param int $post_id Post ID + * @param string $transient The Post Meta Key + */ + do_action( 'tribe_deleted_post_meta_transient', $transient, $post_id, $transient ); + } + + return $result; + } + + /** + * Sets a new value for the Transient. + * + * @since 4.1 + * + * @param int $post_id The Post ID, can also be a WP_Post. + * @param string $transient Post Meta to set. + * @param string $value Only delete if the value Matches. + * @param int $expiration How long this transient will be valid, in seconds. + * + * @return int|false Meta ID on success, false on failure. + */ + public function set( $post_id, $transient, $value, $expiration = 0 ) { + global $_wp_using_ext_object_cache; + + if ( is_numeric( $post_id ) ) { + $post_id = (int) $post_id; + } else { + $post = get_post( $post_id ); + $post_id = $post->ID; + } + + $this->delete( $post_id, $transient ); + + /** + * Attach an action before setting the new Transient + * + * @since 4.1 + * + * @param int $post_id Post ID + * @param string $transient The Post Meta Key + */ + if ( has_filter( 'tribe_pre_set_post_meta_transient_' . $transient ) ) { + $value = apply_filters( 'tribe_pre_set_post_meta_transient_' . $transient, $value, $post_id, $transient ); + } + + if ( $_wp_using_ext_object_cache ) { + $result = wp_cache_set( "tribe_{$transient}-{$post_id}", $value, "tribe_post_meta_transient-{$post_id}", $expiration ); + } else { + $meta_timeout = '_transient_timeout_' . $transient; + $meta = '_transient_' . $transient; + if ( $expiration ) { + add_post_meta( $post_id, $meta_timeout, time() + $expiration, true ); + } + $result = add_post_meta( $post_id, $meta, $value, true ); + } + + if ( $result ) { + /** + * Attach an action after setting the new Transient + * + * @since 4.1 + * + * @param int $post_id Post ID + * @param string $transient The Post Meta Key + */ + do_action( 'tribe_set_post_meta_transient_' . $transient, $post_id, $transient ); + } + + return $result; + } +} diff --git a/tribe-common/src/Tribe/Process/Handler.php b/tribe-common/src/Tribe/Process/Handler.php new file mode 100644 index 0000000000..ccad1f6801 --- /dev/null +++ b/tribe-common/src/Tribe/Process/Handler.php @@ -0,0 +1,361 @@ +action = call_user_func( [ $class, 'action' ] ); + $this->identifier = $this->prefix . '_' . $this->action; + + add_action( 'wp_ajax_' . $this->identifier, [ $this, 'maybe_handle' ] ); + + /** + * Filters whether background processing should be triggered and handled on + * non-private AJAX requests as the ones triggered by a non logged in user. + * Defaults to `true` to exploit any possible chance to process. + * + * @since 4.9.5 + * + * @param bool $allow_nopriv Whether background processing should be triggered and handled on + * non-private AJAX requests or not. + * @param static $this This handler instance. + */ + $allow_nopriv = apply_filters( 'tribe_process_allow_nopriv_handling', true, $this ); + + if ( $allow_nopriv ) { + add_action( 'wp_ajax_nopriv_' . $this->identifier, [ $this, 'maybe_handle' ] ); + } + + $this->healthcheck_cron_hook_id = $this->identifier; + $this->feature_detection = tribe( 'feature-detection' ); + + /* + * This object might have been built while processing crons so + * we hook on the the object cron identifier to handle the task + * if the cron-triggered action ever fires. + */ + add_action( $this->healthcheck_cron_hook_id, [ $this, 'maybe_handle' ] ); + } + + /** + * Returns the async process action name. + * + * Extending classes must override this method to return their unique action slug. + * + * @since 4.7.12 + * + * @return string + * + * @throws RuntimeException If the extending class does not override this method. + */ + public static function action() { + $class = static::class; + throw new RuntimeException( "Class {$class} should override the `action` method to define its own unique identifier." ); + } + + /** + * Handles the process request if valid and if authorized. + * + * @since 4.7.23 + * @since 4.9.5 Pulled the `maybe_handle` implementation of the `WP_Async_Request` class. + * + * @param array|null $data_source A source of data if not provided in the request; used for + * cron-based fallback. + */ + public function maybe_handle( $data_source = null ) { + $data_source = (array) $data_source; + + if ( $this->feature_detection->supports_async_process() ) { + // Don't lock up other requests while processing. + session_write_close(); + + check_ajax_referer( $this->identifier, 'nonce' ); + + // Let's make sure to hydrate date from the request if not set. + if ( count( array_filter( $data_source ) ) < 1 ) { + $data_source = $_POST; + } + + do_action( + 'tribe_log', + 'debug', + $this->identifier, + [ + 'action' => 'async_handling', + 'data_source' => $data_source, + 'payload' => $_POST, + ] + ); + + $this->handle( $data_source ); + + wp_die(); + } + + /* + * If the environment does not support AJAX-based async processing then + * fallback to use the cron-based approach and just call the handle method + * removing it first from the action to avoid multiple calls. + */ + wp_clear_scheduled_hook( $this->healthcheck_cron_hook_id, [ $data_source ] ); + + do_action( + 'tribe_log', + 'debug', + $this->identifier, + array_merge( [ 'action' => 'cron_handling' ], $data_source ) ); + + $this->handle( $data_source ); + } + + /** + * Overrides the base `dispatch` method to allow for constants and/or environment vars to run + * async requests in sync mode. + * + * @since 4.7.12 + * @since 4.9.5 Pulled `dispatch` method logic from the `WP_Async_Request` class. + * + * @return mixed + */ + public function dispatch() { + if ( + ( defined( 'TRIBE_NO_ASYNC' ) && true === TRIBE_NO_ASYNC ) + || true === (bool) getenv( 'TRIBE_NO_ASYNC' ) + ) { + do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'sync_handle', 'data' => $this->data ] ); + + return $this->sync_handle( $this->data ); + } + + if ( $this->feature_detection->supports_async_process() ) { + $url = add_query_arg( $this->get_query_args(), $this->get_query_url() ); + $args = $this->get_post_args(); + + do_action( 'tribe_log', 'debug', $this->identifier, [ 'action' => 'async_dispatch', 'data' => $this->data ] ); + + return wp_remote_post( esc_url_raw( $url ), $args ); + } + + /* + * If async AJAX-based processing is not available then we "dispatch" + * by scheduling a single cron event immediately (as soon as possible) + * for this handler cron identifier. + */ + if ( ! wp_next_scheduled( $this->healthcheck_cron_hook_id, [ $this->data ] ) ) { + // Schedule the event to happen as soon as possible. + $scheduled = wp_schedule_single_event( time() - 1, $this->healthcheck_cron_hook_id, [ $this->data ] ); + + if ( false === $scheduled ) { + /** @var Tribe__Log__Logger $logger */ + $logger = tribe( 'logger' ); + $class = get_class( $this ); + $src = call_user_func( [ $class, 'action' ] ); + $logger->log( 'Could not schedule event for cron-based handling', Tribe__Log::ERROR, $src ); + + do_action( + 'tribe_log', + 'error', + $this->identifier, + [ 'action' => 'schedule_cron', 'data' => $this->data ] + ); + } + + do_action( + 'tribe_log', + 'debug', + $this->identifier, + [ 'action' => 'schedule_cron', 'data' => $this->data ] + ); + } + + return true; + } + + /** + * Handles the process immediately, not in an async manner. + * + * @since 4.7.12 + * + * @param array|null $data_source If not provided the method will read the handler data from the + * request array. + * + * @return mixed|null The result of the synchronous handling. + */ + abstract public function sync_handle( array $data_source = null ); + + /** + * Returns an array of arguments that will be used to send the POST request. + * + * @since 4.9.5 Pulled from the `WP_Async_Request` class. + * + * @return array An array of arguments for the POST request. + */ + protected function get_query_args() { + if ( null !== $this->query_args ) { + return $this->query_args; + } + + return [ + 'action' => $this->identifier, + 'nonce' => wp_create_nonce( $this->identifier ), + ]; + } + + /** + * Returns the URL that wil be used to post the request. + * + * @since 4.9.5 Pulled from the `WP_Async_Request` class. + * + * @return string The URL that will be used to POST the dispatch request; defaults + * to the `admin-ajax.php` one. + */ + protected function get_query_url() { + if ( null !== $this->query_url ) { + return $this->query_url; + } + + return admin_url( 'admin-ajax.php' ); + } + + /** + * Returns the arguments that will be used to send the POST request. + * + * @since 4.9.5 Pulled from the `WP_Async_Request` class. + * + * @return array An array of arguments that will be used to send the POST request. + */ + protected function get_post_args() { + if ( null !== $this->post_args ) { + return $this->post_args; + } + + return [ + 'timeout' => 0.01, + 'blocking' => false, + 'body' => $this->data, + 'cookies' => $_COOKIE, + 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), + ]; + } + + /** + * Returns this handler cron hook identifier. + * + * The handler cron hook identifier is the one that the handler + * will use to schedule a single cron event when the `dispatch` + * method is called and the environment does not support async + * processing. + * + * @since 4.7.23 + * + * @return string The complete cron hook name (identifier) for + * this handler. + */ + public function get_healthcheck_cron_hook_id() { + return $this->healthcheck_cron_hook_id; + } + + /** + * Sets the that will be used during the request. + * + * @since 4.9.5 Pulled from the `WP_Async_Request` class. + * + * @param array $data Data. + * + * @return $this This handler instance. + */ + public function data( $data ) { + $this->data = $data; + + return $this; + } + + /** + * Handles the request and performs an action. + * + * @since 4.9.5 Pulled from the `WP_Async_Request` class. + * + * @param array|null $data_source A source of data if not provided in the request; used for + * cron-based fallback. + * + * @return null|array Depending on the context of the call, cron or async, either the result + * of the handling (cron) or nothing (async). + */ + abstract protected function handle( array $data_source = null ); +} diff --git a/tribe-common/src/Tribe/Process/Post_Thumbnail_Setter.php b/tribe-common/src/Tribe/Process/Post_Thumbnail_Setter.php new file mode 100644 index 0000000000..55ff78b729 --- /dev/null +++ b/tribe-common/src/Tribe/Process/Post_Thumbnail_Setter.php @@ -0,0 +1,176 @@ +set_post_id( $post_id ); + * $post_thumbnail_setter->set_post_thumbnail( 'http://foo.com/random-image.jpg' ); + * $post_thumbnail_setter->dispatch(); + * + * @since 4.7.12 + */ +class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler { + /** + * @var int The ID of the post the post thumbnail should be assigned to. + */ + protected $post_id; + + /** + * @var int|string Either the ID of an attachment that should be set as the post thumbnail + * or the full URL, or file path, to it. + */ + protected $post_thumbnail; + + /** + * {@inheritdoc} + */ + public static function action() { + return 'post_thumbnail_setter'; + } + + /** + * {@inheritdoc} + */ + public function dispatch() { + if ( ! isset( $this->post_id, $this->post_thumbnail ) ) { + // since this is a developer error we are not localizing this error string + throw new InvalidArgumentException( 'Post ID and featured image should be set before trying to dispatch.' ); + } + + $data = [ + 'post_id' => $this->post_id, + 'post_thumbnail' => trim( $this->post_thumbnail ), + ]; + + $this->data( $data ); + + do_action( 'tribe_log', 'debug', $this->identifier, $data ); + + return parent::dispatch(); + } + + /** + * Sets the ID of the post the post thumbnail (aka "featured image") should be attached + * and set for. + * + * @since 4.7.12 + * + * @param int $post_id The target post ID. + */ + public function set_post_id( $post_id ) { + $this->post_id = $post_id; + } + + /** + * Sets the post thumbnail ID or source the process should set. + * + * @since 4.7.12 + * + * @param int|string $post_thumbnail Either an attachment ID or the full URL, or path, to + * the post thumbnail image. + */ + public function set_post_thumbnail( $post_thumbnail ) { + $this->post_thumbnail = $post_thumbnail; + } + + /** + * Handles the post thumbnail setting async process. + * + * The post thumbnail will be uploaded, if not uploaded already, using the `tribe_upload_image` function. + * This method is an alias of the publicly accessible `sync_handle` one. + * + * @since 4.7.12 + * + * @param array|null $data_source An optional source of data. + * + * @see Tribe__Process__Post_Thumbnail_Setter::sync_handle() + * + * @see tribe_upload_image() + */ + protected function handle( array $data_source = null ) { + $this->sync_handle( $data_source ); + } + + /** + * {@inheritdoc} + */ + public function sync_handle( array $data_source = null ) { + do_action( 'tribe_log', 'debug', $this->identifier, [ 'status' => 'handling request' ] ); + + $data_source = isset( $data_source ) ? $data_source : $_POST; + + if ( ! isset( $data_source['post_id'], $data_source['post_thumbnail'] ) ) { + do_action( 'tribe_log', 'error', $this->identifier, [ 'data' => $data_source, ] ); + + return 0; + } + + $id = filter_var( $data_source['post_id'], FILTER_SANITIZE_NUMBER_INT ); + $post_thumbnail = filter_var( $data_source['post_thumbnail'], FILTER_SANITIZE_STRING ); + + do_action( 'tribe_log', 'debug', $this->identifier, [ + 'status' => 'fetching thumbnail', + 'post_thumbnail' => $post_thumbnail, + 'post_id' => $id, + ] ); + + $thumbnail_id = tribe_upload_image( $post_thumbnail ); + + if ( false === $thumbnail_id ) { + do_action( + 'tribe_log', + 'error', + $this->identifier, + [ + 'action' => 'fetch', + 'post_thumbnail' => $post_thumbnail, + 'post_id' => $id, + 'status' => 'could not fetch', + ] + ); + + return 0; + } + + $set = true; + if ( (int) get_post_thumbnail_id( $id ) !== (int) $thumbnail_id ) { + $set = set_post_thumbnail( $id, $thumbnail_id ); + } + + if ( false === $set ) { + do_action( + 'tribe_log', + 'error', + $this->identifier, + [ + 'action' => 'set', + 'post_thumbnail' => $post_thumbnail, + 'attachment_id' => $thumbnail_id, + 'post_id' => $id, + 'status' => 'unable to set thumbnail', + ] + ); + + return $thumbnail_id; + } + + do_action( + 'tribe_log', + 'debug', + $this->identifier, + [ + 'action' => 'set', + 'post_thumbnail' => $post_thumbnail, + 'attachment_id' => $thumbnail_id, + 'post_id' => $id, + 'status' => 'completed - attachment created and linked to the post', + ] + ); + + return $thumbnail_id; + } +} diff --git a/tribe-common/src/Tribe/Process/Queue.php b/tribe-common/src/Tribe/Process/Queue.php new file mode 100644 index 0000000000..650f920b10 --- /dev/null +++ b/tribe-common/src/Tribe/Process/Queue.php @@ -0,0 +1,1129 @@ +action = call_user_func( [ $class, 'action' ] ); + $this->feature_detection = tribe( 'feature-detection' ); + + parent::__construct(); + + $this->healthcheck_cron_hook_id = $this->identifier . '_cron'; + $this->healthcheck_cron_interval_id = $this->identifier . '_cron_interval'; + + add_action( $this->healthcheck_cron_hook_id, [ $this, 'handle_cron_healthcheck' ] ); + add_filter( 'cron_schedules', [ $this, 'schedule_cron_healthcheck' ] ); + + /* + * This object might have been built while processing crons so + * we hook on the the object cron identifier to handle the task + * if the cron-triggered action ever fires. + */ + add_action( $this->identifier, [ $this, 'maybe_handle' ] ); + } + + /** + * Stops a queue that might be running. + * + * The queue process results are not rolled back (e.g. 200 posts to create, stopped + * after 50, those 50 posts will persist). + * + * @since 4.7.12 + * + * @param string $queue_id The unique identifier of the queue that should be stopped. + * + * @see Tribe__Process__Queue::save() to get the queue unique id. + * + * @return bool Whether the queue was correctly stopped, and its information + * deleted, or not. + */ + public static function stop_queue( $queue_id ) { + $meta = (array) get_transient( $queue_id . '_meta' ); + delete_transient( $queue_id . '_meta' ); + + if ( ! empty( $meta['identifier'] ) ) { + delete_transient( $meta['identifier'] . '_process_lock' ); + } + + return delete_option( $queue_id ); + } + + /** + * Whether a queue process is stuck or not. + * + * A queue process that has not been doing anything for an amount + * of time is considered "stuck". + * + * @since 4.7.18 + * + * @param string $queue_id The queue process unique identifier. + * + * @return bool + */ + public static function is_stuck( $queue_id ) { + $queue_status = self::get_status_of( $queue_id ); + $is_stuck = false; + + /** + * Filters the maximum allowed time a queue process can go without updates + * before being considered stuck. + * + * @since 4.7.18 + * + * @param int $time_limit A value in seconds, defaults to 5'. + */ + $limit = (float) apply_filters( 'tribe_process_queue_time_limit', 300 ); + + if ( ! empty( $queue_status['last_update'] ) && is_numeric( $queue_status['last_update'] ) ) { + $is_stuck = time() - (int) $queue_status['last_update'] > $limit; + } else { + $queue_status['last_update'] = time(); + set_transient( $queue_id . '_meta', $queue_status->to_array(), DAY_IN_SECONDS ); + } + + /** + * Filters whether a queue is considered "stuck" or not. + * + * @since 4.7.18 + * + * @param bool $is_stuck + * @param string $queue_id + * @param Tribe__Data $queue_status + */ + return apply_filters( 'tribe_process_queue_is_stuck', $is_stuck, $queue_id, $queue_status ); + } + + /** + * Returns a queue status and information. + * + * @since 4.7.12 + * + * @param string $queue_id + * + * @return Tribe__Data An object containing information about the queue. + * + * @see Tribe__Process__Queue::save() to get the queue unique id. + */ + public static function get_status_of( $queue_id ) { + $meta = (array) get_transient( $queue_id . '_meta' ); + $data = [ + 'identifier' => $queue_id, + 'done' => (int) Tribe__Utils__Array::get( $meta, 'done', 0 ), + 'total' => (int) Tribe__Utils__Array::get( $meta, 'total', 0 ), + 'fragments' => (int) Tribe__Utils__Array::get( $meta, 'fragments', 0 ), + 'last_update' => (int) Tribe__Utils__Array::get( $meta, 'last_update', false ), + ]; + + return new Tribe__Data( $data, 0 ); + } + + /** + * Deletes all queues for a specific action. + * + * @since 4.7.19 + * + * @param string $action The action (prefix) of the queues to delete. + * + * @return int The number of delete queues. + */ + public static function delete_all_queues( $action ) { + global $wpdb; + + $action = $wpdb->esc_like( 'tribe_queue_' . $action ) . '%'; + + $queues = $wpdb->get_col( $wpdb->prepare( " + SELECT DISTINCT(option_name) + FROM {$wpdb->options} + WHERE option_name LIKE %s + ", $action ) ); + + if ( empty( $queues ) ) { + return 0; + } + + $deleted = 0; + + foreach ( $queues as $queue ) { + $deleted ++; + self::delete_queue( $queue ); + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function delete( $key ) { + self::delete_queue( $key ); + + return $this; + } + + /** + * Deletes a queue batch(es) and meta information. + * + * @since 4.7.18 + * + * @param string $key + */ + public static function delete_queue( $key ) { + global $wpdb; + + $meta_key = $key . '_meta'; + + $key = $wpdb->esc_like( $key ) . '%'; + + $wpdb->query( $wpdb->prepare( " + DELETE + FROM {$wpdb->options} + WHERE option_name LIKE %s + ", $key ) ); + + delete_transient( $meta_key ); + } + + /** + * Upates the queue and meta data for the process. + * + * @since 4.7.12 + * @since 4.9.5 Pulled method from the `WP_Background_Process` class. + * + * @param string $key The key of the data to save. + * @param array $data The data to save. + * + * @return $this This process instance. + */ + public function update( $key, $data ) { + $meta_key = $this->get_meta_key( $key ); + $meta = (array) get_transient( $meta_key ); + $done = $this->original_batch_count - count( $data ); + + $update_data = array_merge( $meta, [ + 'done' => $meta['done'] + $done, + 'last_update' => time(), + ] ); + + /** + * Filters the information that will be updated in the database for this queue type. + * + * @since 4.7.12 + * + * @param array $update_data + * @param self $this + */ + $update_data = apply_filters( "tribe_process_queue_{$this->identifier}_update_data", $update_data, $this ); + + set_transient( $meta_key, $update_data, DAY_IN_SECONDS ); + + if ( ! empty( $data ) ) { + update_option( $key, $data ); + } + + return $this; + } + + /** + * Returns the name of the transient that will store the queue meta information + * for the specific key. + * + * @since 4.7.12 + * + * @param string $key + * + * @return string + */ + public function get_meta_key( $key ) { + $key = preg_replace( '/^(.*)_\\d+$/', '$1', $key ); + + return $key . '_meta'; + } + + /** + * {@inheritdoc} + */ + public function save() { + $key = $this->generate_key(); + + $fragments_count = $this->save_split_data( $key, $this->data ); + + $save_data = [ + 'identifier' => $this->identifier, + 'done' => 0, + 'total' => count( $this->data ), + 'fragments' => $fragments_count, + 'last_update' => time(), + ]; + + /** + * Filters the information that will be saved to the database for this queue type. + * + * @since 4.7.12 + * + * @param array $save_data + * @param self $this + */ + $save_data = apply_filters( "tribe_process_queue_{$this->identifier}_save_data", $save_data, $this ); + + set_transient( $this->get_meta_key( $key ), $save_data ); + + $this->did_save = true; + $this->id = $key; + + return $this; + } + + /** + * Generates the unique key for the queue optionally using the client provided + * id. + * + * @since 4.7.12 + * + * @param int $length The lengthy of the key to generate, longer keys will + * add more entropy; default to 64. + * + * @return string The generated batch key. + */ + protected function generate_key( $length = 64 ) { + if ( empty( $this->id_base ) ) { + $this->id_base = md5( microtime() . mt_rand() ); + } + + $prepend = $this->identifier . '_batch_'; + + $this->batch_key = substr( $prepend . $this->id_base, 0, $length ); + + return $this->batch_key; + } + + /** + * Saves the queue data to the database taking max_packet_size into account. + * + * In some instances the serialized size of the data might be bigger than the + * database `max_packet_size`; trying to write all the data in one query would + * make the db "go away...". + * Here we try to read the database `max_packet_size` setting and use that information + * to avoid overloading the query. + * + * @param string $key + * @param array $data + * + * @return int The number of fragments the data was split and stored into. + */ + protected function save_split_data( $key, array $data ) { + if ( empty( $data ) ) { + return 0; + } + + $max_frag_size = $this->get_max_frag_size(); + // we add a 15% to the size to take the serialization and query overhead into account when fragmenting + $serialized_size = strlen( utf8_decode( maybe_serialize( $data ) ) ) * 1.15; + $frags_count = (int) ceil( $serialized_size / $max_frag_size ); + $per_frag = max( (int) floor( count( $data ) / $frags_count ), 1 ); + + $split_data = array_chunk( $data, $per_frag ); + + if ( empty( $split_data ) ) { + return 0; + } + + foreach ( $split_data as $i => $iValue ) { + $postfix = 0 === $i ? '' : "_{$i}"; + update_option( $key . $postfix, $split_data[ $i ] ); + } + + return count( $split_data ); + } + + /** + * Returns the max frag size in bytes. + * + * The bottleneck here is the database `max_packet_size` so we try to read + * it from the database. + * + * @return int The max size, in bytes, of a data fragment. + */ + protected function get_max_frag_size() { + if ( ! empty( $this->max_frag_size ) ) { + return $this->max_frag_size; + } + + return tribe( 'db' )->get_max_allowed_packet_size(); + } + + /** + * Sets the maximum size, in bytes, of the queue fragments. + * + * This will prevent the class from trying to read the value from the database. + * + * @since 4.7.12 + * + * @param int $max_frag_size + */ + public function set_max_frag_size( $max_frag_size ) { + $this->max_frag_size = $max_frag_size; + } + + /** + * Returns the queue unique identifier. + * + * Mind that an id will only be available after saving a queue. + * + * @since 4.7.12 + * + * @return string + * @throws RuntimeException if trying to get the queue id before saving it. + */ + public function get_id() { + if ( null === $this->id ) { + // not localized as this is a developer-land error + throw new RuntimeException( 'Can only get the id of queue after saving it.' ); + } + + return $this->id; + } + + /** + * Sets the queue unique id. + * + * When using this method the client code takes charge of the queue id uniqueness; + * the class will not check it. + * + * @since 4.7.12 + * + * @param string $queue_id + * + * @throws RuntimeException If trying to set the queue id after saving it. + */ + public function set_id( $queue_id ) { + if ( $this->did_save ) { + throw new RuntimeException( 'The queue id can be set only before saving it.' ); + } + + $queue_id = preg_replace( '/^' . preg_quote( $this->identifier, '/' ) . '_batch_/', '', $queue_id ); + + $this->id_base = $queue_id; + } + + /** + * Overrides the base `dispatch` method to allow for constants and/or environment vars to run + * async requests in sync mode. + * + * @since 4.7.12 + * @since 4.9.5 Pulled method code from the `WP_Background_Process` class. + * + * @return mixed + */ + public function dispatch() { + if ( + ( defined( 'TRIBE_NO_ASYNC' ) && true === TRIBE_NO_ASYNC ) + || true === (bool) getenv( 'TRIBE_NO_ASYNC' ) + || (bool) tribe_get_request_var( 'tribe_queue_sync', false ) + || tribe_is_truthy( tribe_get_option( 'tribe_queue_sync', false ) ) + ) { + $result = $this->sync_process(); + $this->complete(); + + return $result; + } + + if ( $this->feature_detection->supports_async_process() ) { + // Schedule the cron health-check. + $this->schedule_event(); + + // Perform remote post. + return parent::dispatch(); + } + + /* + * If async AJAX-based processing is not available then we "dispatch" + * by scheduling a single cron event immediately (as soon as possible) + * for this handler cron identifier. + */ + if ( ! wp_next_scheduled( $this->identifier ) ) { + // Schedule the event to happen as soon as possible. + $scheduled = wp_schedule_single_event( time() - 1, $this->identifier ); + + if ( false === $scheduled ) { + /** @var Tribe__Log__Logger $logger */ + $logger = tribe( 'logger' ); + $class = get_class( $this ); + $src = call_user_func( [ $class, 'action' ] ); + $logger->log( 'Could not schedule event for cron-based processing', Tribe__Log::ERROR, $src ); + } + } + + return true; + } + + /** + * Handles the process immediately, not in an async manner. + * + * @since 4.7.12 + * + * @return array An array containing the result of each item handling. + */ + public function sync_process() { + $result = []; + $this->doing_sync = true; + + foreach ( $this->data as $item ) { + $result[] = $this->task( $item ); + } + + return $result; + } + + /** + * Returns the name of the option used by the queue to store its batch(es). + * + * Mind that this value will be set only when first saving the queue and it will not be set + * in following queue processing. + * + * @since 4.7.12 + * + * @param int $n The number of a specific batch option name to get; defaults to `0` to get the + * option name of the first one. + * + * @return string + * + * @throws RuntimeException If trying to get the value before saving the queue or during following + * processing. + */ + public function get_batch_key( $n = 0 ) { + if ( null === $this->batch_key || ! $this->did_save ) { + throw new RuntimeException( 'The batch key will only be set after the queue is first saved' ); + } + + return empty( $n ) ? $this->batch_key : $this->batch_key . '_' . (int) $n; + } + + /** + * Returns the queue action identifier. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @return string The queue action identifier. + */ + public function get_identifier() { + return $this->identifier; + } + + /** + * Returns a batch of items to process from the queue. + * + * @since 4.7.12 + * @since 4.9.5 Pulled method code from the `WP_Background_Process` class. + * + * @return stdClass The first batch of items from the queue. + */ + protected function get_batch() { + global $wpdb; + + $key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%'; + + $query = $wpdb->get_row( $wpdb->prepare( " + SELECT * + FROM {$wpdb->options} + WHERE option_name LIKE %s + ORDER BY option_id ASC + LIMIT 1 + ", $key ) ); + + $batch = new stdClass(); + $batch->key = $query->option_name; + $batch->data = maybe_unserialize( $query->option_value ); + + $this->original_batch_count = ! empty( $batch->data ) ? count( $batch->data ) : 0; + + return $batch; + } + + /** + * {@inheritdoc} + */ + protected function get_post_args() { + $post_args = parent::get_post_args(); + + /** + * While sending the data into the body makes sense for the async process it does + * not make sense when processing a queue since the data will be stored and read + * from the database; furthermore this could raise issues with the max POST size. + */ + $post_args['body'] = []; + + return $post_args; + } + + /** + * Maybe handle the process request in async or sync mode depending on the + * supported mode. + * + * @param array|null $data_source An optional data source. + * + * @since 4.9.5 + */ + public function maybe_handle( $data_source = null ) { + // Don't lock up other requests while processing + session_write_close(); + + if ( $this->feature_detection->supports_async_process() ) { + return $this->maybe_handle_async(); + } + + return $this->maybe_handle_sync(); + } + + /** + * Push an item to the process queue. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @param mixed $data An item to process. + * + * @return $this This process instance. + */ + public function push_to_queue( $data ) { + $this->data[] = $data; + + return $this; + } + + /** + * Maybe handle this process request in async mode. + * + * @since 4.9.5 + */ + protected function maybe_handle_async() { + if ( $this->is_process_running() ) { + // Background process already running. + wp_die(); + } + + if ( $this->is_queue_empty() ) { + // No data to process: we're done. + $this->complete(); + wp_die(); + } + + check_ajax_referer( $this->identifier, 'nonce' ); + + $this->handle(); + + wp_die(); + } + + /** + * Handle the process request in sync mode. + * + * @since 4.9.5 + */ + protected function maybe_handle_sync() { + if ( $this->is_process_running() ) { + // Background process already running. + return; + } + + if ( $this->is_queue_empty() ) { + // No data to process: we're done. + $this->complete(); + + return; + } + + $this->handle(); + } + + /** + * Checks whether the queue is empty or not. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @return bool Whether the queue is empty or not. + */ + protected function is_queue_empty() { + global $wpdb; + + $key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%'; + + $count = $wpdb->get_var( $wpdb->prepare( " + SELECT COUNT(*) + FROM {$wpdb->options} + WHERE option_name LIKE %s + ", $key ) ); + + return $count <= 0; + } + + /** + * Checks whether the process is currently running or not. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + protected function is_process_running() { + if ( get_transient( $this->identifier . '_process_lock' ) ) { + return true; + } + + return false; + } + + /** + * Locks the process so that other instances cannot spawn and run. + * + * Lock the process so that multiple instances can't run simultaneously. + * Override if applicable, but the duration should be greater than that + * defined in the `time_exceeded()` method. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + protected function lock_process() { + // Set start time of current process. + $this->start_time = time(); + + $lock_duration = $this->queue_lock_time; + + /** + * Filters the duration of the lock acquired by a process instance. + * + * The lock duration should be larger than the maximum time a process is allowed to run. + * + * @since 4.9.5 + * + * @param int $lock_duration The lock duration in seconds; defaults to one minute. + * @param static $this This process instance. + */ + $lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration, $this ); + + set_transient( $this->identifier . '_process_lock', microtime(), $lock_duration ); + } + + /** + * Releases the process lock so that other instances can spawn and run. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @return $this This process instance. + */ + protected function unlock_process() { + delete_transient( $this->identifier . '_process_lock' ); + + return $this; + } + + /** + * Handles the process request. + * + * Pass each queue item to the task handler, while remaining + * within server memory and time limit constraints. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @param array|null $data_source Unused and kept for compatibility with parent; the queue + * data is stored and read from the database. + */ + protected function handle( array $data_source = null ) { + $this->lock_process(); + + do { + $batch = $this->get_batch(); + + foreach ( $batch->data as $key => $value ) { + $task = $this->task( $value ); + + if ( false !== $task ) { + $batch->data[ $key ] = $task; + } else { + unset( $batch->data[ $key ] ); + } + + if ( $this->time_exceeded() || $this->memory_exceeded() ) { + // Batch limits reached. + break; + } + } + + // Update or delete current batch. + if ( ! empty( $batch->data ) ) { + $this->update( $batch->key, $batch->data ); + } else { + $this->delete( $batch->key ); + } + } while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() ); + + $this->unlock_process(); + + // Start next batch or complete process. + if ( ! $this->is_queue_empty() ) { + $this->dispatch(); + } else { + $this->complete(); + } + + if ( doing_action( $this->identifier ) ) { + /* + * We're probably acting in the context of a cron request or + * in the context of an explicitly triggered action: let's not + * die. + */ + return; + } + + wp_die(); + } + + /** + * Checks whether the memory limit was exceeded. + * + * Ensures the batch process never exceeds 90% + * of the maximum WordPress memory. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @return bool + */ + protected function memory_exceeded() { + $memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory + $current_memory = memory_get_usage( true ); + $return = false; + + if ( $current_memory >= $memory_limit ) { + $return = true; + } + + /** + * Filters whether the process did exceed the allowed memory limit or not. + * + * @since 4.9.5 + * + * @param bool $return Whether the process did exceed the allowed memory limit or not. + * @param static $this This process instance. + */ + return apply_filters( $this->identifier . '_memory_exceeded', $return, $this ); + } + + /** + * Returns the memory limit for this process. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @return int The memory limit in bytes. + */ + protected function get_memory_limit() { + if ( function_exists( 'ini_get' ) ) { + $memory_limit = ini_get( 'memory_limit' ); + } else { + // Sensible default. + $memory_limit = '128M'; + } + + if ( ! $memory_limit || -1 === (int) $memory_limit ) { + // Unlimited, set to 32GB. + $memory_limit = '32000M'; + } + + return (int) $memory_limit * 1024 * 1024; + } + + /** + * Checks whether the execution time was exceeded or not. + * + * Ensures the batch never exceeds a sensible time limit. + * A timeout limit of 30s is common on shared hosting. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @return bool Whether the execution time was exceeded or not. + */ + protected function time_exceeded() { + /** + * Filters the maximum time the process can operate before continuing in another + * request. + * We pick a safe default of 20 seconds but this value can be adjusted to suit the system + * timeout settings. + * + * @since 4.9.5 + * + * @param int $default_time_limit The time limit for the process. + * @param static $this This process instance. + */ + $time_limit = apply_filters( $this->identifier . '_default_time_limit', 20, $this ); + + $finish = $this->start_time + $time_limit; + $return = false; + + if ( time() >= $finish ) { + $return = true; + } + + /** + * Filters whether a process instance should be marked as having exceeded the time limit or not. + * + * @since 4.9.5 + * + * @param bool $return Whether the process did exceed the time limit or not. + * @param static $this This process instance. + */ + return apply_filters( $this->identifier . '_time_exceeded', $return ); + } + + /** + * Completes the processing, cleaning up after it. + * + * Override if applicable, but ensure that the below actions are + * performed, or, call parent::complete(). + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + protected function complete() { + // Unschedule the cron health-check. + $this->clear_scheduled_event(); + } + + /** + * Schedules a cron-based health-check to restart the queue if stuck. + * + * Filters the `cron_schedules` filter to add a check every 5 minutes. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @param mixed $schedules The cron schedules to check. + * + * @return mixed The updated cron schedules. + */ + public function schedule_cron_healthcheck( $schedules ) { + /** + * Filters the number of minutes to schedule the cron health-check. + * + * @since 4.9.5 + * + * @param int $interval The number of minutes to schedule the cron health-check; defaults to 5. + * @param static $this This process instance. + */ + $interval = apply_filters( $this->identifier . '_cron_interval', $this->healthcheck_cron_interval, $this ); + + // Adds every 5 minutes to the existing schedules. + $schedules[ $this->identifier . '_cron_interval' ] = [ + 'interval' => MINUTE_IN_SECONDS * $interval, + 'display' => sprintf( __( 'Every %d Minutes', 'tribe-common' ), $interval ), + ]; + + return $schedules; + } + + /** + * Handles the cron health-check. + * + * Restart the background process if not already running + * and data exists in the queue. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + public function handle_cron_healthcheck() { + if ( $this->is_process_running() ) { + // Background process already running. + exit; + } + + if ( $this->is_queue_empty() ) { + // No data to process. + $this->clear_scheduled_event(); + exit; + } + + $this->handle(); + + exit; + } + + /** + * Schedules the cron health-check event. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + protected function schedule_event() { + if ( ! wp_next_scheduled( $this->healthcheck_cron_hook_id ) ) { + wp_schedule_event( time(), $this->healthcheck_cron_interval_id, $this->healthcheck_cron_hook_id ); + } + } + + /** + * Clears the scheduled health-check cron event. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + protected function clear_scheduled_event() { + $timestamp = wp_next_scheduled( $this->healthcheck_cron_hook_id ); + + if ( $timestamp ) { + wp_unschedule_event( $timestamp, $this->healthcheck_cron_hook_id ); + } + } + + /** + * Cancels the current process. + * + * Stops processing queue items and clean up. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + */ + public function cancel_process() { + if ( ! $this->is_queue_empty() ) { + $batch = $this->get_batch(); + + $this->delete( $batch->key ); + + wp_clear_scheduled_hook( $this->healthcheck_cron_hook_id ); + } + + } + + /** + * Executes the process task on a single item. + * + * Override this method to perform any actions required on each + * queue item. Return the modified item for further processing + * in the next pass through. Or, return false to remove the + * item from the queue. + * + * @since 4.9.5 Pulled from the `WP_Background_Process` class. + * + * @param mixed $item Queue item to iterate over. + * + * @return mixed + */ + abstract protected function task( $item ); + + /** + * Concrete implementation of the base handler method. + * + * Just a proxy to the `sync_process` method. + * + * @since 4.9.5 + * + * @param array|null $data_source If not provided the method will read the handler data from the + * request array. + * + * @return array|mixed|null The synchronous process result. + */ + public function sync_handle( array $data_source = null ) { + // In the base implementation the data source is unused and read from the database. + return $this->sync_process(); + } +} diff --git a/tribe-common/src/Tribe/Process/Tester.php b/tribe-common/src/Tribe/Process/Tester.php new file mode 100644 index 0000000000..625bd70b52 --- /dev/null +++ b/tribe-common/src/Tribe/Process/Tester.php @@ -0,0 +1,97 @@ +get_query_args(), $this->get_query_url() ); + $args = $this->get_post_args(); + + return wp_remote_post( esc_url_raw( $url ), $args ); + } + + /** + * An override of the method implemented by the base Tribe Handler + * class to make sure the processing is done in async mode. + * + * This is the same code as the base WP_Background_Process class. + * + * @since 4.7.23 + * + * @param null|array $data_source An optional data source. + */ + public function maybe_handle( $data_source = null ) { + // Don't lock up other requests while processing + session_write_close(); + + check_ajax_referer( $this->identifier, 'nonce' ); + + $this->handle(); + + wp_die(); + } + + /** + * The task this class will perform is just setting a transient. + * The transient existence will be used as a canary to detect if + * background processing is supported. + * + * @since 4.7.23 + * + * @param array|null $data_source Unused. + */ + protected function handle( array $data_source = null ) { + set_transient( self::TRANSIENT_NAME, 1, HOUR_IN_SECONDS ); + } + + /** + * Returns this handler action identifier. + * + * @since 4.7.23 + * + * @return string This handler action identifier. + */ + public static function action() { + return 'async_process_support_test'; + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Promise.php b/tribe-common/src/Tribe/Promise.php new file mode 100644 index 0000000000..d3c1dc4b07 --- /dev/null +++ b/tribe-common/src/Tribe/Promise.php @@ -0,0 +1,309 @@ +save()->dispatch(); + * $promise_id = $promise->get_id(); + * + * The promise is really a background process in disguise and will work, for all + * intents and purposes, like one. + * + * @since 4.9.5 + */ + +class Tribe__Promise extends Tribe__Process__Queue { + + /** + * The action that will be done when the promise is done. + * + * @var string + */ + protected $resolved; + + /** + * An array of arguments that will be used to call a callback on completion. + * + * @var array + */ + protected $resolved_args; + + /** + * The action that will be done when the promise fails due to an error. + * + * @var string + */ + protected $rejected; + + /** + * An array of arguments that will be used to call a callback on failure. + * + * @var array + */ + protected $rejected_args; + + /** + * Whether this promise did resolve correctly or not. + * + * @var bool + */ + protected $resolved_correctly = true; + + /** + * Tribe__Promise constructor. + * + * @param string|array|Tribe__Utils__Callback $callback The callback that should run to perform the promise task. + * @param array $items The items to process, each item will be passed as first + * argument to the callback at run-time. + * @param array $extra_args An array of extra arguments that will be passed to the + * callback function. + */ + public function __construct( $callback = null, array $items = null, array $extra_args = [] ) { + parent::__construct(); + + if ( ! empty( $callback ) && ! empty( $items ) ) { + foreach ( $items as $target ) { + $item['callback'] = $callback; + $item['args'] = array_merge( [ $target ], $extra_args ); + $this->push_to_queue( $item ); + } + } + } + + /** + * {@inheritdoc} + */ + public static function action() { + return 'promise'; + } + + /** + * Sets a callback, and optional arguments, that will be called when the promise + * is resolved. + * + * The callback and arguments must be serializable and make sense in the context of, + * potentially, a different call from the one where this method is called. + * + * @since 4.9.5 + * + * @param callable|Tribe__Utils__Callback $resolved The callback to call on success. + * @param callable|Tribe__Utils__Callback $rejected The callback to call on failure. + * @param array $resolved_args The arguments that will be passed to the resolved + * callback. + * @param array $rejected_args The arguments that will be passed to the rejected + * callback. + * + * @return Tribe__Promise This promise. + * + * @throws LogicException If this method is called after saving the promise. + */ + public function then( $resolved, $rejected = null, array $resolved_args = null, array $rejected_args = null ) { + if ( $this->did_save ) { + throw new LogicException( 'The promise "then" method should be called before the "save" one' ); + } + + $this->resolved = $resolved; + $this->resolved_args = $resolved_args; + $this->rejected = $rejected; + $this->rejected_args = $rejected_args; + + foreach ( $this->data as &$item ) { + $item['resolved'] = $this->resolved; + $item['resolved_args'] = $this->resolved_args; + $item['rejected'] = $this->rejected; + $item['rejected_args'] = $this->rejected_args; + } + + return $this; + } + + /** + * Overrides the base method to save before dispatching. + * + * @since 4.9.5 + * + * @return mixed The dispatch return value. + */ + public function dispatch() { + if ( empty( $this->data ) ) { + $this->complete(); + + return null; + } + + if ( ! $this->did_save ) { + $this->save(); + } + + return parent::dispatch(); + } + + /** + * A custom error handler to log any error tha might happen while invoking a promise + * callback. + * + * @since 4.9.5 + * + * @param int $code The error code. + * @param string $error_message The error message. + * + * @see set_error_handler() + */ + public function error_handler( $code, $error_message ) { + $message = 'There was an error (' . $code . ') while invoking a promise callback:'; + $message .= "\n\t" . $error_message; + tribe( 'logger' )->log( $message, Tribe__Log::ERROR, __CLASS__ ); + } + + /** + * Performs the task associated with the promise. + * + * The promise is really just a flexible background process that + * + * @since 4.9.5 + * + * @param array $item The promise payload, keys: + * { + * @param callable|Tribe__Utils__Callback $callback The callback this promise will + * call to perform the task. + * @param array $args An array of arguments that will be passed to the callback. + * @param callable|Tribe__Utils__Callback $then The callback this promise will + * call when complete. + * @param array $then_args An array of arguments that will be passed to the then callback. + * } + * + * + * @return bool `true` if the task needs to run again, `false` if the task is complete. + */ + protected function task( $item ) { + if ( isset( $item['resolved'] ) ) { + $this->resolved = $item['resolved']; + if ( isset( $item['resolved_args'] ) ) { + $this->resolved_args = $item['resolved_args']; + } + } + + if ( isset( $item['rejected'] ) ) { + $this->rejected = $item['rejected']; + if ( isset( $item['rejected_args'] ) ) { + $this->rejected_args = $item['rejected_args']; + } + } + + $callback_args = isset( $item['args'] ) ? $item['args'] : null; + $done = $this->do_callback( $item['callback'], $callback_args ); + + // If we are done then return `false` to indicate "no need to run again". + return $done ? false : true; + } + + /** + * Overrides the base method to allow building promises on empty objects + * without actually writing to the database. + * + * A fake queue id is set for compatibility reasons. + * + * @since 4.9.5 + * + * @return Tribe__Process__Queue This object. + */ + public function save() { + if ( empty( $this->data ) ) { + $this->id = uniqid( 'promise_', true ); + + return $this; + } + + return parent::save(); + } + + /** + * Invokes a callback function with optional arguments. + * + * If the callback invocation results in an exception or error then the callback will return `true` + * and log. + * + * @since 4.9.5 + * + * @param callable|Tribe__Utils__Callback $callback The callback to call. + * @param array|null $callback_args An optional array of arguments to call the + * callback with. + * + * @return mixed The callback invocation return value. + */ + protected function do_callback( $callback, array $callback_args = null ) { + try { + set_error_handler( [ $this, 'error_handler' ] ); + + $callback = $this->unpack_callback( $callback ); + + if ( count( $callback_args ) ) { + $done = call_user_func_array( $callback, $callback_args ); + } else { + $done = call_user_func( $callback ); + } + + restore_error_handler(); + + return $done; + } catch ( Exception $e ) { + $message = 'Exception (' . get_class( $e ) . ') thrown while invoking a promise callback:'; + $message .= "\n\t" . $e->getMessage(); + tribe( 'logger' )->log( $message, Tribe__Log::ERROR, __CLASS__ ); + + $this->resolved_correctly = false; + $this->complete(); + + return true; + } + } + + /** + * Unpacks a callback returning a callable array for callbacks wrapped using the + * Tribe__Utils__Callback class. + * + * @since 4.9.5 + * + * @param string|array|Tribe__Utils__Callback $callback The callback to unpack. + * + * @return array|string A callable array of string. + */ + protected function unpack_callback( $callback ) { + if ( $callback instanceof Tribe__Utils__Callback ) { + $callback = [ tribe( $callback->get_slug() ), $callback->get_method() ]; + } + + return $callback; + } + + /** + * Overrides the base method to call the success callback on completion. + * + * @since 4.9.5 + */ + protected function complete() { + parent::complete(); + + if ( $this->resolved_correctly && null !== $this->resolved ) { + $callback_args = isset( $this->resolved_args ) ? $this->resolved_args : null; + $this->do_callback( $this->resolved, $callback_args ); + } elseif ( ! $this->resolved_correctly && null !== $this->rejected ) { + $callback_args = isset( $this->rejected_args ) ? $this->rejected_args : null; + $this->do_callback( $this->rejected, $callback_args ); + } + } + + /** + * An alias of the dispatch method to stick with the expected naming + * standard. + * + * @since 4.9.5 + * + * @return mixed The dispatch operation return value. + */ + public function resolve() { + return $this->dispatch(); + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Promoter/Auth.php b/tribe-common/src/Tribe/Promoter/Auth.php new file mode 100644 index 0000000000..a7939e25a4 --- /dev/null +++ b/tribe-common/src/Tribe/Promoter/Auth.php @@ -0,0 +1,112 @@ +connector = $connector; + } + + /** + * Register the promoter auth key as part of the settings in order to make it available into the REST API. + * + * @since 4.12.6 + * + * @return void + */ + public function register_setting() { + register_setting( + 'options', + 'tribe_promoter_auth_key', + [ + 'type' => 'string', + 'show_in_rest' => true, + 'description' => __( 'Promoter Key', 'tribe-common' ), + 'sanitize_callback' => 'sanitize_text_field', + ] + ); + } + + /** + * Add an update the KEY used for promoter during the connection. + * + * @since 4.9.12 + * + * @param $secret_key + * + * @return string + */ + public function filter_promoter_secret_key( $secret_key ) { + + _deprecated_function( __METHOD__, '4.12.6' ); + + return empty( $secret_key ) ? $this->generate_secret_key() : $secret_key; + } + + /** + * Authorize the request with the Promoter Connector. + * + * @since 4.9 + * + * @return bool Whether the request was authorized successfully. + */ + public function authorize_with_connector() { + $secret_key = $this->generate_secret_key(); + $promoter_key = tribe_get_request_var( 'promoter_key' ); + $license_key = tribe_get_request_var( 'license_key' ); + + // send request to auth connector + $result = $this->connector->authorize_with_connector( get_current_user_id(), $secret_key, $promoter_key, $license_key ); + + // If the secret was not stored correctly on Connector Application, remove it! + if ( ! $result ) { + delete_option( 'tribe_promoter_auth_key' ); + } + + return $result; + } + + /** + * Grab the WP constant and store it as the auth key, if none exists or is it empty + * it creates a dynamic one. + * + * @since 4.9.12 + * + * @since 4.9 + * + * @return string The secret key. + */ + public function generate_secret_key() { + + $salt = wp_generate_password( 6 ); + + if ( defined( 'AUTH_KEY' ) ) { + $key = AUTH_KEY; + } else { + $key = wp_generate_password( 25 ); + } + + $key = sha1( $salt . get_current_blog_id() . $key . get_bloginfo( 'url' ) ); + + update_option( 'tribe_promoter_auth_key', $key ); + + return $key; + } +} diff --git a/tribe-common/src/Tribe/Promoter/Connector.php b/tribe-common/src/Tribe/Promoter/Connector.php new file mode 100644 index 0000000000..ad22acd351 --- /dev/null +++ b/tribe-common/src/Tribe/Promoter/Connector.php @@ -0,0 +1,275 @@ +base_url() . 'connect'; + + $payload = [ + 'clientSecret' => $secret_key, + 'licenseKey' => $license_key, + 'userId' => $user_id, + ]; + + $token = \Firebase\JWT\JWT::encode( $payload, $promoter_key ); + + $response = $this->make_call( $url, [ + 'body' => [ 'token' => $token ], + 'sslverify' => false, + ] ); + + return (bool) $response; + } + + /** + * Authenticate the current request user with the Auth Connector + * + * @param string $user_id User ID. + * + * @return bool|string User ID or if promoter is authorized then it return true like a valid user. + * + * @since 4.9 + */ + public function authenticate_user_with_connector( $user_id ) { + $this->authorized = false; + + // If user is already authenticated no need to move forward (wp-admin) and others. + if ( ! empty( $user_id ) ) { + $this->authorized = true; + return $user_id; + } + + $token = $this->get_token(); + + if ( empty( $token ) ) { + return $user_id; + } + + $url = $this->base_url() . 'connect/auth'; + + $response = $this->make_call( $url, [ + 'body' => [ 'token' => $token ], + 'sslverify' => false, + ] ); + + if ( ! $response ) { + return $user_id; + } + + $this->authorized = true; + + return $response; + } + + /** + * Get the token either from a request or a header + * + * @since 4.9.20 + * + * @return mixed + */ + protected function get_token() { + $request_token = $this->get_token_from_request(); + + return ( $request_token ) + ? sanitize_text_field( $request_token ) + : $this->get_token_from_headers(); + } + + /** + * Get the token from a Request variable if present, otherwise fallback to `null` + * + * @since 4.9.20 + * + * @return mixed + */ + protected function get_token_from_request() { + // Used in favor of tribe_get_request_var as at this point tribe_get_request_var is not defined. + return \Tribe__Utils__Array::get_in_any( + [ $_GET, $_POST, $_REQUEST ], + 'tribe_promoter_auth_token' + ); + } + + /** + * Get the token directly from a Bearer Authentication Header, for hosts that + * does not support large Query strings + * + * @since 4.9.20 + * + * @return mixed + */ + protected function get_token_from_headers() { + $headers = [ + 'HTTP_AUTHORIZATION', + 'REDIRECT_HTTP_AUTHORIZATION', + ]; + + foreach ( $headers as $header ) { + if ( empty( $_SERVER[ $header ] ) ) { + continue; + } + + list( $token ) = sscanf( $_SERVER[ $header ], 'Bearer %s' ); + + if ( $token ) { + return sanitize_text_field( $token ); + } + } + } + + /** + * Notify the Promoter app of changes within this system. + * + * @param int $post_id Post ID. + * + * @since 4.9 + */ + public function notify_promoter_of_changes( $post_id ) { + $post_type = get_post_type( $post_id ); + + if ( ! in_array( $post_type, [ 'tribe_events', 'tribe_tickets' ], true ) ) { + return; + } + + $secret_key = $this->get_secret_key(); + + if ( empty( $secret_key ) ) { + return; + } + + /** @var Tribe__Promoter__PUE $promoter_pue */ + $promoter_pue = tribe( 'promoter.pue' ); + $license_info = $promoter_pue->get_license_info(); + + if ( ! $license_info ) { + return; + } + + $license_key = $license_info['key']; + + $payload = [ + 'licenseKey' => $license_key, + 'sourceId' => $post_id instanceof WP_Post ? $post_id->ID : $post_id, + ]; + + $token = \Firebase\JWT\JWT::encode( $payload, $secret_key ); + + $url = $this->base_url() . 'connect/notify'; + + $args = [ + 'body' => [ 'token' => $token ], + 'sslverify' => false, + ]; + + $this->make_call( $url, $args ); + } + + /** + * Get the value for the option `tribe_promoter_auth_key` + * + * @since 4.9.12 + * + * @return mixed + */ + public function get_secret_key() { + $secret_key = get_option( 'tribe_promoter_auth_key' ); + + /** + * @since 4.9.12 + * + * @param string $secret_key + */ + return apply_filters( 'tribe_promoter_secret_key', $secret_key ); + } + + /** + * Make the call to the remote endpoint. + * + * @since 4.9 + * + * @param array $args Data to send. + * + * @param string $url URL to send data to. + * + * @return string|false The response body or false if not successful. + * + */ + public function make_call( $url, $args ) { + $response = wp_remote_post( $url, wp_parse_args( $args, [ 'timeout' => 30 ] ) ); + $code = wp_remote_retrieve_response_code( $response ); + $body = wp_remote_retrieve_body( $response ); + + if ( $code > 299 || is_wp_error( $response ) ) { + do_action( + 'tribe_log', + 'debug', + __METHOD__, + [ + 'url' => $url, + 'args' => $args, + 'response' => $response, + 'response_code' => $code, + ] + ); + + return false; + } + + return $body; + } + + /** + * Check whether the user request is currently authorized by Promoter. + * + * @since 4.9.4 + * + * @return bool Whether the user request is currently authorized by Promoter. + */ + public function is_user_authorized() { + return $this->authorized; + } +} diff --git a/tribe-common/src/Tribe/Promoter/PUE.php b/tribe-common/src/Tribe/Promoter/PUE.php new file mode 100644 index 0000000000..0900c1d4e9 --- /dev/null +++ b/tribe-common/src/Tribe/Promoter/PUE.php @@ -0,0 +1,96 @@ +pue_checker = new Tribe__PUE__Checker( 'http://tri.be/', $this->slug, [ + 'context' => 'service', + 'plugin_name' => __( 'Promoter', 'tribe-common' ), + ] ); + } + + /** + * Get whether service has a license and if the license is activated on network. + * + * @return array|false License information or false if not set. + * + * @since 4.9 + */ + public function get_license_info() { + $option_name = 'pue_install_key_' . $this->slug; + + $key = get_option( $option_name ); + + $is_network_key = false; + + if ( is_multisite() ) { + $network_key = get_network_option( null, $option_name ); + + if ( empty( $key ) ) { + $key = $network_key; + + $is_network_key = true; + } + } + + if ( empty( $key ) ) { + return false; + } + + return [ + 'key' => $key, + 'is_network_key' => $is_network_key, + ]; + } + + /** + * Check whether service has a license key set or not. + * + * @return bool Whether service has a license key set. + * + * @since 4.9 + */ + public function has_license_key() { + return ! empty( $this->get_license_info() ); + } + + /** + * Check whether service has a valid license key or not. + * + * @return bool Whether service has a valid license key. + * + * @since 4.9 + */ + public function has_valid_license() { + $license_info = $this->get_license_info(); + + if ( ! $license_info ) { + return false; + } + + $response = $this->pue_checker->validate_key( $license_info['key'], $license_info['is_network_key'] ); + + return isset( $response['status'] ) && 1 === (int) $response['status']; + } + +} diff --git a/tribe-common/src/Tribe/Promoter/View.php b/tribe-common/src/Tribe/Promoter/View.php new file mode 100644 index 0000000000..f2fe93a828 --- /dev/null +++ b/tribe-common/src/Tribe/Promoter/View.php @@ -0,0 +1,96 @@ +set_template_origin( Tribe__Main::instance() ); + $this->set_template_folder( 'src/views/promoter' ); + $this->set_template_context_extract( true ); + $this->set_template_folder_lookup( true ); + } + + /** + * Add the rewrite rules and tags. + * + * @since 4.9 + */ + public function add_rewrites() { + add_rewrite_rule( 'tribe-promoter-auth/?$', 'index.php?tribe-promoter-auth-check=1', 'top' ); + add_rewrite_tag( '%tribe-promoter-auth-check%', '([^&]+)' ); + } + + /** + * Get the redirect URL for finishing onboarding + * + * @since 4.9.6 + * + * @return string Redirect URL for completing onboarding. + */ + public function authorized_redirect_url() { + $url = 'https://promoter.theeventscalendar.com/welcome/review'; + + if ( defined( 'TRIBE_PROMOTER_AUTHORIZED_REDIRECT_URL' ) ) { + $url = TRIBE_PROMOTER_AUTHORIZED_REDIRECT_URL; + } + + /** + * The url for redirecting in order to complete onboarding + * + * @since 4.9.6 + * + * @param string $url Redirect URL. + */ + return apply_filters( 'tribe_promoter_authorized_redirect_url', $url ); + } + + /** + * Display the auth check page when the correct permalink is loaded. + * + * @since 4.9 + */ + public function display_auth_check_view() { + global $wp_query; + + $promoter_key = tribe_get_request_var( 'promoter_key' ); + $license_key = tribe_get_request_var( 'license_key' ); + + if ( empty( $promoter_key ) || empty( $wp_query->query_vars['tribe-promoter-auth-check'] ) ) { + return; + } + + $is_admin = is_user_logged_in() && current_user_can( 'manage_options' ) && current_user_can( 'read_private_posts' ); + $authorized = false; + $auth_error = false; + + if ( $is_admin && ! empty( $_POST['promoter_authenticate'] ) ) { + /** @var Tribe__Promoter__Auth $promoter_auth */ + $promoter_auth = tribe( 'promoter.auth' ); + $authorized = $promoter_auth->authorize_with_connector(); + $auth_error = ! $authorized; + } + + if ( $authorized ) { + wp_redirect( esc_url_raw( $this->authorized_redirect_url() ) ); + } else { + $this->template( 'auth', [ + 'authorized' => $authorized, + 'auth_error' => $auth_error, + 'logged_in' => is_user_logged_in(), + 'admin' => $is_admin, + 'promoter_key' => $promoter_key, + 'license_key' => $license_key, + ], true ); + } + + tribe_exit(); + } + +} diff --git a/tribe-common/src/Tribe/REST/Endpoints/CREATE_Endpoint_Interface.php b/tribe-common/src/Tribe/REST/Endpoints/CREATE_Endpoint_Interface.php new file mode 100644 index 0000000000..0b4b5eee2c --- /dev/null +++ b/tribe-common/src/Tribe/REST/Endpoints/CREATE_Endpoint_Interface.php @@ -0,0 +1,29 @@ +message = $message; + $this->code = $code; + $this->status = $status; + } + + /** + * Return the error status. + * @return int + */ + public function getStatus() { + return $this->status; + } +} diff --git a/tribe-common/src/Tribe/REST/Headers/Base_Header.php b/tribe-common/src/Tribe/REST/Headers/Base_Header.php new file mode 100644 index 0000000000..a420ca07b8 --- /dev/null +++ b/tribe-common/src/Tribe/REST/Headers/Base_Header.php @@ -0,0 +1,19 @@ +base = $base; + } +} diff --git a/tribe-common/src/Tribe/REST/Headers/Base_Interface.php b/tribe-common/src/Tribe/REST/Headers/Base_Interface.php new file mode 100644 index 0000000000..4cf32f0adc --- /dev/null +++ b/tribe-common/src/Tribe/REST/Headers/Base_Interface.php @@ -0,0 +1,49 @@ +base->get_api_version_header() . ': disabled' ); + } +} diff --git a/tribe-common/src/Tribe/REST/Headers/Headers_Interface.php b/tribe-common/src/Tribe/REST/Headers/Headers_Interface.php new file mode 100644 index 0000000000..554520867b --- /dev/null +++ b/tribe-common/src/Tribe/REST/Headers/Headers_Interface.php @@ -0,0 +1,18 @@ +main = $main; + } + + /** + * Prints TEC REST API related meta on the site. + */ + public function add_header() { + $api_root = $this->base->get_rest_url(); + + if ( empty( $api_root ) ) { + return; + } + + printf( '', esc_attr( $this->base->get_api_version_meta_name() ), esc_attr( $this->main->get_version() ) ); + printf( '', esc_attr( $this->base->get_api_origin_meta_name() ), esc_url( $this->base->get_rest_origin_url() ) ); + printf( '', esc_attr( $this->main->get_reference_url() ), esc_url( $api_root ) ); + } + + /** + * Sends TEC REST API related headers. + */ + public function send_header() { + if ( headers_sent() ) { + return; + } + + $api_root = $this->base->get_rest_url(); + + if ( empty( $api_root ) ) { + return; + } + + header( $this->base->get_api_version_header() . ': ' . $this->main->get_version() ); + header( $this->base->get_api_root_header() . ': ' . esc_url_raw( $api_root ) ); + header( $this->base->get_api_origin_header() . ': ' . esc_url_raw( $this->base->get_rest_origin_url() ) ); + } +} diff --git a/tribe-common/src/Tribe/REST/Headers/Unsupported.php b/tribe-common/src/Tribe/REST/Headers/Unsupported.php new file mode 100644 index 0000000000..af8e3b5a5a --- /dev/null +++ b/tribe-common/src/Tribe/REST/Headers/Unsupported.php @@ -0,0 +1,39 @@ +main = $main; + } + + /** + * Prints TEC REST API related meta on the site. + */ + public function add_header() { + // no-op + } + + /** + * Sends TEC REST API related headers. + */ + public function send_header() { + if ( headers_sent() ) { + return; + } + + header( $this->base->get_api_version_header() . ': unsupported' ); + } +} diff --git a/tribe-common/src/Tribe/REST/Main.php b/tribe-common/src/Tribe/REST/Main.php new file mode 100644 index 0000000000..73b3504136 --- /dev/null +++ b/tribe-common/src/Tribe/REST/Main.php @@ -0,0 +1,149 @@ +namespace; + } + + /** + * Returns the REST API URL prefix. + * + * @return string The REST API URL prefix. + */ + public function get_url_prefix() { + $use_builtin = $this->use_builtin(); + + if ( $use_builtin ) { + $prefix = rest_get_url_prefix(); + } else { + $prefix = apply_filters( 'rest_url_prefix', 'wp-json' ); + } + + $default_tec_prefix = $this->namespace . '/' . trim( $this->url_prefix(), '/' ); + $prefix = rtrim( $prefix, '/' ) . '/' . trim( $default_tec_prefix, '/' ); + + /** + * Filters the TEC REST API URL prefix + * + * @param string $prefix The complete URL prefix. + * @param string $default_tec_prefix The default URL prefix appended to the REST URL by The Events Calendar. + */ + return apply_filters( 'tribe_events_rest_url_prefix', $prefix, $default_tec_prefix ); + } + + /** + * Retrieves the URL to a TEC REST endpoint on a site. + * + * Note: The returned URL is NOT escaped. + * + * @global WP_Rewrite $wp_rewrite + * + * @param string $path Optional. TEC REST route. Default '/'. + * @param string $scheme Optional. Sanitization scheme. Default 'rest'. + * @param int $blog_id Optional. Blog ID. Default of null returns URL for current blog. + * + * @return string Full URL to the endpoint. + */ + public function get_url( $path = '/', $scheme = 'rest', $blog_id = null ) { + if ( empty( $path ) ) { + $path = '/'; + } + + $tec_path = '/' . trim( $this->namespace, '/' ) . $this->url_prefix() . '/' . ltrim( $path, '/' ); + + if ( $this->use_builtin() ) { + $url = get_rest_url( $blog_id, $tec_path, $scheme ); + } else { + if ( ( is_multisite() && get_blog_option( $blog_id, 'permalink_structure' ) ) || get_option( 'permalink_structure' ) ) { + global $wp_rewrite; + + if ( $wp_rewrite->using_index_permalinks() ) { + $url = get_home_url( $blog_id, $wp_rewrite->index . '/' . self::get_url_prefix(), $scheme ); + } else { + $url = get_home_url( $blog_id, self::get_url_prefix(), $scheme ); + } + + $url .= '/' . ltrim( $path, '/' ); + } else { + $url = get_home_url( $blog_id, 'index.php', $scheme ); + + $url = add_query_arg( 'rest_route', $tec_path, $url ); + } + + if ( is_ssl() ) { + // If the current host is the same as the REST URL host, force the REST URL scheme to HTTPS. + if ( $_SERVER['SERVER_NAME'] === parse_url( get_home_url( $blog_id ), PHP_URL_HOST ) ) { + $url = set_url_scheme( $url, 'https' ); + } + } + } + + /** + * Filters The Events Calendar REST URL. + * + * @param string $url TEC REST URL. + * @param string $path REST route. + * @param int $blog_id Blog ID. + * @param string $scheme Sanitization scheme. + */ + return apply_filters( 'tribe_rest_url', $url, $path, $blog_id, $scheme ); + } + + /** + * Whether built-in WP REST API functions and functionalities should/can be used or not. + * + * @return bool + */ + protected function use_builtin() { + /** + * Filters whether builtin WordPress REST API functions should be used or not if available. + */ + $use_builtin = apply_filters( 'tribe_events_rest_use_builtin', true ); + + return $use_builtin && function_exists( 'get_rest_url' ); + } + + /** + * Returns the REST API URL prefix that will be appended to the namespace. + * + * The prefix should be in the `/some/path` format. + * + * @return string + */ + abstract protected function url_prefix(); + + /** + * Returns the string indicating the REST API version. + * + * @return string + */ + abstract public function get_version(); + + /** + * Returns the URL where the API users will find the API documentation. + * + * @return string + */ + abstract public function get_reference_url(); +} diff --git a/tribe-common/src/Tribe/REST/Messages_Interface.php b/tribe-common/src/Tribe/REST/Messages_Interface.php new file mode 100644 index 0000000000..13edb0360c --- /dev/null +++ b/tribe-common/src/Tribe/REST/Messages_Interface.php @@ -0,0 +1,30 @@ + => ]` format. + */ + public function get_messages(); + + /** + * Prefixes a message slug with a common root. + * + * @param string $message_slug + * + * @return string The prefixed message slug. + */ + public function prefix_message_slug( $message_slug ); +} diff --git a/tribe-common/src/Tribe/REST/Post_Repository.php b/tribe-common/src/Tribe/REST/Post_Repository.php new file mode 100644 index 0000000000..274e18327d --- /dev/null +++ b/tribe-common/src/Tribe/REST/Post_Repository.php @@ -0,0 +1,107 @@ + $full_url, + 'id' => $image_id, + 'extension' => pathinfo( $file, PATHINFO_EXTENSION ), + ]; + + $metadata = wp_get_attachment_metadata( $image_id ); + + if ( + false !== $metadata + && isset( $metadata['image_meta'], $metadata['file'], $metadata['sizes'] ) + ) { + unset( $metadata['image_meta'], $metadata['file'] ); + + foreach ( $metadata['sizes'] as $size => &$meta ) { + $size_image_src = wp_get_attachment_image_src( $image_id, $size ); + $meta['url'] = ! empty( $size_image_src[0] ) ? $size_image_src[0] : ''; + unset( $meta['file'] ); + } + unset( $meta ); + + $data = array_filter( array_merge( $data, $metadata ) ); + } + + return $data; + } + + /** + * @param string $date A date string in a format `strtotime` can parse. + * + * @return array An array of date details for the end date; each entry will be + * empty if the date is empty. + */ + protected function get_date_details( $date ) { + if ( empty( $date ) ) { + return [ + 'year' => '', + 'month' => '', + 'day' => '', + 'hour' => '', + 'minutes' => '', + 'seconds' => '', + ]; + } + + $time = strtotime( $date ); + + return [ + 'year' => date( 'Y', $time ), + 'month' => date( 'm', $time ), + 'day' => date( 'd', $time ), + 'hour' => date( 'H', $time ), + 'minutes' => date( 'i', $time ), + 'seconds' => date( 's', $time ), + ]; + } + + /** + * Returns a localized and formatted list of cost values in ASC order. + * + * @since 4.7.19 + * + * @param array $cost_couples An array of cost couples in the [ => ] format. + * + * @return array + */ + protected function format_and_sort_cost_couples( array $cost_couples = [] ) { + global $wp_locale; + + $cost_values = []; + foreach ( $cost_couples as $key => $value ) { + $value = str_replace( + [ + $wp_locale->number_format['decimal_point'], + $wp_locale->number_format['thousands_sep'], + ], + [ '.', '' ], + '' . $value + ); + if ( is_numeric( $value ) ) { + $cost_values[] = $value; + } else { + $cost_values[] = $key; + } + } + + sort( $cost_values, SORT_NUMERIC ); + + return $cost_values; + } +} diff --git a/tribe-common/src/Tribe/REST/Post_Repository_Interface.php b/tribe-common/src/Tribe/REST/Post_Repository_Interface.php new file mode 100644 index 0000000000..096c8908ff --- /dev/null +++ b/tribe-common/src/Tribe/REST/Post_Repository_Interface.php @@ -0,0 +1,14 @@ + 'post', + 'suppress_filters' => false, + 'posts_per_page' => -1, + ]; + + /** + * @var array A list of query modifiers that will trigger a overriding merge, thus + * replacing previous values, when set multiple times. + */ + protected static $replacing_modifiers = [ + 'p', + 'author', + 'author_name', + 'author__in', + 'author__not_in', + 'has_password', + 'post_password', + 'cat', + 'category__and', + 'category__in', + 'category__not_in', + 'category_name', + 'comment_count', + 'comment_status', + 'menu_order', + 'title', + 'title_like', + 'name', + 'post_name__in', + 'ping_status', + 'post__in', + 'post__not_in', + 'post_parent', + 'post_parent__in', + 'post_parent__not_in', + 'post_mime_type', + 's', + 'search', + 'tag', + 'tag__and', + 'tag__in', + 'tag__not_in', + 'tag_id', + 'tag_slug__and', + 'tag_slug__in', + 'ID', + 'id', + 'date', + 'after_date', + 'before_date', + 'date_gmt', + 'after_date_gmt', + 'before_date_gmt', + 'post_title', + 'post_content', + 'post_excerpt', + 'post_status', + 'to_ping', + 'post_modified', + 'post_modified_gmt', + 'post_content_filtered', + 'guid', + 'perm', + 'order', + ]; + + /** + * @var int + */ + protected static $meta_alias = 0; + + /** + * @var array A list of keys that denote the value to check should be cast to array. + */ + protected static $multi_value_keys = [ 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ]; + + /** + * @var array A map of SQL comparison operators to their human-readable counterpart. + */ + protected static $comparison_operators = [ + '=' => 'equals', + '!=' => 'not-equals', + '>' => 'gt', + '>=' => 'gte', + '<' => 'lt', + '<=' => 'lte', + 'LIKE' => 'like', + 'NOT LIKE' => 'not-like', + 'IN' => 'in', + 'NOT IN' => 'not-in', + 'BETWEEN' => 'between', + 'NOT BETWEEN' => 'not-between', + 'EXISTS' => 'exists', + 'NOT EXISTS' => 'not-exists', + 'REGEXP' => 'regexp', + 'NOT REGEXP' => 'not-regexp', + ]; + + /** + * A counter to keep track, on the class level, of the aliases generated for the terms table + * while building multi queries. + * + * @var int + */ + protected static $alias_counter = 1; + + /** + * @var string + */ + protected $filter_name = 'default'; + /** + * @var array The post IDs that will be updated. + */ + protected $ids = []; + /** + * @var bool Whether the post IDs to update have already been fetched or not. + */ + protected $has_ids = false; + /** + * @var array The updates that will be saved to the database. + */ + protected $updates = []; + + /** + * @var array A list of taxonomies this repository will recognize. + */ + protected $taxonomies = []; + + /** + * @var array A map detailing which fields should be converted from a + * GMT time and date to a local one. + */ + protected $to_local_time_map = [ + 'post_date_gmt' => 'post_date', + ]; + + /** + * @var array A map detailing which fields should be converted from a + * localized time and date to a GMT one. + */ + protected $to_gmt_map = [ + 'post_date' => 'post_date_gmt', + ]; + + /** + * @var array + */ + protected $default_args = [ 'post_type' => 'post' ]; + + /** + * @var array An array of query modifying callbacks populated while applying + * the filters. + */ + protected $query_modifiers = []; + + /** + * @var bool Whether the current query is void or not. + */ + protected $void_query = false; + + /** + * @var array An array of query arguments that will be populated while applying + * filters. + */ + protected $query_args = [ + 'meta_query' => [ 'relation' => 'AND' ], + 'tax_query' => [ 'relation' => 'AND' ], + 'date_query' => [ 'relation' => 'AND' ], + ]; + + /** + * @var array An array of query arguments that support 'relation'. + */ + protected $relation_query_args = [ + 'meta_query', + 'tax_query', + 'date_query', + ]; + + /** + * @var WP_Query The current query object built and modified by the instance. + */ + protected $current_query; + + /** + * @var array An associative array of the filters that will be applied and the used values. + */ + protected $current_filters = []; + + /** + * @var string|null The current filter being applied. + */ + protected $current_filter; + + /** + * @var Tribe__Repository__Query_Filters + */ + public $filter_query; + + /** + * @var string The filter that should be used to get a post by its primary key. + */ + protected $primary_key = 'p'; + + /** + * @var array A map of callbacks in the shape [ => ] + */ + protected $schema = []; + + /** + * @var array A map of schema slugs and their meta keys to be queried. + */ + protected $simple_meta_schema = []; + + /** + * @var array A map of schema slugs and their taxonomies to be queried. + */ + protected $simple_tax_schema = []; + + /** + * @var Tribe__Repository__Interface + */ + protected $main_repository; + + /** + * @var Tribe__Repository__Formatter_Interface + */ + protected $formatter; + + /** + * @var bool + */ + protected $skip_found_rows = true; + + /** + * @var Tribe__Repository__Interface + */ + protected $query_builder; + + /** + * A map relating aliases to their real update field name. + * + * E.g. the `title` alias might be an alias of `post_title` in update/save operations. + * This is done to allow using set-like methods with human-readable names. + * Extending classes should pre-fill this with default aliases. + * + * @var array + */ + protected $update_fields_aliases = [ + 'title' => 'post_title', + 'content' => 'post_content', + 'description' => 'post_content', + 'slug' => 'post_name', + 'excerpt' => 'post_excerpt', + 'status' => 'post_status', + 'parent' => 'post_parent', + 'author' => 'post_author', + 'date' => 'post_date', + 'date_gmt' => 'post_date_gmt', + 'date_utc' => 'post_date_gmt', + 'tag' => 'post_tag', + 'image' => '_thumbnail_id', + ]; + + /** + * The default create args that will be used by the repository + * to create posts of the managed type. + * + * @var + */ + protected $create_args; + + /** + * Indicates the current display context if any. + * Extending classes can support and use this property to know the + * display context. + * + * @var string + */ + protected $display_context = 'default'; + + /** + * Indicates the current render context if any. + * Extending classes can support and use this property to know the + * render context. + * + * @var string + */ + protected $render_context = 'default'; + + /** + * The query last built from the repository instance. + * + * @var WP_Query|null + */ + protected $last_built_query; + + /** + * The hash of the last built query. + * + * @var string + */ + protected $last_built_hash = ''; + + /** + * Tribe__Repository constructor. + * + * @since 4.7.19 + */ + public function __construct() { + $this->filter_query = new Tribe__Repository__Query_Filters(); + $this->default_args = array_merge( [ 'posts_per_page' => -1 ], $this->default_args ); + $post_types = (array) Tribe__Utils__Array::get( $this->default_args, 'post_type', [] ); + $this->taxonomies = get_taxonomies( [ 'object_type' => $post_types ], 'names' ); + + /** + * Allow plugins to init their classes and setup hooks at the initial setup of a repository. + * + * @param Tribe__Repository $this This repository instance + * + * @since 4.9.5 + */ + do_action( "tribe_repository_{$this->filter_name}_init", $this ); + } + + /** + * {@inheritdoc} + */ + public function get_default_args() { + return $this->default_args; + } + + /** + * {@inheritdoc} + */ + public function set_default_args( array $default_args ) { + $this->default_args = $default_args; + } + + /** + * Returns the value of a protected property. + * + * @since 4.7.19 + * + * @param string $name + * + * @return mixed|null + * @throws Tribe__Repository__Usage_Error If trying to access a non defined property. + */ + public function __get( $name ) { + if ( ! property_exists( $this, $name ) ) { + throw Tribe__Repository__Usage_Error::because_property_is_not_defined( $name, $this ); + } + + return $this->{$name}; + } + + /** + * Magic method to set protected properties. + * + * @since 4.7.19 + * + * @param string $name + * @param mixed $value + * + * @throws Tribe__Repository__Usage_Error As properties have to be set extending + * the class, using setter methods or via constructor injection + */ + public function __set( $name, $value ) { + throw Tribe__Repository__Usage_Error::because_properties_should_be_set_correctly( $name, $this ); + } + + /** + * Whether the class has a property with the specific name or not. + * + * @since 4.7.19 + * + * @param string $name + * + * @return bool + */ + public function __isset( $name ) { + return property_exists( $this, $name ) && isset( $this->{$name} ); + } + + /** + * {@inheritdoc} + */ + public function where( $key, $value = null ) { + $call_args = func_get_args(); + + return call_user_func_array( [ $this, 'by' ], $call_args ); + } + + /** + * {@inheritdoc} + */ + public function page( $page ) { + $this->query_args['paged'] = absint( $page ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function per_page( $per_page ) { + // we allow for `-1` here + $this->query_args['posts_per_page'] = $per_page; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function count() { + if ( $this->void_query ) { + return 0; + } + + $query = $this->build_query(); + + // The request property will be set during the `get_posts` method and empty before it. + if ( ! empty( $query->request ) ) { + return (int) $query->post_count; + } + + $original_fields_value = $query->get( 'fields', '' ); + + $query->set( 'fields', 'ids' ); + + /** + * Filters the query object by reference before counting found posts in the current page. + * + * @since 4.7.19 + * + * @param WP_Query $query + */ + do_action( "tribe_repository_{$this->filter_name}_pre_count_posts", $query ); + + $ids = $query->get_posts(); + + $query->set( 'fields', $original_fields_value ); + + return is_array( $ids ) ? count( $ids ) : 0; + } + + /** + * {@inheritdoc} + */ + public function build_query( $use_query_builder = true ) { + $query = null; + + if ( array_key_exists( 'void_query', $this->query_args ) && false !== $this->query_args['void_query'] ) { + $this->void_query = true; + } + + // We'll let the query builder decide if the query has to be rebuilt or not. + if ( $use_query_builder && null !== $this->query_builder ) { + $query = $this->build_query_with_builder(); + } + + if ( null !== $this->last_built_query && $this->last_built_hash === $this->hash()) { + return $this->last_built_query; + } + + if ( null === $query ) { + $query = $this->build_query_internally(); + } + + /** + * Fires after the query has been built and before it's returned. + * + * @since 4.9.5 + * + * @param WP_Query $query The built query. + * @param array $query_args An array of query arguments used to build the query. + * @param Tribe__Repository $this This repository instance. + * @param bool $use_query_builder Whether a query builder was used to build this query or not. + * @param Tribe__Repository__Interface $query_builder The query builder in use, if any. + */ + do_action( "tribe_repository_{$this->filter_name}_query", + $query, + $this, + $use_query_builder, + $this->query_builder + ); + + $this->last_built_query = $query; + $this->last_built_hash = $this->hash(); + + return $query; + } + + /** + * {@inheritdoc} + */ + public function found() { + if ( $this->void_query ) { + return 0; + } + + $query = $this->build_query(); + + $original_no_found_rows_value = $query->get( 'no_found_rows' ); + + // The request property will be set during the `get_posts` method and empty before it. + if ( ! empty( $query->request ) && ( false === (boolean) $original_no_found_rows_value || ! $this->skip_found_rows ) ) { + return (int) $query->found_posts; + } + + $original_fields_value = $query->get( 'fields' ); + + $query->set( 'fields', 'ids' ); + $query->set( 'no_found_rows', false ); + + /** + * Filters the query object by reference before counting found posts. + * + * @since 4.7.19 + * + * @param WP_Query $query + */ + do_action( "tribe_repository_{$this->filter_name}_pre_found_posts", $query ); + + $query->get_posts(); + + $query->set( 'fields', $original_fields_value ); + $query->set( 'no_found_rows', $original_no_found_rows_value ); + + return (int) $query->found_posts; + } + + /** + * {@inheritdoc} + */ + public function all() { + if ( $this->void_query ) { + return []; + } + + $query = $this->build_query(); + + // The request property will be set during the `get_posts` method and empty before it. + if ( ! empty( $query->request ) ) { + return array_map( [ $this, 'format_item' ], $query->posts ); + } + + $original_fields_value = $query->get( 'fields', '' ); + + $return_ids = 'ids' === $original_fields_value; + + /** + * Do not skip counting the rows if we have some filtering to do on + * `found_posts`. + */ + $query->set( 'no_found_rows', $this->skip_found_rows ); + + // We'll let the class build the items later. + $query->set( 'fields', 'ids' ); + + /** + * Filters the query object by reference before getting the posts. + * + * @since 4.7.19 + * + * @param WP_Query $query + */ + do_action( "tribe_repository_{$this->filter_name}_pre_get_posts", $query ); + + $results = $query->get_posts(); + + /** + * Allow extending classes to customize the return value. + * Since we are filtering the array returning empty values while formatting + * the item will exclude it from the return values. + */ + $formatted = $return_ids + ? $results + : array_filter( array_map( [ $this, 'format_item' ], $results ) ); + + // Reset the fields if required. + $query->set( 'fields', $original_fields_value ); + + return $formatted; + } + + /** + * {@inheritdoc} + */ + public function offset( $offset, $increment = false ) { + /** + * The `offset` argument will only be used when `posts_per_page` is not -1 + * and will ignore pagination. + * So we filter to apply a real SQL OFFSET; we also leave in place the `offset` + * query var to have a fallback should the LIMIT cause proving difficult to filter. + */ + $this->query_args['offset'] = $increment + ? absint( $offset ) + (int) Tribe__Utils__Array::get( $this->query_args, 'offset', 0 ) + : absint( $offset ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function order( $order = 'ASC' ) { + $order = strtoupper( $order ); + + if ( ! in_array( $order, [ 'ASC', 'DESC' ], true ) ) { + return $this; + } + + $this->query_args['order'] = $order; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function order_by( $order_by, $order = 'DESC' ) { + $this->query_args['orderby'] = $order_by; + + // Based on `WP_Query->parse_orderby` we should ignore the global order passed, and use the value on for each item in array. + if ( ! is_array( $order_by ) ) { + $this->query_args['order'] = $order; + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function fields( $fields ) { + $this->query_args['fields'] = $fields; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function permission( $permission ) { + if ( ! in_array( $permission, [ self::PERMISSION_READABLE, self::PERMISSION_EDITABLE ], true ) ) { + return $this; + } + + $this->query_args['perm'] = $permission; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function in( $post_ids ) { + $this->add_args( 'post__in', $post_ids ); + + return $this; + } + + /** + * Merges arguments into a query arg. + * + * @since 4.7.19 + * + * @param string $key + * @param array|int $value + */ + protected function add_args( $key, $value ) { + $this->query_args[ $key ] = (array) $value; + } + + /** + * {@inheritdoc} + */ + public function not_in( $post_ids ) { + $this->add_args( 'post__not_in', $post_ids ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function parent( $post_id ) { + $this->add_args( 'post_parent__in', $post_id ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function parent_in( $post_ids ) { + $this->add_args( 'post_parent__in', $post_ids ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function parent_not_in( $post_ids ) { + $this->add_args( 'post_parent__not_in', $post_ids ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function search( $search ) { + $this->query_args['s'] = $search; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function first() { + $query = $this->build_query(); + + $original_fields_value = $query->get( 'fields', '' ); + + $return_id = 'ids' === $original_fields_value; + + // The request property will be set during the `get_posts` method and empty before it. + if ( ! empty( $query->request ) ) { + $ids = $this->get_ids(); + + if ( empty( $ids ) ) { + return null; + } + + return $return_id ? reset( $ids ) : $this->format_item( reset( $ids ) ); + } + + $query->set( 'fields', 'ids' ); + $ids = $query->get_posts(); + + $query->set( 'fields', $original_fields_value ); + + if ( empty( $ids ) ) { + return null; + } + + return $return_id ? reset( $ids ) : $this->format_item( reset( $ids ) ); + } + + /** + * Formats a post handled by the repository to the expected + * format. + * + * Extending classes should use this method to format return values to the expected format. + * + * @since 4.7.19 + * + * @param int|WP_Post $id + * + * @return WP_Post + */ + protected function format_item( $id ) { + $formatted = null === $this->formatter + ? get_post( $id ) + : $this->formatter->format_item( $id ); + + /** + * Filters a single formatted result. + * + * @since 4.9.11 + * + * @param mixed|WP_Post $formatted The formatted post result, usually a post object. + * @param int $id The formatted post ID. + * @param Tribe__Repository__Interface $this The current repository object. + */ + $formatted = apply_filters( "tribe_repository_{$this->filter_name}_format_item", $formatted, $id, $this ); + + return $formatted; + } + + /** + * {@inheritdoc} + */ + public function last() { + $query = $this->build_query(); + + $original_fields_value = $query->get('fields', ''); + + $return_id = 'ids' === $original_fields_value; + + // The request property will be set during the `get_posts` method and empty before it. + if ( ! empty( $query->request ) ) { + $ids = $this->get_ids(); + + if ( empty( $ids ) ) { + return null; + } + + return $return_id ? end( $ids ) : $this->format_item( end( $ids ) ); + } + + $query->set( 'fields', 'ids' ); + $ids = $query->get_posts(); + + $query->set( 'fields', $original_fields_value ); + + if ( empty( $ids ) ) { + return null; + } + + return $return_id ? end( $ids ) : $this->format_item( end( $ids ) ); + } + + /** + * {@inheritdoc} + */ + public function nth( $n ) { + $per_page = (int) Tribe__Utils__Array::get_in_any( [ + $this->query_args, + $this->default_args, + ], 'posts_per_page', get_option( 'posts_per_page' ) ); + + if ( - 1 !== $per_page && $n > $per_page ) { + return null; + } + + $query = $this->build_query(); + + $return_ids = 'ids' === $query->get( 'fields', '' ); + + $i = absint( $n ) - 1; + + $ids = $this->get_ids(); + + if ( empty( $ids[ $i ] ) ) { + return null; + } + + return $return_ids ? $ids[ $i ] : $this->format_item( $ids[ $i ] ); + } + + /** + * Applies and returns a schema entry. + * + * @since 4.7.19 + * + * @param string $key + * @param mixed $value + * @param mixed ...$args Additional arguments for the application. + * + * @return mixed A scalar value or a callable. + */ + public function apply_modifier( $key, $value = null ) { + $call_args = func_get_args(); + + $application = Tribe__Utils__Array::get( $this->schema, $key, null ); + + /** + * Return primitives, including `null`, as they are. + */ + if ( ! is_callable( $application ) ) { + return $application; + } + + /** + * Allow for callbacks to fire immediately and return more complex values. + * This also means that callbacks meant to run on the next step, the one + * where args are applied, will need to be "wrapped" in callbacks themselves. + * The `$key` is removed from the args to get the value first and avoid + * unused args. + */ + $args_without_key = array_splice( $call_args, 1 ); + + $schema_entry = call_user_func_array( $application, $args_without_key ); + + /** + * Filters the applied modifier schema entry response. + * + * @param mixed $schema_entry A scalar value or a callable. + * @param Tribe__Repository $this This repository instance + * + * @since 4.9.5 + */ + return apply_filters( "tribe_repository_{$this->filter_name}_apply_modifier_schema_entry", $schema_entry, $this ); + } + + /** + * {@inheritdoc} + */ + public function take( $n ) { + $query = $this->build_query(); + + $return_ids = 'ids' === $query->get( 'fields', '' ); + + $matching_ids = $this->get_ids(); + + if ( empty( $matching_ids ) ) { + return []; + } + + $spliced = array_splice( $matching_ids, 0, $n ); + + return $return_ids ? $spliced : array_map( [ $this, 'format_item' ], $spliced ); + } + + /** + * Fetches a single instance of the post type handled by the repository. + * + * Similarly to the `get_post` function permissions are not taken into account when returning + * an instance by its primary key; extending classes can refine this behaviour to suit. + * + * @param mixed $primary_key + * + * @return WP_Post|null|mixed + */ + public function by_primary_key( $primary_key ) { + return $this->by( $this->primary_key, $primary_key )->first(); + } + + /** + * Filters posts by simple meta schema value. + * + * @since 4.9.5 + * + * @param mixed $value Meta value. + */ + public function filter_by_simple_meta_schema( $value ) { + $filter = $this->get_current_filter(); + + if ( ! array_key_exists( $filter, $this->simple_meta_schema ) ) { + return; + } + + $simple_meta = $this->simple_meta_schema[ $filter ]; + + $by = Tribe__Utils__Array::get( $simple_meta, 'by', 'meta_regexp_or_like' ); + + $this->by( $by, $simple_meta['meta_key'], $value ); + } + + /** + * Filters posts by simple tax schema value. + * + * @since 4.9.5 + * + * @param int|string|array $value Term value(s). + */ + public function filter_by_simple_tax_schema( $value ) { + $filter = $this->get_current_filter(); + + if ( ! array_key_exists( $filter, $this->simple_tax_schema ) ) { + return; + } + + $simple_tax = $this->simple_tax_schema[ $filter ]; + + $by = Tribe__Utils__Array::get( $simple_tax, 'by', 'term_in' ); + + $this->by( $by, $simple_tax['taxonomy'], $value ); + } + + /** + * {@inheritdoc} + */ + public function by( $key, $value = null ) { + if ( $this->void_query || ( 'void_query' === $key && false !== $value ) ) { + $this->void_query = true; + + // No point in doing more computations if the query is void. + return $this; + } + + $call_args = func_get_args(); + + $this->current_filters[ $key ] = array_slice( $call_args, 1 ); + + try { + // Set current filter as which one we are running. + $this->current_filter = $key; + + $query_modifier = $this->modify_query( $key, $call_args ); + + // Set current filter as no longer active, we aren't running it anymore. + $this->current_filter = null; + + /** + * Here we allow the repository to call one of its own methods and return `null`. + * A repository might have a `where` or `by` that is just building + * a more complex query using a base `where` or `by`. + */ + if ( null === $query_modifier ) { + return $this; + } + + /** + * Primitives are just merged in. + * Since we are using `array_merge_recursive` we expect them to be arrays. + */ + if ( ! ( is_object( $query_modifier ) || is_callable( $query_modifier ) ) ) { + + if ( ! is_array( $query_modifier ) ) { + throw new InvalidArgumentException( 'Query modifier should be an array!' ); + } + + $replace_modifiers = in_array( $key, $this->replacing_modifiers(), true ); + if ( $replace_modifiers ) { + /** + * We do a merge to make sure new values will override and replace the old + * ones. + */ + $this->query_args = array_merge( $this->query_args, $query_modifier ); + } else { + /** + * We do a recursive merge to allow "stacking" of same kind of queries; + * e.g. two or more `tax_query` or `meta_query` entries should merge into one. + */ + $this->query_args = Arr::merge_recursive_query_vars( $this->query_args, $query_modifier ); + } + } else { + /** + * If we get back something that is not an array then we add it to + * the stack of query modifying callbacks we'll call on the query + * after building it. + */ + $this->query_modifiers[] = $query_modifier; + } + } catch ( Exception $e ) { + /** + * We allow for the `apply` method to orderly fail to micro-optimize. + * If applying one parameter would yield no results then let's immediately bail. + * Schema should throw t + * his Exception if a light-weight on the filters would already + * deem a query as yielding nothing. + */ + $this->void_query = true; + + return $this; + } + + /** + * Catching other type of exceptions is something the client code should handle! + */ + + return $this; + } + + /** + * Returns the query modifier for a key. + * + * @since 4.7.19 + * + * @param string $key + * @param array $call_args + * + * @return mixed + * + * @throws Tribe__Repository__Usage_Error If the required filter is not defined by the class. + * @throws Tribe__Repository__Void_Query_Exception To signal the query would yield no results. + */ + protected function modify_query( $key, $call_args ) { + if ( ! $this->schema_has_modifier_for( $key ) ) { + if ( $this->has_default_modifier( $key ) ) { + // let's use the default filters normalizing the key first + $call_args[0] = $this->normalize_key( $key ); + $query_modifier = call_user_func_array( [ $this, 'apply_default_modifier' ], $call_args ); + } elseif ( 2 === count( $call_args ) ) { + // Pass query argument $key with the single value argument. + $query_modifier = [ + $key => $call_args[1], + ]; + } else { + // More than two $call_args were sent (key, value), assume it was meant for a filter that was not defined yet. + throw Tribe__Repository__Usage_Error::because_the_read_filter_is_not_defined( $key, $this ); + } + } else { + $query_modifier = call_user_func_array( [ $this, 'apply_modifier' ], $call_args ); + } + + return $query_modifier; + } + + /** + * Whether the current schema defines an application for the key or not. + * + * @since 4.7.19 + * + * @param $key + * + * @return bool + */ + protected function schema_has_modifier_for( $key ) { + return isset( $this->schema[ $key ] ); + } + + /** + * Whether a filter defined and handled by the repository exists or not. + * + * @since 4.7.19 + * + * @param string $key + * + * @return bool + */ + protected function has_default_modifier( $key ) { + $normalized_key = $this->normalize_key( $key ); + + return in_array( $normalized_key, self::$default_modifiers, true ); + } + + /** + * Normalizes the filter key to allow broad matching of the `by` filters. + * + * @since 4.7.19 + * + * E.g. `by( 'id', 23 )` is the same as `by( 'ID', 23 ). + * E.g. `by( 'parent', 23 )` is the same as `by( `post_parent`, 23 )` + * + * @param string $key + * + * @return string The normalized filter key + */ + protected function normalize_key( $key ) { + // `ID` to `id` + $normalized = strtolower( $key ); + + $post_prefixed = [ + 'password', + 'name__in', + '_in', + '_not_in', + 'parent', + 'parent__in', + 'parent__not_in', + 'mime_type', + 'content', + 'excerpt', + 'status', + 'modified', + 'modified_gmt', + 'content_filtered', + ]; + + if ( in_array( $key, $post_prefixed, true ) ) { + $normalized = 'post_' . $key; + } + + return $normalized; + } + + /** + * Returns a list of modifiers that, when applied multiple times, + * will replace the previous value. + * + * This behaviour is in opposition to "stackable" modifiers that will, + * instead, be composed and stacked. + * + * @since 4.7.19 + * + * @return array + */ + protected function replacing_modifiers() { + return self::$replacing_modifiers; + } + + /** + * Batch filter application method. + * + * This is the same as calling `where` multiple times with different arguments. + * + * @since 4.7.19 + * + * @param array $args An associative array of arguments to filter + * the posts by in the shape [ , ]. + * + * @return Tribe__Repository__Read_Interface|Tribe__Repository__Update_Interface + */ + public function where_args( array $args ) { + return $this->by_args( $args ); + } + + /** + * {@inheritdoc} + */ + public function by_args( array $args ) { + foreach ( $args as $key => $value ) { + $this->by( $key, $value ); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function save( $return_promise = false ) { + $to_update = $this->get_ids(); + + if ( empty( $to_update ) ) { + return $return_promise ? new Tribe__Promise() : []; + } + + $exit = []; + $postarrs = []; + + foreach ( $to_update as $id ) { + $postarrs[ $id ] = $this->filter_postarr_for_update( $this->build_postarr( $id ), $id ); + } + + // If any `filter_postarr_for_update` call returned a falsy value then drop it. + $postarrs = array_filter( $postarrs ); + + if ( + $this->is_background_update_active( $to_update ) + && count( $to_update ) > $this->get_background_update_threshold( $to_update ) + ) { + return $this->async_update( $postarrs, true ); + } + + $update_callback = $this->get_update_callback( $to_update, false ); + + foreach ( $postarrs as $id => $postarr ) { + $this_exit = $update_callback( $postarr ); + $exit[ $id ] = $id === $this_exit ? true : $this_exit; + } + + return $return_promise ? new Tribe__Promise : $exit; + } + + /** + * {@inheritdoc} + */ + public function get_ids() { + if ( $this->void_query ) { + return []; + } + + + try { + /** @var WP_Query $query */ + $query = $this->get_query(); + + // The request property will be set during the `get_posts` method and empty before it. + if ( empty( $query->request ) ) { + $query->set( 'fields', 'ids' ); + + return $query->get_posts(); + } + + return array_map( + static function ( $post ) { + if ( is_int( $post ) ) { + return $post; + } + $post_arr = (array) $post; + + return Arr::get( $post_arr, 'ID', Arr::get( $post_arr, 'id', 0 ) ); + }, + $query->posts + ); + + } catch ( Tribe__Repository__Void_Query_Exception $e ) { + /* + * Extending classes might use this method to run sub-queries + * and signal a void query; let's return an empty array. + */ + return []; + } + } + + /** + * {@inheritdoc} + */ + public function get_query() { + return $this->build_query(); + } + + /** + * Whether the current key can be updated by this repository or not. + * + * @since 4.7.19 + * + * @param string $key + * + * @return bool + */ + protected function can_be_updated( $key ) { + return ! in_array( $key, self::$blocked_keys, true ); + } + + /** + * Whether the current key is a date one requiring a converted key pair too or not. + * + * @param string $key + * + * @return bool + */ + protected function requires_converted_date( $key ) { + return array_key_exists( $key, $this->to_local_time_map ) || array_key_exists( $key, $this->to_gmt_map ); + } + + /** + * Updates the update post payload to add dates that should be provided in GMT + * and localized version. + * + * @since 4.7.19 + * + * @param string $key + * @param string|int $value + * @param array $postarr + */ + protected function update_postarr_dates( $key, $value, array &$postarr ) { + if ( array_key_exists( $key, $this->to_gmt_map ) ) { + $postarr[ $this->to_gmt_map[ $key ] ] = Tribe__Timezones::to_tz( $value, 'UTC' ); + } elseif ( array_key_exists( $key, $this->to_local_time_map ) ) { + $postarr[ $this->to_local_time_map[ $key ] ] = Tribe__Timezones::to_tz( $value, Tribe__Timezones::wp_timezone_string() ); + } + $postarr[ $key ] = $value; + } + + /** + * {@inheritdoc} + */ + public function set_args( array $update_map ) { + foreach ( $update_map as $key => $value ) { + $this->set( $key, $value ); + } + + return $this; + } + + /** + * Sets the args to be updated during save process. + * + * @param string $key Argument key. + * @param mixed $value Argument value. + * + * @throws Tribe__Repository__Usage_Error + * + * @return $this + */ + public function set( $key, $value ) { + if ( ! is_string( $key ) ) { + throw Tribe__Repository__Usage_Error::because_update_key_should_be_a_string( $this ); + } + + $this->updates[ $key ] = $value; + + return $this; + } + + /** + * Sets the create args the repository will use to create posts. + * + * @since 4.9.5 + * + * @param string|int $image The path to an image file, an image URL, or an attachment post ID. + * + * @return $this + */ + public function set_featured_image( $image ) { + if ( '' === $image || false === $image ) { + $thumbnail_id = false; + } elseif ( 0 === $image || null === $image ) { + $thumbnail_id = ''; + } else { + $thumbnail_id = tribe_upload_image( $image ); + } + + if ( false === $thumbnail_id ) { + return $this; + } + + return $this->set( '_thumbnail_id', $thumbnail_id ); + } + + /** + * {@inheritdoc} + */ + public function filter_name( $filter_name ) { + $this->filter_name = trim( $filter_name ); + + return $this; + + } + + /** + * {@inheritdoc} + */ + public function set_formatter( Tribe__Repository__Formatter_Interface $formatter ) { + $this->formatter = $formatter; + } + + /** + * Filters the query to only return posts that are related, via a meta key, to posts + * that satisfy a condition. + * + * @param string|array $meta_keys One or more `meta_keys` relating the queried post type(s) + * to another post type. + * @param string $compare The SQL comparison operator. + * @param string $field One (a column in the `posts` table) that should match + * the comparison criteria; required if the comparison operator is not `EXISTS` or + * `NOT EXISTS`. + * @param string|array $values One or more values the post field(s) should be compared to; + * required if the comparison operator is not `EXISTS` or `NOT EXISTS`. + * + * @return $this + * @throws Tribe__Repository__Usage_Error If the comparison operator requires + */ + public function where_meta_related_by( $meta_keys, $compare, $field = null, $values = null ) { + $meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys ); + + if ( ! in_array( $compare, [ 'EXISTS', 'NOT EXISTS' ], true ) ) { + if ( empty( $field ) || empty( $values ) ) { + throw Tribe__Repository__Usage_Error::because_this_comparison_operator_requires_fields_and_values( $meta_keys, $compare, $this ); + } + } + + $field = esc_sql( $field ); + + /** @var wpdb $wpdb */ + global $wpdb; + $p = $this->sql_slug( 'meta_related_post', $compare, $meta_keys ); + $pm = $this->sql_slug( 'meta_related_post_meta', $compare, $meta_keys ); + + $this->filter_query->join( "LEFT JOIN {$wpdb->postmeta} {$pm} ON {$wpdb->posts}.ID = {$pm}.post_id" ); + $this->filter_query->join( "LEFT JOIN {$wpdb->posts} {$p} ON {$pm}.meta_value = {$p}.ID" ); + + $keys_in = $this->prepare_interval( $meta_keys ); + + if ( 'EXISTS' === $compare ) { + $this->filter_query->where( "{$pm}.meta_key IN {$keys_in} AND {$pm}.meta_id IS NOT NULL" ); + } elseif ( 'NOT EXISTS' === $compare ) { + $this->filter_query->where( "{$pm}.meta_id IS NULL" ); + } else { + if ( in_array( $compare, self::$multi_value_keys, true ) ) { + $values = $this->prepare_interval( $values ); + } else { + $values = $this->prepare_value( $values ); + } + $this->filter_query->where( "{$pm}.meta_key IN {$keys_in} AND {$p}.{$field} {$compare} {$values}" ); + } + + return $this; + } + + /** + * Filters the query to only return posts that are related, via a meta key, to posts + * that satisfy a condition. + * + * @since 4.10.3 + * + * @throws Tribe__Repository__Usage_Error If the comparison operator requires and no value provided. + * + * @param string|array $meta_keys One or more `meta_keys` relating the queried post type(s) + * to another post type. + * @param string $compare The SQL comparison operator. + * @param string $meta_field One (a column in the `postmeta` table) that should match + * the comparison criteria; required if the comparison operator is not `EXISTS` or + * `NOT EXISTS`. + * @param string|array $meta_values One or more values the post field(s) should be compared to; + * required if the comparison operator is not `EXISTS` or `NOT EXISTS`. + * @param boolean $or_not_exists Whether or not to also include a clause to check if value IS NULL. + * Example with this as true: `value = X OR value IS NULL`. + * + * @return $this + */ + public function where_meta_related_by_meta( $meta_keys, $compare, $meta_field = null, $meta_values = null, $or_not_exists = false ) { + $meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys ); + + if ( ! in_array( $compare, [ 'EXISTS', 'NOT EXISTS' ], true ) ) { + if ( empty( $meta_field ) || empty( $meta_values ) ) { + throw Tribe__Repository__Usage_Error::because_this_comparison_operator_requires_fields_and_values( $meta_keys, $compare, $this ); + } + } + + $meta_field = esc_sql( $meta_field ); + + /** @var wpdb $wpdb */ + global $wpdb; + + $pm = $this->sql_slug( 'post_meta_related_post_meta', $compare, $meta_keys ); + $pmm = $this->sql_slug( 'meta_post_meta_related_post_meta', $compare, $meta_keys ); + + $this->filter_query->join( "LEFT JOIN {$wpdb->postmeta} {$pm} ON {$pm}.post_id = {$wpdb->posts}.ID" ); + $this->filter_query->join( " + LEFT JOIN {$wpdb->postmeta} {$pmm} + ON {$pmm}.post_id = {$pm}.meta_value + AND {$pmm}.meta_key = '{$meta_field}' + " ); + + $keys_in = $this->prepare_interval( $meta_keys ); + + if ( 'EXISTS' === $compare ) { + $this->filter_query->where( " + {$pm}.meta_key IN {$keys_in} + AND {$pmm}.meta_id IS NOT NULL + " ); + } elseif ( 'NOT EXISTS' === $compare ) { + $this->filter_query->where( " + {$pm}.meta_key IN {$keys_in} + AND {$pmm}.meta_id IS NULL + " ); + } else { + if ( in_array( $compare, static::$multi_value_keys, true ) ) { + $meta_values = $this->prepare_interval( $meta_values ); + } else { + $meta_values = $this->prepare_value( $meta_values ); + } + + $clause = "{$pmm}.meta_value {$compare} {$meta_values}"; + + if ( $or_not_exists ) { + $clause = " + ( + {$clause} + OR {$pmm}.meta_id IS NULL + ) + "; + } + + $this->filter_query->where( " + {$pm}.meta_key IN {$keys_in} + AND {$clause} + " ); + } + + return $this; + } + + /** + * Builds a fenced group of WHERE clauses that will be used with OR logic. + * + * Mind that this is a lower level implementation of WHERE logic that requires + * each callback method to add, at least, one WHERE clause using the repository + * own `where_clause` method. + * + * @param array $callbacks One or more WHERE callbacks that will be called + * this repository. The callbacks have the shape + * [ , <...args>] + * + * @return $this + * @throws Tribe__Repository__Usage_Error If one of the callback methods does + * not add any WHERE clause. + * + * @see Tribe__Repository::where_clause() + * @see Tribe__Repository__Query_Filters::where() + */ + public function where_or( $callbacks ) { + $all_callbacks = func_get_args(); + $buffered = $this->filter_query->get_buffered_where_clauses( true ); + + $this->filter_query->buffer_where_clauses( true ); + + $buffered_count = count( $buffered ); + + foreach ( $all_callbacks as $c ) { + call_user_func_array( [ $this, $c[0] ], array_slice( $c, 1 ) ); + + if ( $buffered_count === count( $this->filter_query->get_buffered_where_clauses() ) ) { + throw Tribe__Repository__Usage_Error::because_where_or_should_only_be_used_with_methods_that_add_where_clauses( $c, $this ); + } + + $buffered_count ++; + } + + $buffered = $this->filter_query->get_buffered_where_clauses( true ); + + $fenced = sprintf( '( %s )', implode( ' OR ', $buffered ) ); + + $this->where_clause( $fenced ); + + return $this; + } + + /** + * Adds an entry to the repository filter schema. + * + * @since 4.9.5 + * + * @param string $key The filter key, the one that will be used in `by` and `where` + * calls. + * @param callable $callback The function that should be called to apply this filter. + */ + public function add_schema_entry( $key, $callback ) { + $this->schema[ $key ] = $callback; + } + + /** + * Adds a simple meta entry to the repository filter schema. + * + * @since 4.9.5 + * + * @param string $key The filter key, the one that will be used in `by` and `where` calls. + * @param string|array $meta_key The meta key(s) to use for the meta lookup. + * @param string|null $by The ->by() lookup to use (defaults to meta_regexp_or_like). + */ + public function add_simple_meta_schema_entry( $key, $meta_key, $by = null ) { + $this->schema[ $key ] = [ $this, 'filter_by_simple_meta_schema' ]; + + $this->simple_meta_schema[ $key ] = [ + 'meta_key' => $meta_key, + 'by' => $by, + ]; + } + + /** + * Adds a simple taxonomy entry to the repository filter schema. + * + * @since 4.9.5 + * + * @param string $key The filter key, the one that will be used in `by` and `where` calls. + * @param string|array $taxonomy The taxonomy/taxonomies to use for the tax lookup. + * @param string|null $by The ->by() lookup to use (defaults to term_in). + */ + public function add_simple_tax_schema_entry( $key, $taxonomy, $by = null ) { + $this->schema[ $key ] = [ $this, 'filter_by_simple_tax_schema' ]; + + $this->simple_tax_schema[ $key ] = [ + 'taxonomy' => $taxonomy, + 'by' => $by, + ]; + } + + /** + * {@inheritdoc} + */ + public function add_update_field_alias( $alias, $field_name ) { + $this->update_fields_aliases[ $alias ] = $field_name; + } + + /** + * Returns modified query arguments after applying a default filter. + * + * @since 4.7.19 + * + * @param string $key + * @param mixed $value + * + * @return array + * @throws Tribe__Repository__Usage_Error If a filter is called with wrong arguments. + */ + protected function apply_default_modifier( $key, $value ) { + $args = []; + + $call_args = func_get_args(); + $arg_1 = isset( $call_args[2] ) ? $call_args[2] : null; + $arg_2 = isset( $call_args[3] ) ? $call_args[3] : null; + + /** @var wpdb $wpdb */ + global $wpdb; + + switch ( $key ) { + default: + // leverage built-in WP_Query filters + $args = [ $key => $value ]; + break; + case 'ID': + case 'id': + $args = [ 'p' => $value ]; + break; + case 'search': + $args = [ 's' => $value ]; + break; + case 'post_status': + $this->query_args['post_status'] = (array) $value; + break; + case 'date': + case 'after_date': + $args = $this->get_posts_after( $value, 'post_date' ); + break; + case 'before_date': + $args = $this->get_posts_before( $value, 'post_date' ); + break; + case 'date_gmt': + case 'after_date_gmt': + $args = $this->get_posts_after( $value, 'post_date_gmt' ); + break; + case 'before_date_gmt': + $args = $this->get_posts_before( $value, 'post_date_gmt' ); + break; + case 'title_like': + $this->filter_query->to_get_posts_with_title_like( $value ); + break; + case 'post_content': + $this->filter_query->to_get_posts_with_content_like( $value ); + break; + case 'post_excerpt': + $this->filter_query->to_get_posts_with_excerpt_like( $value ); + break; + case 'to_ping': + $this->filter_query->to_get_posts_to_ping( $value ); + $args = [ 'to_ping' => $value ]; + break; + case 'post_modified': + $args = $this->get_posts_after( $value, 'post_modified' ); + break; + case 'post_modified_gmt': + $args = $this->get_posts_after( $value, 'post_modified_gmt' ); + break; + case 'post_content_filtered': + $this->filter_query->to_get_posts_with_filtered_content_like( $value ); + break; + case 'guid': + $this->filter_query->to_get_posts_with_guid_like( $value ); + break; + case 'menu_order': + $args = [ 'menu_order' => $value ]; + break; + case 'meta': + case 'meta_equals': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, '=', $format = $arg_2 ); + break; + case 'meta_not_equals': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, '!=', $format = $arg_2 ); + break; + case 'meta_gt': + case 'meta_greater_than': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, '>', $format = $arg_2 ); + break; + case 'meta_gte': + case 'meta_greater_than_or_equal': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, '>=', $format = $arg_2 ); + break; + case 'meta_like': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'LIKE' ); + break; + case 'meta_not_like': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'NOT LIKE' ); + break; + case 'meta_lt': + case 'meta_less_than': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, '<', $format = $arg_2 ); + break; + case 'meta_lte': + case 'meta_less_than_or_equal': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, '<=', $format = $arg_2 ); + break; + case 'meta_in': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'IN', $format = $arg_2 ); + break; + case 'meta_not_in': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'NOT IN', $format = $arg_2 ); + break; + case 'meta_between': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'BETWEEN', $format = $arg_2 ); + break; + case 'meta_not_between': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'NOT BETWEEN', $format = $arg_2 ); + break; + case 'meta_exists': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'EXISTS' ); + break; + case 'meta_not_exists': + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'NOT EXISTS' ); + break; + case 'meta_regexp': + case 'meta_equals_regexp': + // Check if Regexp is fenced. + if ( tribe_is_regex( $arg_1 ) ) { + // Unfence the Regexp. + $arg_1 = tribe_unfenced_regex( $arg_1 ); + } + + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'REGEXP' ); + break; + case 'meta_not_regexp': + case 'meta_not_equals_regexp': + // Check if Regexp is fenced. + if ( tribe_is_regex( $arg_1 ) ) { + // Unfence the Regexp. + $arg_1 = tribe_unfenced_regex( $arg_1 ); + } + + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, 'NOT REGEXP' ); + break; + case 'meta_regexp_or_like': + case 'meta_equals_regexp_or_like': + $compare = 'LIKE'; + + // Check if Regexp is fenced (the only way for Regexp to be supported in this context). + if ( tribe_is_regex( $arg_1 ) ) { + $compare = 'REGEXP'; + + // Unfence the Regexp. + $arg_1 = tribe_unfenced_regex( $arg_1 ); + } + + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, $compare ); + break; + case 'meta_not_regexp_or_like': + case 'meta_not_equals_regexp_or_like': + $compare = 'NOT LIKE'; + + // Check if Regexp is fenced (the only way for Regexp to be supported in this context). + if ( tribe_is_regex( $arg_1 ) ) { + $compare = 'NOT REGEXP'; + + // Unfence the Regexp. + $arg_1 = tribe_unfenced_regex( $arg_1 ); + } + + $args = $this->build_meta_query( $meta_key = $value, $meta_value = $arg_1, $compare ); + break; + case 'taxonomy_exists': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'EXISTS' ); + break; + case 'taxonomy_not_exists': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'NOT EXISTS' ); + break; + case 'term_id_in': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'IN' ); + break; + case 'term_id_not_in': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'NOT IN' ); + break; + case 'term_id_and': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'AND' ); + break; + case 'term_name_in': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'name', 'IN' ); + break; + case 'term_name_not_in': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'name', 'NOT IN' ); + break; + case 'term_name_and': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'name', 'AND' ); + break; + case 'term_slug_in': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'slug', 'IN' ); + break; + case 'term_slug_not_in': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'slug', 'NOT IN' ); + break; + case 'term_slug_and': + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'slug', 'AND' ); + break; + case 'term_in': + $arg_1 = Tribe__Terms::translate_terms_to_ids( $arg_1, $value, false ); + + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'IN' ); + break; + case 'term_not_in': + $arg_1 = Tribe__Terms::translate_terms_to_ids( $arg_1, $value, false ); + + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'NOT IN' ); + break; + case 'term_and': + $arg_1 = Tribe__Terms::translate_terms_to_ids( $arg_1, $value, false ); + + $args = $this->build_tax_query( $taxonomy = $value, $terms = $arg_1, 'term_id', 'AND' ); + break; + } + + + return $args; + } + + /** + * Builds a date query entry to get posts after a date. + * + * @since 4.7.19 + * + * @param string $value + * @param string $column + * + * @return array + */ + protected function get_posts_after( $value, $column = 'post_date' ) { + $timezone = in_array( $column, [ 'post_date_gmt', 'post_modified_gmt' ], true ) + ? 'UTC' + : Tribe__Timezones::generate_timezone_string_from_utc_offset( Tribe__Timezones::wp_timezone_string() ); + + if ( is_numeric( $value ) ) { + $value = "@{$value}"; + } + + $date = new DateTime( $value, new DateTimeZone( $timezone ) ); + + $array_key = sprintf( '%s-after', $column ); + + return [ + 'date_query' => [ + 'relation' => 'AND', + $array_key => [ + 'inclusive' => true, + 'column' => $column, + 'after' => $date->format( 'Y-m-d H:i:s' ), + ], + ], + ]; + } + + /** + * Builds a date query entry to get posts before a date. + * + * @since 4.7.19 + * + * @param string $value + * @param string $column + * + * @return array + */ + protected function get_posts_before( $value, $column = 'post_date' ) { + $timezone = in_array( $column, [ 'post_date_gmt', 'post_modified_gmt' ], true ) + ? 'UTC' + : Tribe__Timezones::generate_timezone_string_from_utc_offset( Tribe__Timezones::wp_timezone_string() ); + + if ( is_numeric( $value ) ) { + $value = "@{$value}"; + } + + $date = new DateTime( $value, new DateTimeZone( $timezone ) ); + + $array_key = sprintf( '%s-before', $column ); + + return [ + 'date_query' => [ + 'relation' => 'AND', + $array_key => [ + 'inclusive' => true, + 'column' => $column, + 'before' => $date->format( 'Y-m-d H:i:s' ), + ], + ], + ]; + } + + /** + * Builds a meta query entry. + * + * @since 4.7.19 + * + * @param string $meta_key + * @param string|array $meta_value + * @param string $compare + * @param string $type_or_format The type of value to compare + * + * @return array|null + * @throws Tribe__Repository__Usage_Error If trying to compare multiple values with a single + * comparison operator. + */ + protected function build_meta_query( $meta_key, $meta_value = 'value', $compare = '=', $type_or_format = null ) { + $meta_keys = Tribe__Utils__Array::list_to_array( $meta_key ); + + $postfix = Tribe__Utils__Array::get( self::$comparison_operators, $compare, '' ); + + if ( count( $meta_keys ) === 1 ) { + $array_key = $this->sql_slug( $meta_keys[0], $postfix ); + + $args = [ + 'meta_query' => [ + $array_key => [ + 'key' => $meta_keys[0], + 'compare' => strtoupper( $compare ), + ], + ], + ]; + + if ( ! in_array( $compare, [ 'EXISTS', 'NOT EXISTS' ], true ) ) { + $args['meta_query'][ $array_key ]['value'] = $meta_value; + } + + if ( 0 === strpos( $type_or_format, '%' ) ) { + throw Tribe__Repository__Usage_Error::because_the_type_is_a_wpdb_prepare_format( $meta_key, $type_or_format, $this ); + } + + if ( null !== $type_or_format ) { + $args['meta_query'][ $array_key ]['type'] = $type_or_format; + } + + return $args; + } + + + if ( null === $type_or_format ) { + $type_or_format = '%s'; + } elseif ( 0 !== strpos( $type_or_format, '%' ) ) { + throw Tribe__Repository__Usage_Error::because_the_format_is_not_a_wpdb_prepare_one( $meta_key, $type_or_format, $this ); + } + + /** @var wpdb $wpdb */ + global $wpdb; + + // Build custom WHERE and JOINS to reduce the JOIN clauses + $pm_alias = $this->sql_slug( 'meta', $postfix, ++ self::$meta_alias ); + $meta_keys_in = sprintf( "('%s')", implode( "','", array_map( 'esc_sql', $meta_keys ) ) ); + + $this->validate_operator_and_values( $compare, $meta_keys, $meta_value ); + + if ( in_array( $compare, self::$multi_value_keys, true ) ) { + $meta_values = $this->prepare_interval( Tribe__Utils__Array::list_to_array( $meta_value ), $type_or_format ); + } else { + $meta_values = $this->prepare_value( $meta_value, $type_or_format ); + } + + $this->filter_query->join( "JOIN {$wpdb->postmeta} {$pm_alias} ON {$wpdb->posts}.ID = {$pm_alias}.post_id" ); + + if ( 'EXISTS' === $compare ) { + $this->filter_query->where( "{$pm_alias}.meta_key IN {$meta_keys_in} AND {$pm_alias}.meta_id IS NOT NULL" ); + } elseif ( 'NOT EXISTS' === $compare ) { + $this->filter_query->where( "{$pm_alias}.meta_key NOT IN {$meta_keys_in} AND {$pm_alias}.meta_id IS NOT NULL" ); + } else { + $this->filter_query->where( "{$pm_alias}.meta_key IN {$meta_keys_in} AND {$pm_alias}.meta_value {$compare} {$meta_values}" ); + } + } + + /** + * Generates a SQL friendly slug from the provided, variadic, fragments. + * + * @since 4.7.19 + * + * @param ...string $frag + * + * @return string + */ + protected function sql_slug( $frag ) { + $frags = func_get_args(); + + foreach ( $frags as &$frag ) { + if ( is_string( $frag ) ) { + Tribe__Utils__Array::get( self::$comparison_operators, $frag, $frag ); + } elseif ( is_array( $frag ) ) { + $frag = implode( '_', $frag ); + } + } + + + $frags = array_filter( $frags ); + + return strtolower( str_replace( '-', '_', sanitize_title( implode( '_', $frags ) ) ) ); + } + + /** + * Builds a taxonomy query entry. + * + * @since 4.7.19 + * + * @param string $taxonomy + * @param int|string|array $terms + * @param string $field + * @param string $operator + * + * @return array + */ + protected function build_tax_query( $taxonomy, $terms, $field, $operator ) { + if ( in_array( $operator, [ 'EXISTS', 'NOT EXISTS' ], true ) ) { + $array_key = $this->sql_slug( $taxonomy, $operator ); + } else { + $array_key = $this->sql_slug( $taxonomy, $field, $operator ); + } + + return [ + 'tax_query' => [ + $array_key => [ + 'taxonomy' => $taxonomy, + 'field' => $field, + 'terms' => $terms, + 'operator' => strtoupper( $operator ), + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function join_clause( $join ) { + $this->filter_query->join( $join ); + } + + /** + * {@inheritdoc} + */ + public function where_clause( $where ) { + $this->filter_query->where( $where ); + } + + /** + * {@inheritdoc} + */ + public function set_query_builder( $query_builder ) { + $this->query_builder = $query_builder; + } + + /** + * Builds and escapes an interval of strings. + * + * The return string includes opening and closing braces. + * + * @since 4.7.19 + * + * @param string|array $values One or more values to use to build + * the interval + * . + * @param string $format The format that should be used to escape + * the values; default to '%s'. + * @param string $operator The operator the interval is being prepared for; + * defaults to `IN`. + * + * @return string + */ + public function prepare_interval( $values, $format = '%s', $operator = 'IN' ) { + $values = Tribe__Utils__Array::list_to_array( $values ); + + $prepared = []; + foreach ( $values as $value ) { + $prepared[] = $this->prepare_value( $value, $format ); + } + + return in_array( $operator, [ 'BETWEEN', 'NOT BETWEEN' ] ) + ? sprintf( '%s AND %s', $prepared[0], $prepared[1] ) + : sprintf( '(%s)', implode( ',', $prepared ) ); + } + + /** + * Prepares a single value to be used in a SQL query. + * + * @since 4.7.19 + * + * @param mixed $value + * @param string $format + * + * @return string + */ + public function prepare_value( $value, $format = '%s' ) { + /** @var wpdb $wpdb */ + global $wpdb; + + return $wpdb->prepare( $format, $value ); + } + + /** + * Validates that a comparison operator is used with the correct type of values. + * + * This is just a wrap to signal this kind of code error not in bad SQL error but + * with a visible exception. + * + * @since 4.7.19 + * + * @param string $compare A SQL comparison operator + * @param string|array $meta_key + * @param mixed $meta_value + * + * @throws Tribe__Repository__Usage_Error + */ + protected function validate_operator_and_values( $compare, $meta_key, $meta_value ) { + if ( is_array( $meta_value ) && ! in_array( $compare, self::$multi_value_keys, true ) ) { + throw Tribe__Repository__Usage_Error::because_single_value_comparisons_should_be_used_with_one_value( + $meta_key, + $meta_value, + $compare, + $this + ); + } + } + + /** + * {@inheritdoc} + */ + public function by_related_to_min( $by_meta_keys, $min, $keys = null, $values = null ) { + $min = $this->prepare_value( $min, '%d' ); + + /** @var wpdb $wpdb */ + global $wpdb; + + $by_meta_keys = $this->prepare_interval( $by_meta_keys ); + + $join = ''; + $and_where = ''; + if ( ! empty( $keys ) || ! empty( $values ) ) { + $join = "\nJOIN {$wpdb->postmeta} pm2 ON pm1.post_id = pm2.post_id\n"; + } + if ( ! empty( $keys ) ) { + $keys = $this->prepare_interval( $keys ); + $and_where .= "\nAND pm2.meta_key IN {$keys}\n"; + } + if ( ! empty( $values ) ) { + $values = $this->prepare_interval( $values ); + $and_where .= "\nAND pm2.meta_value IN {$values}\n"; + } + + $this->where_clause( "{$wpdb->posts}.ID IN ( + SELECT pm1.meta_value + FROM {$wpdb->postmeta} pm1 {$join} + WHERE pm1.meta_key IN {$by_meta_keys} {$and_where} + GROUP BY( pm1.meta_value ) + HAVING COUNT(DISTINCT pm1.post_id) >= {$min} + )" ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function by_related_to_max( $by_meta_keys, $max, $keys = null, $values = null ) { + $max = $this->prepare_value( $max, '%d' ); + + /** @var wpdb $wpdb */ + global $wpdb; + + $join = ''; + $and_where = ''; + if ( ! empty( $keys ) || ! empty( $values ) ) { + $join = "\nJOIN {$wpdb->postmeta} pm2 ON pm1.post_id = pm2.post_id\n"; + } + if ( ! empty( $keys ) ) { + $keys = $this->prepare_interval( $keys ); + $and_where .= "\nAND pm2.meta_key IN {$keys}\n"; + } + if ( ! empty( $values ) ) { + $values = $this->prepare_interval( $values ); + $and_where .= "\nAND pm2.meta_value IN {$values}\n"; + } + + $by_meta_keys = $this->prepare_interval( $by_meta_keys ); + + $this->where_clause( "{$wpdb->posts}.ID IN ( + SELECT pm1.meta_value + FROM {$wpdb->postmeta} pm1 {$join} + WHERE pm1.meta_key IN {$by_meta_keys} {$and_where} + GROUP BY( pm1.meta_value ) + HAVING COUNT(DISTINCT pm1.post_id) <= {$max} + )" ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function by_related_to_between( $by_meta_keys, $min, $max, $keys = null, $values = null ) { + $min = $this->prepare_value( $min, '%d' ); + $max = $this->prepare_value( $max, '%d' ); + + /** @var wpdb $wpdb */ + global $wpdb; + + $by_meta_keys = $this->prepare_interval( $by_meta_keys ); + + $join = ''; + $and_where = ''; + if ( ! empty( $keys ) || ! empty( $values ) ) { + $join = "\nJOIN {$wpdb->postmeta} pm2 ON pm1.post_id = pm2.post_id\n"; + } + if ( ! empty( $keys ) ) { + $keys = $this->prepare_interval( $keys ); + $and_where .= "\nAND pm2.meta_key IN {$keys}\n"; + } + if ( ! empty( $values ) ) { + $values = $this->prepare_interval( $values ); + $and_where .= "\nAND pm2.meta_value IN {$values}\n"; + } + + $this->where_clause( "{$wpdb->posts}.ID IN ( + SELECT pm1.meta_value + FROM {$wpdb->postmeta} pm1 {$join} + WHERE pm1.meta_key IN {$by_meta_keys} {$and_where} + GROUP BY( pm1.meta_value ) + HAVING COUNT(DISTINCT pm1.post_id) BETWEEN {$min} AND {$max} + )" ); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function has_filter( $key, $value = null ) { + $args = func_get_args(); + $values = array_slice( $args, 1 ); + + if ( null === $value ) { + // We just want to check if a filter is applied. + return array_key_exists( $key, $this->current_filters ); + } + + // We check if the filter exists and the arguments match; inline to prevent "Undefined index" errors. + return array_key_exists( $key, $this->current_filters ) && array_slice( + $this->current_filters[ $key ], + 0, + min( count( $this->current_filters[ $key ] ), count( $values ) ) + ) === $values; + } + + /** + * {@inheritdoc} + */ + public function get_current_filter() { + return $this->current_filter; + } + + /** + * Returns a map relating comparison operators to their "pretty" name. + * + * @since 4.9.5 + * + * @return array + */ + public static function get_comparison_operators() { + return self::$comparison_operators; + } + + /** + * {@inheritdoc} + */ + public function delete( $return_promise = false ) { + $to_delete = $this->get_ids(); + + if ( empty( $to_delete ) ) { + return $return_promise ? new Tribe__Promise() : []; + } + + + /** + * Filters the post delete operation allowing third party code to bail out of + * the process completely. + * + * @since 4.9.5 + * + * @param array|null $deleted An array containing the the IDs of the deleted posts. + * @param self $this This repository instance. + */ + $deleted = apply_filters( "tribe_repository_{$this->filter_name}_delete", null, $to_delete ); + if ( null !== $deleted ) { + return $deleted; + } + + if ( + $this->is_background_delete_active( $to_delete ) + && count( $to_delete ) > $this->get_background_delete_threshold( $to_delete ) + ) { + return $this->async_delete( $to_delete, $return_promise ); + } + + $delete_callback = $this->get_delete_callback( $to_delete ); + + foreach ( $to_delete as $id ) { + $done = $delete_callback( $id ); + + if ( empty( $done ) ) { + tribe( 'logger' )->log( + __( 'Could not delete post with ID ' . $id, 'tribe-common' ), + Tribe__Log::WARNING, + $this->filter_name + ); + continue; + } + $deleted[] = $id; + } + + return $return_promise ? new Tribe__Promise() : $deleted; + } + + /** + * Whether background delete is activated for the repository or not. + * + * @since 4.9.5 + * + * @param array $to_delete An array of post IDs to delete. + * + * @return bool Whether background delete is activated for the repository or not. + */ + protected function is_background_delete_active( $to_delete ) { + /** + * Whether background, asynchronous, deletion of posts is active or not for all repositories. + * + * If active then if the number of posts to delete is over the threshold, defined + * by the `tribe_repository_delete_background_threshold` filter, then the deletion will happen + * in background in other requests. + * + * @since 4.9.5 + * + * @param bool $background_active Whether background deletion is active or not. + * @param array $to_delete The array of post IDs to delete. + */ + $background_active = (bool) apply_filters( 'tribe_repository_delete_background_activated', true, $to_delete ); + + /** + * Whether background, asynchronous, deletion of posts is active or not for this specific repository. + * + * If active then if the number of posts to delete is over the threshold, defined + * by the `tribe_repository_delete_background_threshold` filter, then the deletion will happen + * in background in other requests. + * + * @since 4.9.5 + * + * @param bool $background_active Whether background deletion is active or not. + * @param array $to_delete The array of post IDs to delete. + */ + $background_active = (bool) apply_filters( + "tribe_repository_{$this->filter_name}_delete_background_activated", + $background_active, + $to_delete + ); + + return $background_active; + } + + /** + * Returns the threshold above which posts will be deleted in background. + * + * @since 4.9.5 + * + * @param array $to_delete An array of post IDs to delete. + * + * @return int The threshold above which posts will be deleted in background. + */ + protected function get_background_delete_threshold( $to_delete ) { + /** + * The number of posts above which the deletion will happen in background. + * + * This filter will be ignored if background delete is deactivated with the `tribe_repository_delete_background_activated` + * or `tribe_repository_{$this->filter_name}_delete_background_activated` filter. + * + * @since 4.9.5 + * + * @param int The threshold over which posts will be deleted in background. + * @param array $to_delete The post IDs to delete. + */ + $background_threshold = (int) apply_filters( 'tribe_repository_delete_background_threshold', 20, $to_delete ); + + /** + * The number of posts above which the deletion will happen in background. + * + * This filter will be ignored if background delete is deactivated with the `tribe_repository_delete_background_activated` + * or `tribe_repository_{$this->filter_name}_delete_background_activated` filter. + * + * @since 4.9.5 + * + * @param int The threshold over which posts will be deleted in background. + * @param array $to_delete The post IDs to delete. + */ + $background_threshold = (int) apply_filters( + "tribe_repository_{$this->filter_name}_delete_background_threshold", + $background_threshold, + $to_delete + ); + + return $background_threshold; + } + + /** + * Whether background update is activated for the repository or not. + * + * @since 4.9.5 + * + * @param array $to_update An array of post IDs to update. + * + * @return bool Whether background update is activated for the repository or not. + */ + protected function is_background_update_active( $to_update ) { + /** + * Whether background, asynchronous, update of posts is active or not for all repositories. + * + * If active then if the number of posts to update is over the threshold, defined + * by the `tribe_repository_update_background_threshold` filter, then the update will happen + * in background in other requests. + * + * @since 4.9.5 + * + * @param bool $background_active Whether background update is active or not. + * @param array $to_update The array of post IDs to update. + */ + $background_active = (bool) apply_filters( 'tribe_repository_update_background_activated', true, $to_update ); + + /** + * Whether background, asynchronous, update of posts is active or not for this specific repository. + * + * If active then if the number of posts to update is over the threshold, defined + * by the `tribe_repository_update_background_threshold` filter, then the update will happen + * in background in other requests. + * + * @since 4.9.5 + * + * @param bool $background_active Whether background update is active or not. + * @param array $to_update The array of post IDs to update. + */ + $background_active = (bool) apply_filters( + "tribe_repository_{$this->filter_name}_update_background_activated", + $background_active, + $to_update + ); + + return $background_active; + } + + /** + * Returns the threshold above which posts will be updated in background. + * + * @since 4.9.5 + * + * @param array $to_update An array of post IDs to update. + * + * @return int The threshold above which posts will be updated in background. + */ + protected function get_background_update_threshold( $to_update ) { + /** + * The number of posts above which the update will happen in background. + * + * This filter will be ignored if background update is deactivated with the `tribe_repository_update_background_activated` + * or `tribe_repository_{$this->filter_name}_update_background_activated` filter. + * + * @since 4.9.5 + * + * @param int The threshold over which posts will be updated in background. + * @param array $to_update The post IDs to update. + */ + $background_threshold = (int) apply_filters( 'tribe_repository_update_background_threshold', 20, $to_update ); + + /** + * The number of posts above which the update will happen in background. + * + * This filter will be ignored if background update is deactivated with the `tribe_repository_update_background_activated` + * or `tribe_repository_{$this->filter_name}_update_background_activated` filter. + * + * @since 4.9.5 + * + * @param int The threshold over which posts will be updated in background. + * @param array $to_update The post IDs to update. + */ + $background_threshold = (int) apply_filters( + "tribe_repository_{$this->filter_name}_update_background_threshold", + $background_threshold, + $to_update + ); + + return $background_threshold; + } + + + /** + * {@inheritdoc} + */ + public function async_delete( array $to_delete, $return_promise = true ) { + $promise = new Tribe__Promise( $this->get_delete_callback( $to_delete, true ), $to_delete ); + if ( ! $return_promise ) { + // Dispatch it immediately and return the IDs that will be deleted. + $promise->save()->dispatch(); + + return $to_delete; + } + + // Return the promise and let the client do the dispatching. + return $promise; + } + + /** + * Returns the delete callback function or method to use to delete posts. + * + * @since 4.9.5 + * + * @param int|array $to_delete The post ID to delete or an array of post IDs to delete. + * @param bool $background Whether the callback will be used in background delete operations or not. + * + * @return callable The callback to use. + */ + protected function get_delete_callback( $to_delete, $background = false ) { + /** + * Filters the callback that all repositories should use to delete posts. + * + * @since 4.9.5 + * + * @param callable $callback The callback that should be used to delete each post; defaults + * to `wp_delete_post`; falsy return values will be interpreted as + * failures to delete. + * @param array|int $to_delete An array of post IDs to delete. + * @param bool $background Whether the delete operation will happen in background or not. + */ + $callback = apply_filters( 'tribe_repository_delete_callback', 'wp_delete_post', (array) $to_delete, (bool) $background ); + + /** + * Filters the callback that all repositories should use to delete posts. + * + * @since 4.9.5 + * + * @param callable $callback The callback that should be used to delete each post; defaults + * to `wp_delete_post`; falsy return values will be interpreted as + * failures to delete. + * @param array|int $to_delete An array of post IDs to delete. + * @param bool $background Whether the delete operation will happen in background or not. + */ + $callback = apply_filters( + "tribe_repository_{$this->filter_name}_delete_callback", + $callback, + (array) $to_delete, + (bool) $background + ); + + return $callback; + } + + /** + * {@inheritdoc} + */ + public function get_filter_name() { + return $this->filter_name; + } + + /** + * Returns the update callback function or method to use to update posts. + * + * @since 4.9.5 + * + * @param int|array $to_update The post ID to update or an array of post IDs to update. + * @param bool $background Whether the callback will be used in background update operations or not. + * + * @return callable The callback to use. + */ + protected function get_update_callback( $to_update, $background = false ) { + /** + * Filters the callback that all repositories should use to update posts. + * + * @since 4.9.5 + * + * @param callable $callback The callback that should be used to update each post; defaults + * to `wp_update_post`; falsy return values will be interpreted as + * failures to update. + * @param array|int $to_update An array of post IDs to update. + * @param bool $background Whether the update operation will happen in background or not. + */ + $callback = apply_filters( 'tribe_repository_update_callback', 'wp_update_post', (array) $to_update, (bool) $background ); + + /** + * Filters the callback that all repositories should use to update posts. + * + * @since 4.9.5 + * + * @param callable $callback The callback that should be used to update each post; defaults + * to `wp_update_post`; falsy return values will be interpreted as + * failures to update. + * @param array|int $to_update An array of post IDs to update. + * @param bool $background Whether the update operation will happen in background or not. + */ + $callback = apply_filters( + "tribe_repository_{$this->filter_name}_update_callback", + $callback, + (array) $to_update, + (bool) $background + ); + + return $callback; + } + + /** + * {@inheritdoc} + */ + public function async_update( array $to_update, $return_promise = true ) { + $promise = new Tribe__Promise( $this->get_update_callback( $to_update, true ), $to_update ); + if ( ! $return_promise ) { + // Dispatch it immediately and return the IDs that will be deleted. + $promise->save()->dispatch(); + + return $to_update; + } + + // Return the promise and let the client do the dispatching. + return $promise; + } + + /** + * {@inheritdoc} + */ + public function get_update_fields_aliases() { + return $this->update_fields_aliases; + } + + /** + * {@inheritdoc} + */ + public function set_update_fields_aliases( array $update_fields_aliases ) { + $this->update_fields_aliases = $update_fields_aliases; + } + + /** + * {@inheritdoc} + */ + public function filter_postarr_for_update( array $postarr, $post_id ) { + /** + * Filters the post array that will be used for an update. + * + * @since 4.9.5 + * + * @param array $postarr The post array that will be sent to the update callback. + * @param int The post ID if set. + */ + return apply_filters( "tribe_repository_{$this->filter_name}_update_postarr", $postarr, $post_id ); + } + + /** + * A utility method to cast any PHP error into an exception proper. + * + * Usage: `set_error_handler( array( $repository, 'cast_error_to_exception' ) ); + * + * @since 4.9.5 + * + * @param int $code The error code. + * @param string $message The error message. + */ + public function cast_error_to_exception( $code, $message ) { + throw new RuntimeException( $message, $code ); + } + + /** + * {@inheritdoc} + */ + public function create() { + $postarr = $this->filter_postarr_for_create( array_merge( $this->build_postarr(), $this->create_args ) ); + + // During the filtering allow extending classes or filters to prevent the create completely. + if ( false === ( bool ) $postarr ) { + return false; + } + + $created = call_user_func( $this->get_create_callback( $postarr ), $postarr ); + + $post = $this->format_item( $created ); + + return $post instanceof WP_Post && $post->ID === $created ? $post : false; + } + + /** + * {@inheritdoc} + */ + public function filter_postarr_for_create( array $postarr ) { + /** + * Filters the post array that will be used for the creation of a post + * of the type managed by the repository. + * + * @since 4.9.5 + * + * @param array $postarr The post array that will be sent to the create callback. + */ + return apply_filters( "tribe_repository_{$this->filter_name}_update_postarr", $postarr ); + } + + /** + * {@inheritdoc} + */ + public function build_postarr( $id = null ) { + $postarr = [ + 'tax_input' => [], + 'meta_input' => [], + ]; + + /* + * The check is lax here by design: we leave space for the client code + * to use this method to build post arrays; when this is used by the + * repository the integrity of `$id` is granted. + */ + $is_update = null !== $id && is_numeric( $id ); + + // But still let's provide values that make sense. + if ( $is_update ) { + $postarr['ID'] = (int) $id; + } + + foreach ( $this->updates as $key => $value ) { + if ( is_callable( $value ) ) { + $value = $value( $id, $key, $this ); + } + + // Allow fields to be aliased + $key = Tribe__Utils__Array::get( $this->update_fields_aliases, $key, $key ); + + if ( ! $this->can_be_updated( $key ) ) { + throw Tribe__Repository__Usage_Error::because_this_field_cannot_be_updated( $key, $this ); + } + + if ( $this->is_a_post_field( $key ) ) { + if ( $this->requires_converted_date( $key ) ) { + $this->update_postarr_dates( $key, $value, $postarr ); + } else { + $postarr[ $key ] = $value; + } + } elseif ( $this->is_a_taxonomy( $key ) ) { + $taxonomy = get_taxonomy( $key ); + if ( $taxonomy instanceof WP_Taxonomy ) { + $postarr['tax_input'][ $key ] = Tribe__Utils__Array::list_to_array( $value ); + } + } else { + // it's a custom field + $postarr['meta_input'][ $key ] = $value; + } + } + + return $postarr; + } + + /** + * Returns the create callback function or method to use to create posts. + * + * @since 4.9.5 + * + * @param array $postarr The post array that will be used for the creation. + * + * @return callable The callback to use. + */ + protected function get_create_callback( array $postarr ) { + /** + * Filters the callback that all repositories should use to create posts. + * + * @since 4.9.5 + * + * @param callable $callback The callback that should be used to create posts; defaults + * to `wp_insert_post`; non numeric and existing post ID return + * values will be interpreted as failures to create the post. + * @param array $postarr The post array that will be used for the creation. + */ + $callback = apply_filters( 'tribe_repository_create_callback', 'wp_insert_post', $postarr ); + + /** + * Filters the callback that all repositories should use to create posts. + * + * @since 4.9.5 + * + * @param callable $callback The callback that should be used to create posts; defaults + * to `wp_insert_post`; non numeric and existing post ID return + * values will be interpreted as failures to create the post. + * @param array $postarr The post array that will be used for the creation. + */ + $callback = apply_filters( + "tribe_repository_{$this->filter_name}_create_callback", + $callback, + $postarr + ); + + return $callback; + } + + /** + * Returns the create args the repository will use to create posts. + * + * @since 4.9.5 + * + * @return array The create args the repository will use to create posts. + */ + public function get_create_args() { + return $this->create_args; + } + + /** + * Sets the create args the repository will use to create posts. + * + * @since 4.9.5 + * + * @param array $create_args The create args the repository will use to create posts. + */ + public function set_create_args( array $create_args ) { + $this->create_args = $create_args; + } + + /** + * Returns a value trying to fetch it from an array first and then + * reading it from the meta. + * + * @since 4.9.5 + * + * @param array $postarr The array to look into. + * @param string $key The key to retrieve. + * @param int|null $post_id The post ID to fetch the value for. + * @param mixed $default The default value to return if nothing was found. + * + * @return mixed The found value if any. + */ + protected function get_from_postarr_or_meta( array $postarr, $key, $post_id = null, $default = null ) { + $default_value = get_post_meta( $post_id, $key, true ); + if ( '' === $default_value || null === $post_id ) { + $default_value = $default; + } + + return Tribe__Utils__Array::get( $postarr['meta_input'], $key, $default_value ); + } + + /** + * {@inheritdoc} + */ + public function set_display_context( $context = 'default' ) { + $this->display_context = $context; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function set_render_context( $context = 'default' ) { + $this->render_context = $context; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function get_query_for_posts( array $posts ) { + $posts = array_filter( array_map( 'get_post', $posts ) ); + $query = new \WP_Query(); + // Let's make it look like the posts are the result of a query using `post__in`. + $query->set( 'post__in', wp_list_pluck( $posts, 'ID' ) ); + $query->found_posts = count( $posts ); + $query->posts = $posts; + $query->post_count = count( $posts ); + $query->current_post = - 1; + + return $query; + } + + /** + * {@inheritdoc} + */ + public function pluck( $field ) { + $list = new WP_List_Util( $this->all() ); + + return $list->pluck( $field ); + } + + /** + * {@inheritdoc} + */ + public function filter( $args = [], $operator = 'AND' ) { + $list = new WP_List_Util( $this->all() ); + + return $list->filter( $args, $operator ); + } + + /** + * {@inheritdoc} + */ + public function sort( $orderby = [], $order = 'ASC', $preserve_keys = false ) { + $list = new WP_List_Util( $this->all() ); + + return $list->sort( $orderby, $order, $preserve_keys ); + } + + /** + * {@inheritdoc} + */ + public function collect() { + return new Tribe__Utils__Post_Collection( $this->all() ); + } + + /** + * Builds the ORM query with the query builder. + * + * Allow classes extending or decorating the repository to act before + * the query is built or replace its building completely. + * + * @since 4.9.5 + * + * @return WP_Query|null A built query object or `null` if the builder failed or bailed. + */ + protected function build_query_with_builder() { + $built = $this->query_builder->build_query(); + + $built->builder = $this->query_builder; + + if ( null !== $built ) { + $query = $built; + } + + return $query; + } + + /** + * Builds the ORM query internally, without a query builder. + * + * @since 4.9.5 + * + * @return WP_Query The built query object. + */ + protected function build_query_internally() { + $query = new WP_Query(); + + $query->builder = $this; + + $this->filter_query->set_query( $query ); + + /** + * Here we merge, not recursively, to allow user-set query arguments + * to override the default ones. + */ + $query_args = array_merge( $this->default_args, $this->query_args ); + + $default_post_status = [ 'publish' ]; + if ( current_user_can( 'read_private_posts' ) ) { + $default_post_status[] = 'private'; + } + + $query_args['post_status'] = Tribe__Utils__Array::get( $query_args, 'post_status', $default_post_status ); + + /** + * Filters the query arguments that will be used to fetch the posts. + * + * @param array $query_args An array of the query arguments the query will be + * initialized with. + * @param WP_Query $query The query object, the query arguments have not been parsed yet. + * @param $this $this This repository instance + */ + $query_args = apply_filters( "tribe_repository_{$this->filter_name}_query_args", $query_args, $query, $this ); + + /** + * Provides a last-ditch effort to override the filtered offset. + * + * This should only be used if doing creating pagination for performance purposes. + * + * @since 4.11.0 + * + * @param null|int $filtered_offset Offset parameter setting. + * @param array $query_args List of query arguments. + */ + $filtered_offset = apply_filters( 'tribe_repository_query_arg_offset_override', null, $query_args ); + + if ( $filtered_offset || isset( $query_args['offset'] ) ) { + $per_page = (int) Tribe__Utils__Array::get( $query_args, 'posts_per_page', get_option( 'posts_per_page' ) ); + + if ( $filtered_offset ) { + $query_args['offset'] = $filtered_offset; + } elseif ( isset( $query_args['offset'] ) ) { + $offset = absint( $query_args['offset'] ); + $page = (int) Tribe__Utils__Array::get( $query_args, 'paged', 1 ); + + $real_offset = $per_page === -1 ? $offset : ( $per_page * ( $page - 1 ) ) + $offset; + $query_args['offset'] = $real_offset; + + /** + * Unset the `offset` query argument to avoid applying it multiple times when this method + * is used, on the same repository, more than once. + */ + unset( $this->query_args['offset'] ); + } + + $query_args['posts_per_page'] = $per_page === -1 ? self::MAX_NUMBER_OF_POSTS_PER_PAGE : $per_page; + } + + foreach ( $query_args as $key => $value ) { + $query->set( $key, $value ); + } + + /** + * Here process the previously set query modifiers passing them the + * query object before it executes. + * The query modifiers should modify the query by reference. + */ + foreach ( $this->query_modifiers as $arg ) { + if ( is_object( $arg ) && method_exists( $arg, '__invoke' ) ) { + // __invoke, assume changes are made by reference + $arg( $query ); + } elseif ( is_callable( $arg ) ) { + // assume changes are made by reference + $arg( $query ); + } + } + + return $query; + } + + /** + * {@inheritDoc} + */ + public function hash( array $settings = [], WP_Query $query = null ) { + return md5( json_encode( $this->get_hash_data( $settings, $query ) ) ); + } + + /** + * {@inheritDoc} + */ + public function get_hash_data( array $settings, WP_Query $query = null ) { + $filters = $this->current_filters; + $query_vars = null !== $query + ? $query->query + : array_merge( $this->default_args, $this->query_args ); + + if ( isset( $settings['exclude'] ) ) { + $filters = array_diff_key( + $filters, + array_combine( $settings['exclude'], $settings['exclude'] ) + ); + $query_vars = array_diff_key( + $query_vars, + array_combine( $settings['exclude'], $settings['exclude'] ) + ); + } + + if ( isset( $settings['include'] ) ) { + $filters = array_intersect_key( + $filters, + array_combine( $settings['include'], $settings['include'] ) + ); + $query_vars = array_intersect_key( + $query_vars, + array_combine( $settings['include'], $settings['include'] ) + ); + } + + Tribe__Utils__Array::recursive_ksort( $filters ); + Tribe__Utils__Array::recursive_ksort( $query_vars ); + + return [ 'filters' => $filters, 'query_vars' => $query_vars ]; + } + + /** + * {@inheritDoc} + */ + public function get_last_built_query() { + return $this->last_built_query; + } + + /** + * Checks a SQL relation is valid. + * + * Allowed values are 'OR' and 'AND'. + * + * @since 4.9.6 + * + * @param string $relation The relation to check. + * + * @throws \Tribe__Repository__Usage_Error If the relation is not a valid one. + */ + protected function validate_relation( $relation ) { + if ( ! in_array( $relation, [ 'OR', 'AND' ], true ) ) { + throw Tribe__Repository__Usage_Error::because_this_relation_is_not_valid( $relation ); + } + } + + /** + * Sanitizes and prepares string to be used in a LIKE comparison. + * + * If no leading and trailing `%` was found it will be added at the start and end of the string. + * + * @since 4.9.6 + * + * @param string|array $value The string to prepare or an array of strings to prepare. + * + * @return string|array The sanitized string, or strings. + */ + protected function prepare_like_string( $value ) { + $original_value = $value; + $values = (array) $value; + $prepared = []; + $pattern = '/^(?
          %{0,1})(?.*?)(?%{0,1})$/u';
          +
          +		global $wpdb;
          +
          +		foreach ( $values as $v ) {
          +			preg_match( $pattern, $v, $matches );
          +			$pre = $matches['pre'] ?: '';
          +			$post = $matches['post'] ?: '';
          +			$string = $wpdb->esc_like( $matches['string'] );
          +
          +			if ( '' === $pre && '' === $post ) {
          +				// If the string does not contain any starting and ending placeholder we'll add all combinations.
          +				$prepared[] = '%' . $string;
          +				$prepared[] = $string . '%';
          +				$prepared[] = $string;
          +				$pre = $post = '%';
          +			}
          +
          +			$prepared[] = $pre . $string . $post;
          +		}
          +
          +		return is_array( $original_value ) ? $prepared : reset( $prepared );
          +	}
          +
          +	/**
          +	 * Builds the WHERE clause for a set of fields.
          +	 *
          +	 * This method is table-agnostic. While flexible it will also require some care to be used.
          +	 *
          +	 * @since 4.9.6
          +	 *
          +	 * @param string|array $fields  One or more fields to build the clause for.
          +	 * @param string       $compare The comparison operator to use to build the
          +	 * @param string|array $values One or more values to build the WHERE clause for.
          +	 * @param string       $value_format The format, a `$wpdb::prepare()` compatible one, to use to format the values.
          +	 * @param string       $where_relation The relation to apply between each WHERE fragment.
          +	 * @param string       $value_relation The relation to apply between each value fragment.
          +	 *
          +	 * @return string The built WHERE clause.
          +	 *
          +	 * @throws \Tribe__Repository__Usage_Error If the relations are not valid or another WHERE building issue happens.
          +	 */
          +	protected function build_fields_where_clause(
          +		$fields,
          +		$compare,
          +		$values,
          +		$value_format = '%s',
          +		$where_relation = 'OR',
          +		$value_relation = 'OR'
          +	) {
          +		$this->validate_relation( $where_relation );
          +		$this->validate_relation( $value_relation );
          +		global $wpdb;
          +		$fields_where_clauses = [];
          +		$fields = (array) $fields;
          +		$values = (array) $values;
          +		foreach ( $fields as $field ) {
          +			$value_clauses = [];
          +			foreach ( $values as $compare_value ) {
          +				if ( ! is_array( $compare_value ) || count( $compare_value ) === 1 ) {
          +					$value_clauses[] = $wpdb->prepare(
          +						"({$field} {$compare} {$value_format})",
          +						$compare_value
          +					);
          +				} else {
          +					$value_format = implode(
          +						',',
          +						array_fill( 0, count( $compare_value ), $value_format )
          +					);
          +					$value_clauses[] = $wpdb->prepare(
          +						"({$field} {$compare} ({$value_format}))",
          +						$compare_value
          +					);
          +				}
          +			}
          +			$fields_where_clauses[] = '(' . implode( " {$value_relation} ", $value_clauses ) . ')';
          +		}
          +
          +		$fields_where = $wpdb->remove_placeholder_escape(
          +			implode( " {$where_relation} ", $fields_where_clauses )
          +		);
          +
          +		return $fields_where;
          +	}
          +
          +	/**
          +	 * Returns the term IDs of terms matching a criteria, the match is made on the terms slug and name.
          +	 *
          +	 * This should be used to break-down a query and fetch term IDs, to then use in a "lighter" join, later.
          +	 *
          +	 * @since 4.9.6
          +	 *
          +	 * @param string|array $taxonomy The taxonomy, or taxonomies, to fetch the terms for.
          +	 * @param string $compare The comparison operator to use, e.g. 'LIKE' or '=>'.
          +	 * @param string|array $value An array of values to compare the terms slug or names with.
          +	 * @param string $relation The relation, either 'OR' or 'AND', to apply to the matching.
          +	 * @param string $format The format, a `$wpdb::prepare()` supported one, to use to format the values for the query.
          +	 *
          +	 * @return array An array of term IDs matching the query, if any.
          +	 */
          +	protected function fetch_taxonomy_terms_matches( $taxonomy, $compare, $value, $relation = 'OR', $format = '%s' ) {
          +		global $wpdb;
          +		$taxonomies = (array) $taxonomy;
          +		$values = (array) $value;
          +
          +		$compare_target = count( $values ) > 1
          +			? '(' . $this->filter_query->create_interval_of_strings( $values ) . ')'
          +			: $wpdb->prepare( $format, reset( $values ) );
          +
          +		$taxonomies_interval = $this->filter_query->create_interval_of_strings( $taxonomies );
          +
          +		$query = "SELECT  tt.term_taxonomy_id FROM {$wpdb->terms} AS t
          +			INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
          +			WHERE tt.taxonomy IN ({$taxonomies_interval}) AND
          +			( t.slug {$compare} {$compare_target} {$relation} t.name {$compare} {$compare_target} )";
          +
          +		return $wpdb->get_col( $wpdb->remove_placeholder_escape( $query ) );
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function where_multi( array $fields, $compare, $value, $where_relation = 'OR', $value_relation = 'OR' ) {
          +		$compare = strtoupper( trim( $compare ) );
          +
          +		// Check each value is compatible with the comparison operator.
          +		$values = (array) $value;
          +		foreach ( $values as $v ) {
          +			$this->validate_operator_and_values( $compare, 'where_multi', $v );
          +		}
          +
          +		global $wpdb;
          +
          +		if ( in_array( $compare, [ 'LIKE', 'NOT LIKE' ], true ) ) {
          +			$values = $this->prepare_like_string( $values );
          +		}
          +
          +		$where_relation = strtoupper( trim( $where_relation ) );
          +		$this->validate_relation( $where_relation );
          +		$value_relation = strtoupper( trim( $value_relation ) );
          +		$this->validate_relation( $value_relation );
          +
          +		$post_fields = [];
          +		$taxonomies = [];
          +
          +		foreach ( $fields as $field ) {
          +			if ( $this->is_a_post_field( $field ) ) {
          +				$post_fields[] = $field;
          +			} elseif ( array_key_exists( $field, $this->simple_tax_schema ) ) {
          +				// Handle simple tax schema aliases.
          +				$schema = $this->simple_tax_schema[ $field ]['taxonomy'];
          +
          +				if ( ! is_array( $schema ) ) {
          +					$taxonomies[] = $schema;
          +
          +					continue;
          +				}
          +
          +				// If doing an AND where relation, pass all taxonomies in to be grouped with OR.
          +				if ( 'AND' === $where_relation ) {
          +					$this->where_multi( $schema, $compare, $value, 'OR', $value_relation );
          +
          +					continue;
          +				}
          +
          +				foreach ( $schema as $taxonomy ) {
          +					$taxonomies[] = $taxonomy;
          +				}
          +			} elseif ( array_key_exists( $field, $this->simple_meta_schema ) ) {
          +				// Handle simple meta schema aliases.
          +				$schema = $this->simple_meta_schema[ $field ]['meta_key'];
          +
          +				if ( ! is_array( $schema ) ) {
          +					$custom_fields[] = $schema;
          +
          +					continue;
          +				}
          +
          +				// If doing an AND where relation, pass all meta keys in to be grouped with OR.
          +				if ( 'AND' === $where_relation ) {
          +					$this->where_multi( $schema, $compare, $value, 'OR', $value_relation );
          +
          +					continue;
          +				}
          +
          +				foreach ( $schema as $meta_key ) {
          +					$custom_fields[] = $meta_key;
          +				}
          +			} elseif ( $this->is_a_taxonomy( $field ) ) {
          +				$taxonomies[] = $field;
          +			} else {
          +				$custom_fields[] = $field;
          +			}
          +		}
          +
          +		$value_formats = [];
          +
          +		foreach ( $values as $v ) {
          +			$value_format = '%d';
          +			if ( is_string( $v ) ) {
          +				$value_format = '%s';
          +			} elseif ( (int) $v !== (float) $v ) {
          +				$value_format = '%f';
          +			}
          +			$value_formats[] = $value_format;
          +		}
          +
          +		// If the value formats differ then treat all of them as strings.
          +		if ( count( array_unique( $value_formats ) ) > 1 ) {
          +			$value_format = '%s';
          +		} else {
          +			$value_format = reset( $value_formats );
          +		}
          +
          +		$where = [];
          +
          +		if ( ! empty( $post_fields ) ) {
          +			$post_fields = array_map( static function ( $post_field ) use ( $wpdb ) {
          +				return "{$wpdb->posts}.$post_field";
          +			}, $post_fields );
          +
          +			$post_fields_where = $this->build_fields_where_clause(
          +				$post_fields,
          +				$compare,
          +				$values,
          +				$value_format,
          +				$where_relation,
          +				$value_relation
          +			);
          +
          +			$wheres[] = $post_fields_where;
          +		}
          +
          +		if ( ! empty( $taxonomies ) ) {
          +			$all_matching_term_ids = [];
          +			$taxonomy_values = $values;
          +
          +			if ( in_array( $compare, [ 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ], true ) ) {
          +				// We can use multiple values in the same query.
          +				$taxonomy_values = [ $values ];
          +			}
          +
          +			foreach ( $taxonomy_values as $taxonomy_value ){
          +				$matching_term_ids = $this->fetch_taxonomy_terms_matches(
          +					$taxonomies,
          +					$compare,
          +					$taxonomy_value,
          +					$where_relation,
          +					$value_format
          +				);
          +
          +				if ( empty( $matching_term_ids ) ) {
          +					if ( 'AND' === $value_relation ) {
          +						// No reason to waste any more time.
          +						$this->void_query = true;
          +
          +						return $this;
          +					}
          +
          +					continue;
          +				}
          +
          +				$all_matching_term_ids[] = $matching_term_ids;
          +			}
          +
          +			$intersection = count( $all_matching_term_ids ) > 1
          +				? array_intersect( ...$all_matching_term_ids )
          +				: reset( $all_matching_term_ids );
          +
          +			if ( 'AND' === $where_relation && 0 === count( $intersection ) ) {
          +				// Let's not waste any more time.
          +				$this->void_query = true;
          +
          +				return $this;
          +			}
          +
          +			$merge = count( $all_matching_term_ids ) > 1
          +				? array_unique( array_merge( ...$all_matching_term_ids ) )
          +				: (array) reset( $all_matching_term_ids );
          +			$matching_term_ids = $where_relation === 'OR' ? array_filter( $merge ) : array_filter( $intersection );
          +
          +			if ( 'AND' === $where_relation || ! empty( $matching_term_ids ) ) {
          +				// Let's not add WHERE and JOIN clauses if there is nothing to add.
          +				$tt_alias = 'tribe_tt_' . self::$alias_counter ++;
          +				$this->filter_query->join(
          +					"JOIN {$wpdb->term_relationships} {$tt_alias} ON {$wpdb->posts}.ID = {$tt_alias}.object_id"
          +				);
          +				$matching_term_ids_interval = implode( ',', $matching_term_ids );
          +				$wheres[] = "{$tt_alias}.term_taxonomy_id IN ({$matching_term_ids_interval})";
          +			}
          +		}
          +
          +		if ( ! empty( $custom_fields ) ) {
          +			$meta_alias = 'tribe_meta_' . self::$alias_counter ++;
          +
          +			$custom_fields = array_map( static function ( $custom_field ) use ( $wpdb, $meta_alias ) {
          +				return $wpdb->prepare(
          +					"{$meta_alias}.meta_key = %s AND {$meta_alias}.meta_value",
          +					$custom_field
          +				);
          +			}, $custom_fields );
          +
          +			$meta_where = $this->build_fields_where_clause(
          +				$custom_fields,
          +				$compare,
          +				$values,
          +				$value_format,
          +				$where_relation,
          +				$value_relation
          +			);
          +
          +			$this->filter_query->join(
          +				"JOIN {$wpdb->postmeta} {$meta_alias} ON {$wpdb->posts}.ID = {$meta_alias}.post_id"
          +			);
          +
          +			$wheres[] = $meta_where;
          +		}
          +
          +		$this->filter_query->where( implode( " {$where_relation} ", $wheres ) );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function set_query( WP_Query $query ) {
          +		if (
          +			$this->last_built_query instanceof WP_Query
          +			&& !empty($this->last_built_query->request)
          +		){
          +			throw Tribe__Repository__Usage_Error::because_query_cannot_be_set_after_it_ran();
          +		}
          +		$this->last_built_query = $query;
          +		$this->last_built_hash  = $this->hash();
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function set_found_rows( $found_rows ) {
          +		$this->skip_found_rows = ! $found_rows;
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * Flush current filters and query information.
          +	 *
          +	 * @since 4.9.10
          +	 *
          +	 * @return self
          +	 */
          +	public function flush() {
          +		$this->current_query    = null;
          +		$this->current_filters  = [];
          +		$this->current_filter   = null;
          +		$this->last_built_query = null;
          +		$this->last_built_hash  = '';
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function next() {
          +		$next         = clone $this;
          +		$current_page = isset( $this->query_args['paged'] )
          +			? (int) $this->query_args['paged']
          +			: 1;
          +		$next->page( $current_page + 1 );
          +
          +		// Let's try to avoid running a query if we already know if a next page will yield any result or not.
          +		$query_ran = ! empty( $this->last_built_query ) && ! empty( $this->last_built_query->request );
          +		if ( $query_ran && ( false === (bool) $this->last_built_query->get( 'no_found_rows' ) ) ) {
          +			$found             = $this->last_built_query->found_posts;
          +			$posts_per_page    = $this->last_built_query->get( 'posts_per_page' );
          +			$this_is_last_page = ( $current_page * $posts_per_page ) >= $found;
          +			if ( $this_is_last_page ) {
          +				$next->void_query = true;
          +			}
          +		}
          +
          +		$next->last_built_query = null;
          +
          +		return $next;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function prev() {
          +		$prev         = clone $this;
          +		$current_page = isset( $this->query_args['paged'] )
          +			? (int) $this->query_args['paged']
          +			: 1;
          +
          +		if ( $current_page === 1 ) {
          +			$prev->void_query = true;
          +
          +			return $prev;
          +		}
          +
          +		// If we're on page 1 we know there will be previous posts.
          +		$prev->page( $current_page - 1 );
          +		$prev->last_built_query = null;
          +
          +		return $prev;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function void_query( $void_query = true ) {
          +		$this->void_query = (bool) $void_query;
          +
          +		return $this;
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Core_Read_Interface.php b/tribe-common/src/Tribe/Repository/Core_Read_Interface.php
          new file mode 100644
          index 0000000000..a342f7313b
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Core_Read_Interface.php
          @@ -0,0 +1,402 @@
          +,  ]. * * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function by_args( array $args );
          +
          +	/**
          +	 * Applies a filter to the query.
          +	 *
          +	 * While the signature only shows 2 arguments additional arguments will be passed
          +	 * to the schema filters.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $key
          +	 * @param mixed  $value
          +	 * @param mixed  ...$args Additional, optional, call arguments that will be passed to
          +	 *                        the schema.
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function by( $key, $value = null );
          +
          +	/**
          +	 * Just an alias of the `by` method to allow for easier reading.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $key
          +	 * @param mixed  $value
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function where( $key, $value = null );
          +
          +	/**
          +	 * Sets the page of posts to fetch.
          +	 *
          +	 * Mind that this implementation does not support a `by( 'page', 2 )`
          +	 * filter to force more readable code.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param int $page
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function page( $page );
          +
          +	/**
          +	 * Sets the number of posts to retrieve per page.
          +	 *
          +	 * Mind that this implementation does not support a `by( 'per_page', 5 )`
          +	 * filter to force more readable code; by default posts per page is set to
          +	 * the pagination defaults for the post type.
          +	 *
          +	 * @param int $per_page
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function per_page( $per_page );
          +
          +	/**
          +	 * Returns the number of posts found matching the query.
          +	 *
          +	 * Mind that this value ignores the offset returning the
          +	 * number of results if limits where not applied.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @return int
          +	 */
          +	public function found();
          +
          +	/**
          +	 * Returns all posts matching the query.
          +	 *
          +	 * Mind that "all" means "all the posts matching all the filters" so pagination applies.
          +	 *
          +	 * @return array
          +	 */
          +	public function all();
          +
          +	/**
          +	 * Sets the offset on the query.
          +	 *
          +	 * Mind that this implementation does not support a `by( 'offset', 2 )`
          +	 * filter to force more readable code.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param int  $offset
          +	 * @param bool $increment Whether to increment the offset by the value
          +	 *                        or replace it.
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function offset( $offset, $increment = false );
          +
          +	/**
          +	 * Sets the order on the query.
          +	 *
          +	 * Mind that this implementation does not support a `by( 'order', 2 )`
          +	 * filter to force more readable code.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $order
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function order( $order = 'ASC' );
          +
          +	/**
          +	 * Sets the order criteria results should be fetched by.
          +	 *
          +	 * Mind that this implementation does not support a `by( 'order_by', 'title' )`
          +	 * filter to force more readable code.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string|array $order_by The post field, custom field or alias key to order posts by.
          +	 * @param string                      $order    The order direction; optional; shortcut for the `order` method; defaults
          +	 *                                              to `DESC`.
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function order_by( $order_by, $order = 'DESC' );
          +
          +	/**
          +	 * Sets the fields that should be returned by the query.
          +	 *
          +	 * Mind that this implementation does not support a `by( 'fields', 'ids' )`
          +	 * filter to force more readable code.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $fields
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function fields( $fields );
          +
          +	/**
          +	 * Sugar method to set the `post__in` argument.
          +	 *
          +	 * Successive calls will stack, not replace each one.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|int $post_ids
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function in( $post_ids );
          +
          +	/**
          +	 * Sugar method to set the `post__not_in` argument.
          +	 *
          +	 * Successive calls will stack, not replace each one.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|int $post_ids
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function not_in( $post_ids );
          +
          +	/**
          +	 * Sugar method to set the `post_parent__in` argument.
          +	 *
          +	 * Successive calls will stack, not replace each one.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|int $post_id
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function parent( $post_id );
          +
          +	/**
          +	 * Sugar method to set the `post_parent__in` argument.
          +	 *
          +	 * Successive calls will stack, not replace each one.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array $post_ids
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function parent_in( $post_ids );
          +
          +	/**
          +	 * Sugar method to set the `post_parent__not_in` argument.
          +	 *
          +	 * Successive calls will stack, not replace each one.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array $post_ids
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function parent_not_in( $post_ids );
          +
          +	/**
          +	 * Sugar method to set the `s` argument.
          +	 *
          +	 * Successive calls will replace the search string.
          +	 * This is the default WordPress searh, to search by title,
          +	 * content or excerpt only use the `title`, `content`, `excerpt` filters.
          +	 *
          +	 * @param $search
          +	 *
          +	 * @return Tribe__Repository__Read_Interface
          +	 */
          +	public function search( $search );
          +
          +	/**
          +	 * Returns the number of posts found matching the query in the current page.
          +	 *
          +	 * While the `found` method will return the number of posts found
          +	 * across all pages this method will only return the number of
          +	 * posts found in the current page.
          +	 * Differently from the `found` method this method will apply the
          +	 * offset if set.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @return int
          +	 */
          +	public function count();
          +
          +	/**
          +	 * Returns the first post of the page matching the current query.
          +	 *
          +	 * If, by default or because set with the `per_page` method, all
          +	 * posts matching the query should be returned then this will be
          +	 * the first post of all those matching the query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @return WP_Post|mixed|null
          +	 *
          +	 * @see   Tribe__Repository__Read_Interface::per_page()
          +	 */
          +	public function first();
          +
          +	/**
          +	 * Returns the last post of the page matching the current query.
          +	 *
          +	 * If, by default or because set with the `per_page` method, all
          +	 * posts matching the query should be returned then this will be
          +	 * the last post of all those matching the query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @return WP_Post|mixed|null
          +	 *
          +	 * @see   Tribe__Repository__Read_Interface::per_page()
          +	 */
          +	public function last();
          +
          +	/**
          +	 * Returns the nth post (1-based) of the page matching the current query.
          +	 *
          +	 * Being 1-based the second post can be fetched using `nth( 2 )`.
          +	 * If, by default or because set with the `per_page` method, all
          +	 * posts matching the query should be returned then this will be
          +	 * the nth post of all those matching the query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param int $n
          +	 *
          +	 * @return WP_Post|mixed|null
          +	 *
          +	 * @see   Tribe__Repository__Read_Interface::per_page()
          +	 */
          +	public function nth( $n );
          +
          +	/**
          +	 * Returns the first n posts of the page matching the current query.
          +	 *
          +	 * If, by default or because set with the `per_page` method, all
          +	 * posts matching the query should be returned then this method will
          +	 * return the first n posts of all those matching the query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @return array An array of posts matching the query.
          +	 *
          +	 * @see   Tribe__Repository__Read_Interface::per_page()
          +	 */
          +	public function take( $n );
          +
          +	/**
          +	 * Plucks a field from all results and returns it.
          +	 *
          +	 * This method will implicitly build and use a `WP_List_Util` instance on the return
          +	 * value of a call to the `all` method.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param string $field The field to pluck from each result.
          +	 *
          +	 * @return array An array of the plucked results.
          +	 *
          +	 * @see   \wp_list_pluck()
          +	 */
          +	public function pluck( $field );
          +
          +	/**
          +	 * Filters the results according to the specified criteria.
          +	 *
          +	 * This method will implicitly build and use a `WP_List_Util` instance on the return
          +	 * value of a call to the `all` method.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param array  $args     Optional. An array of key => value arguments to match
          +	 *                         against each object. Default empty array.
          +	 * @param string $operator Optional. The logical operation to perform. 'AND' means
          +	 *                         all elements from the array must match. 'OR' means only
          +	 *                         one element needs to match. 'NOT' means no elements may
          +	 *                         match. Default 'AND'.
          +	 *
          +	 * @return array An array of the filtered results.
          +	 *
          +	 * @see   \wp_list_filter()
          +	 */
          +	public function filter( $args = [], $operator = 'AND' );
          +
          +	/**
          +	 * Sorts the results according to the specified criteria.
          +	 *
          +	 * This method will implicitly build and use a `WP_List_Util` instance on the return
          +	 * value of a call to the `all` method.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param string|array $orderby       Optional. Either the field name to order by or an array
          +	 *                                    of multiple orderby fields as $orderby => $order.
          +	 * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if $orderby
          +	 *                                    is a string.
          +	 * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
          +	 *
          +	 * @return array An array of the sorted results.
          +	 *
          +	 * @see   \wp_list_sort()
          +	 */
          +	public function sort( $orderby = [], $order = 'ASC', $preserve_keys = false );
          +
          +	/**
          +	 * Builds a collection on the result of the `all()` method call.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @return \Tribe__Utils__Post_Collection
          +	 */
          +	public function collect();
          +
          +	/**
          +	 * Gets the ids of the posts matching the query.
          +	 *
          +	 * @return array An array containing the post IDs to update.
          +	 */
          +	public function get_ids();
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Decorator.php b/tribe-common/src/Tribe/Repository/Decorator.php
          new file mode 100644
          index 0000000000..642e83f42d
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Decorator.php
          @@ -0,0 +1,688 @@
          +decorated->get_default_args();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_default_args( array $default_args ) {
          +		return $this->decorated->set_default_args( $default_args );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function filter_name( $filter_name ) {
          +		$this->decorated->filter_name( $filter_name );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function by_args( array $args ) {
          +		$this->decorated->by_args( $args );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function by( $key, $value = null ) {
          +		$call_args = func_get_args();
          +		call_user_func_array( [ $this->decorated, 'by' ], $call_args );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function where( $key, $value = null ) {
          +		$call_args = func_get_args();
          +		call_user_func_array( [ $this->decorated, 'where' ], $call_args );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function page( $page ) {
          +		$this->decorated->page( $page );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function per_page( $per_page ) {
          +		$this->decorated->per_page( $per_page );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function found() {
          +		return $this->decorated->found();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function all() {
          +		return $this->decorated->all();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function offset( $offset, $increment = false ) {
          +		$this->decorated->offset( $offset );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function order( $order = 'ASC' ) {
          +		$this->decorated->order( $order );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function order_by( $order_by, $order = 'DESC' ) {
          +		$this->decorated->order_by( $order_by, $order );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function fields( $fields ) {
          +		$this->decorated->fields( $fields );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function permission( $permission ) {
          +		$this->decorated->permission( $permission );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function in( $post_ids ) {
          +		$this->decorated->in( $post_ids );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function not_in( $post_ids ) {
          +		$this->decorated->not_in( $post_ids );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function parent( $post_id ) {
          +		$this->decorated->parent( $post_id );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function parent_in( $post_ids ) {
          +		$this->decorated->parent_in( $post_ids );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function parent_not_in( $post_ids ) {
          +		$this->decorated->parent_not_in( $post_ids );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function search( $search ) {
          +		$this->decorated->search( $search );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function count() {
          +		return $this->decorated->count();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function first() {
          +		return $this->decorated->first();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function last() {
          +		return $this->decorated->last();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function nth( $n ) {
          +		return $this->decorated->nth( $n );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function take( $n ) {
          +		return $this->decorated->take( $n );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function by_primary_key( $primary_key ) {
          +		return $this->decorated->by_primary_key( $primary_key );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set( $key, $value ) {
          +		$this->decorated->set( $key, $value );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_query() {
          +		return $this->decorated->get_query();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_args( array $update_map ) {
          +		$this->decorated->set_args( $update_map );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function save( $return_promise = true ) {
          +		$this->decorated->save( $return_promise );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_formatter( Tribe__Repository__Formatter_Interface $formatter ) {
          +		$this->decorated->set_formatter( $formatter );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function join_clause( $join ) {
          +		$this->decorated->join_clause( $join );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function where_clause( $where ) {
          +		$this->decorated->where_clause( $where );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_query_builder( $query_builder ) {
          +		$this->decorated->set_query_builder( $query_builder );
          +	}
          +
          +	/**
          +	 * Sets the repository to be decorated.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param Tribe__Repository__Interface $decorated
          +	 */
          +	protected function set_decorated_repository( Tribe__Repository__Interface $decorated ) {
          +		$this->decorated = $decorated;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function build_query( $use_query_builder = true ) {
          +		return $this->decorated->build_query( $use_query_builder );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function where_or( $callbacks ) {
          +		$call_args = func_get_args();
          +		call_user_func_array( [ $this->decorated, 'where_or' ], $call_args );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function by_related_to_min( $by_meta_keys, $min, $keys = null, $values = null ) {
          +		$this->decorated->by_related_to_min( $by_meta_keys, $min, $keys, $values );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function by_related_to_max( $by_meta_keys, $max, $keys = null, $values = null ) {
          +		$this->decorated->by_related_to_max( $by_meta_keys, $max, $keys, $values );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function by_related_to_between( $by_meta_keys, $min, $max, $keys = null, $values = null ) {
          +		$this->decorated->by_related_to_between( $by_meta_keys, $min, $max, $keys, $values );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function has_filter( $key, $value = null ) {
          +		return $this->decorated->has_filter( $key, $value );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_current_filter() {
          +		return $this->decorated->get_current_filter();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_ids() {
          +		return $this->decorated->get_ids();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function add_schema_entry( $key, $callback ) {
          +		$this->decorated->add_schema_entry( $key, $callback );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function prepare_interval( $values, $format = '%s' ) {
          +		return $this->decorated->prepare_interval( $values, $format );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function delete( $return_promise = false ) {
          +		return $this->decorated->delete( $return_promise );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function async_delete( array $to_delete, $return_promise = true ) {
          +		return $this->decorated->async_delete( $to_delete, $return_promise );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function add_update_field_alias( $alias, $field_name ) {
          +		$this->decorated->add_update_field_alias( $alias, $field_name );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function async_update( array $to_update, $return_promise = true ) {
          +		return $this->decorated->async_update( $to_update, $return_promise );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_update_fields_aliases() {
          +		return $this->decorated->get_update_fields_aliases();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_update_fields_aliases( array $update_fields_aliases ) {
          +		$this->decorated->set_update_fields_aliases( $update_fields_aliases );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_filter_name() {
          +		return $this->decorated->get_filter_name();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function filter_postarr_for_update( array $postarr, $post_id ) {
          +		return $this->decorated->filter_postarr_for_update( $postarr, $post_id );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function build_postarr( $id = null ) {
          +		return $this->decorated->build_postarr();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function create() {
          +		return $this->decorated->create();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function filter_postarr_for_create( array $postarr ) {
          +		return $this->decorated->filter_postarr_for_create( $postarr, $post_id );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_create_args( array $create_args ) {
          +		$this->decorated->set_create_args( $create_args );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_create_args() {
          +		return $this->decorated->get_create_args();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_display_context( $context = 'default' ) {
          +		$this->decorated->set_display_context( $context );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function set_render_context( $context = 'default' ) {
          +		$this->decorated->set_render_context( $context );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function get_query_for_posts( array $posts ) {
          +		return $this->decorated->get_query_for_posts( $posts );
          +	}
          +
          +	/**
          +	 * Whether the decorator is decorating an instance of a specific repository class or not.
          +	 *
          +	 * The check is made recursively for decorators to get to the first repository implementation.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param string $class The class to check for.
          +	 *
          +	 * @return bool Whether the decorator is decorating an instance of a specific repository class or not.
          +	 */
          +	public function decorates_an_instance_of( $class ) {
          +		return $this->decorated instanceof Tribe__Repository__Decorator
          +			? $this->decorated->decorates_an_instance_of( $class )
          +			: $this->decorated instanceof $class;
          +	}
          +
          +	/**
          +	 * Returns the concrete repository implementation that's "hidden" under the decorator(s).
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @return \Tribe__Repository__Interface The concrete repository instance.
          +	 */
          +	public function get_decorated_repository() {
          +		return $this->decorated instanceof Tribe__Repository__Decorator
          +			? $this->decorated->get_decorated_repository()
          +			: $this->decorated;
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function pluck( $field ) {
          +		return $this->decorated->pluck( $field );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function filter( $orderby = [], $order = 'ASC', $preserve_keys = false ) {
          +		return $this->decorated->filter( $orderby, $order, $preserve_keys );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function sort( $orderby = [], $order = 'ASC', $preserve_keys = false ) {
          +		return $this->decorated->sort( $orderby, $order, $preserve_keys );
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function collect() {
          +		return $this->decorated->collect();
          +	}
          +
          +	/**
          +	 * {@inheritdoc}
          +	 */
          +	public function hash( array $settings = [], WP_Query $query = null ) {
          +		return $this->decorated->hash( $settings );
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function get_hash_data( array $settings, WP_Query $query = null ) {
          +		return $this->decorated->get_hash_data( $settings, $query );
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function get_last_built_query() {
          +		return $this->decorated->last_built_query;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function where_multi( array $fields, $compare, $value, $where_relation = 'OR', $value_relation = 'OR' ) {
          +		$this->decorated->where_multi( $fields, $compare, $value, $where_relation, $value_relation );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * Handle getting additional property from decorated object.
          +	 *
          +	 * @since 4.9.6.1
          +	 *
          +	 * @param string $name Property name.
          +	 *
          +	 * @return mixed
          +	 */
          +	public function __get( $name ) {
          +		return $this->decorated->{$name};
          +	}
          +
          +	/**
          +	 * Handle setting additional property on decorated object.
          +	 *
          +	 * @since 4.9.6.1
          +	 *
          +	 * @param string $name  Property name.
          +	 * @param mixed  $value Property value.
          +	 */
          +	public function __set( $name, $value ) {
          +		$this->decorated->{$name} = $value;
          +	}
          +
          +	/**
          +	 * Check if additional property on decorated object exists.
          +	 *
          +	 * @since 4.9.6.1
          +	 *
          +	 * @param string $name Property name.
          +	 *
          +	 * @return bool
          +	 */
          +	public function __isset( $name ) {
          +		return isset( $this->decorated->{$name} );
          +	}
          +
          +	/**
          +	 * Call methods on decorated object.
          +	 *
          +	 * @since 4.9.6.1
          +	 *
          +	 * @param string $name      Method name.
          +	 * @param array  $arguments Method arguments.
          +	 *
          +	 * @return mixed
          +	 */
          +	public function __call( $name, $arguments ) {
          +		return call_user_func_array( [ $this->decorated, $name ], $arguments );
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function set_query( WP_Query $query ) {
          +		$this->decorated->set_query( $query );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function next() {
          +		return $this->decorated->next();
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function prev() {
          +		return $this->decorated->prev();
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function set_found_rows( $found_rows ) {
          +		$this->decorated->set_found_rows( $found_rows );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * {@inheritDoc}
          +	 */
          +	public function void_query( $void_query = true ) {
          +		$this->decorated->void_query( $void_query );
          +
          +		return $this;
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Filter_Validation.php b/tribe-common/src/Tribe/Repository/Filter_Validation.php
          new file mode 100644
          index 0000000000..11573f1e50
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Filter_Validation.php
          @@ -0,0 +1,61 @@
          + => [  =>  ]
          +	 *  ]
          +	 * ```
          +	 *
          +	 * @since 4.10.2
          +	 *
          +	 * @param       string $filter The name of the filter currently validating.
          +	 * @param array        $call_args The current filter call args, usually `func_get_args()`.
          +	 *
          +	 * @throws Usage_Error If there is a definition for the filter and the argument count or nature is not correct.
          +	 */
          +	protected function ensure_args_for_filter( $filter, array $call_args ) {
          +		$map = isset( static::$filter_args_map ) ? static::$filter_args_map : false;
          +
          +		if ( empty( $map ) ) {
          +			return;
          +		}
          +
          +		$required_args = Arr::get( $filter, $map, false );
          +
          +		if ( false === $required_args ) {
          +			return;
          +		}
          +
          +		if ( count( $required_args ) !== count( $call_args ) ) {
          +			throw Usage_Error::because_filter_requires_args( $filter, array_keys( $required_args ) );
          +		}
          +
          +		$iterator = new \MultipleIterator();
          +		$iterator->attachIterator( new \ArrayIterator( array_keys( $required_args ) ) );
          +		$iterator->attachIterator( new \ArrayIterator( array_values( $required_args ) ) );
          +		$iterator->attachIterator( new \ArrayIterator( $call_args ) );
          +
          +		foreach ( $required_args as list( $arg_name, $validator, $input ) ) {
          +			if ( empty( $validator( $input ) ) ) {
          +				throw Usage_Error::because_filter_arg_is_not_valid( $filter, $arg_name );
          +			}
          +		}
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Formatter_Interface.php b/tribe-common/src/Tribe/Repository/Formatter_Interface.php
          new file mode 100644
          index 0000000000..4e484a769c
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Formatter_Interface.php
          @@ -0,0 +1,24 @@
          +, <...args>]
          +	 *
          +	 * @return $this
          +	 * @throws Tribe__Repository__Usage_Error If one of the callback methods does
          +	 *                                        not add any WHERE clause.
          +	 *
          +	 * @see Tribe__Repository::where_clause()
          +	 * @see Tribe__Repository__Query_Filters::where()
          +	 */
          +	public function where_or( $callbacks );
          +
          +	/**
          +	 * Filters the query to return posts that have got a number or posts
          +	 * related to them by meta at least equal to a value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string|array $by_meta_keys One or more `meta_keys` relating
          +	 *                                   another post TO this post type.
          +	 * @param int          $min          The minimum number of posts of another type that should
          +	 *                                   be related to the queries post type(s).
          +	 * @param string|array $keys         One or more meta_keys to check on the post type in relation
          +	 *                                   with the query post type(s); if the `$values` parameter is
          +	 *                                   not provided then this will trigger an EXISTS check.
          +	 * @param string|array $values       One or more value the meta_key specified with `$keys` should
          +	 *                                   match.
          +	 *
          +	 * @return $this
          +	 */
          +	public function by_related_to_min( $by_meta_keys, $min, $keys = null, $values = null );
          +
          +	/**
          +	 * Filters the query to return posts that have got a number or posts
          +	 * related to them by meta at most equal to a value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string|array $by_meta_keys One or more `meta_keys` relating
          +	 *                                   another post TO this post type.
          +	 *                                   be related to the queries post type(s).
          +	 * @param int          $max          The maximum number of posts of another type that should
          +	 *                                   be related to the queries post type(s).
          +	 * @param string|array $keys         One or more meta_keys to check on the post type in relation
          +	 *                                   with the query post type(s); if the `$values` parameter is
          +	 *                                   not provided then this will trigger an EXISTS check.
          +	 * @param string|array $values       One or more value the meta_key specified with `$keys` should
          +	 *                                   match.
          +	 *
          +	 * @return $this
          +	 */
          +	public function by_related_to_max( $by_meta_keys, $max, $keys = null, $values = null );
          +
          +	/**
          +	 * Filters the query to return posts that have got a number or posts
          +	 * related to them by meta between two values.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string|array $by_meta_keys One or more `meta_keys` relating
          +	 *                                   another post TO this post type.
          +	 * @param int          $min          The minimum number of posts of another type that should
          +	 *                                   be related to the queries post type(s).
          +	 * @param int          $max          The maximum number of posts of another type that should
          +	 *                                   be related to the queries post type(s).
          +	 *
          +	 * @param string|array $keys         One or more meta_keys to check on the post type in relation
          +	 *                                   with the query post type(s); if the `$values` parameter is
          +	 *                                   not provided then this will trigger an EXISTS check.
          +	 * @param string|array $values       One or more value the meta_key specified with `$keys` should
          +	 *                                   match.
          +	 *
          +	 * @return $this
          +	 */
          +	public function by_related_to_between( $by_meta_keys, $min, $max, $keys = null, $values = null );
          +
          +	/**
          +	 * Adds an entry to the repository filter schema.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param string   $key      The filter key, the one that will be used in `by` and `where`
          +	 *                           calls.
          +	 * @param callable $callback The function that should be called to apply this filter.
          +	 */
          +	public function add_schema_entry( $key, $callback );
          +
          +	/**
          +	 * Returns an hash string for this repository instance filters and, optionally, a generated query.
          +	 *
          +	 * By default all applied filters, and query vars, will be included but specific filters can
          +	 * be excluded, or included, from the hash generation.
          +	 * The possibility to include the query in the hash generation is required as the query vars could
          +	 * be further modified after the repository filters are applied and the query is built.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param array          $settings An array of settings to define how the hash should be produced in the shape
          +	 *                                 `[ 'exclude' => [ 'ex_1', ... ], 'include' => [ 'inc_1', ... ] ]`. This array
          +	 *                                 will apply both to the Repository filters and the query vars.
          +	 * @param WP_Query|null $query An optional query object to include in the hashing.
          +	 *
          +	 * @return string The generated hash string.
          +	 *
          +	 */
          +	public function hash( array $settings = [], WP_Query $query = null );
          +
          +	/**
          +	 * Returns the data the repository would use to build the hash.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param array          $settings An array of settings to define how the hash should be produced in the shape
          +	 *                                 `[ 'exclude' => [ 'ex_1', ... ], 'include' => [ 'inc_1', ... ] ]`. This array
          +	 *                                 will apply both to the Repository filters and the query vars.
          +	 * @param WP_Query|null $query An optional query object to include in the hashing.
          +	 *
          +	 * @return array An array of hash data components.
          +	 */
          +	public function get_hash_data( array $settings, WP_Query $query = null );
          +
          +	/**
          +	 * Returns the last built query from the repository instance.
          +	 *
          +	 * @since 4.9.6
          +	 *
          +	 * @return WP_Query|null The last built query instance if any.
          +	 */
          +	public function get_last_built_query();
          +
          +	/**
          +	 * Builds, and adds to the query, a WHERE clause to the query on multiple fields.
          +	 *
          +	 * @since 4.9.6
          +	 *
          +	 * @param array  $fields         The fields to add WHERE clauses for. The fields can be post fields, custom fields or
          +	 *                               taxonomy terms.
          +	 * @param string $compare        The comparison operator to use, e.g. 'LIKE' or '>'.
          +	 * @param mixed  $value          The value, or values, to compare with; the format will be set depending on the type of
          +	 *                               each value.
          +	 * @param string $where_relation The relation to join the WHERE clauses with, either 'OR' or 'AND'; default to 'OR'.
          +	 * @param string $value_relation The relation to join the value clauses in case the value is an array, either 'OR'
          +	 *                               or 'AND'; defaults to 'OR'.
          +	 *
          +	 * @return $this This repository instance to allow chain calls.
          +	 *
          +	 * @throws \Tribe__Repository__Usage_Error If the comparison operator or the relation are not valid.
          +	 */
          +	public function where_multi( array $fields, $compare, $value, $where_relation = 'OR', $value_relation = 'OR' );
          +
          +	/**
          +	 * Sets the query instance the repository will use.
          +	 *
          +	 * Setting a query explicitly
          +	 *
          +	 * @since 4.9.9
          +	 *
          +	 * @param  \WP_Query  $query An query instance.
          +	 *
          +	 * @return \Tribe__Repository__Interface The repository instance, for chaining.
          +	 * @throws \Tribe__Repository__Usage_Error If trying to set the query after a fetching operation is done.
          +	 */
          +	public function set_query( WP_Query $query );
          +
          +	/**
          +	 * Returns a cloned instance of the repository that will yield the next page results.
          +	 *
          +	 * Mind that this method will always return a Repository instance, no matter if a next page exists or not.
          +	 * If a next page does not exist then the instance returned by this method will yield no posts and a count of `0`.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @return \Tribe__Repository__Interface The repository instance that will yield the next page results.
          +	 */
          +	public function next();
          +
          +	/**
          +	 * Returns a cloned instance of the repository that will yield the previous page results.
          +	 *
          +	 * Mind that this method will always return a Repository instance, no matter if a previous page exists or not.
          +	 * If a previous page does not exist then the instance returned by this method will yield no posts and a count
          +	 * of `0`.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @return \Tribe__Repository__Interface The repository instance that will yield the previous page results.
          +	 */
          +	public function prev();
          +
          +	/**
          +	 * Sets the found rows calculation to be enabled for queries.
          +	 *
          +	 * @since 4.9.10
          +	 *
          +	 * @param bool $found_rows Whether found rows calculation should be enabled.
          +	 *
          +	 * @return \Tribe__Repository__Interface The repository instance, for chaining.
          +	 */
          +	public function set_found_rows( $found_rows );
          +
          +	/**
          +	 * Voids the repositories queries preventing the repository from running any query.
          +	 *
          +	 * @since 4.9.14
          +	 *
          +	 * @param bool $void Whether to void the repository queries or not.
          +	 *
          +	 * @return Tribe__Repository__Interface $this The repository instance.
          +	 */
          +	public function void_query( $void_query = true );
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Query_Filters.php b/tribe-common/src/Tribe/Repository/Query_Filters.php
          new file mode 100644
          index 0000000000..c04f602621
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Query_Filters.php
          @@ -0,0 +1,1139 @@
          + [
          +			'post_title'   => [],
          +			'post_content' => [],
          +			'post_excerpt' => [],
          +		],
          +		'status' => [],
          +		'join'   => [],
          +		'where'  => [],
          +	];
          +
          +	/**
          +	 * An array of the filters that can be set and unset by id.
          +	 *
          +	 * @since 4.9.14
          +	 *
          +	 * @var array
          +	 */
          +	protected static $identifiable_filters = [ 'fields', 'join', 'where', 'orderby' ];
          +
          +	/**
          +	 * @var array
          +	 */
          +	protected $query_vars;
          +
          +	/**
          +	 * @var WP_Query
          +	 */
          +	protected $current_query;
          +
          +	/**
          +	 * @var int A reasonably large number for the LIMIT clause.
          +	 */
          +	protected $really_large_number = 99999999;
          +
          +	/**
          +	 * @var array A list of the filters this class has added.
          +	 */
          +	protected $active_filters = [];
          +
          +	/**
          +	 * @var bool
          +	 */
          +	protected $buffer_where_clauses = false;
          +
          +	/**
          +	 * @var array
          +	 */
          +	protected $buffered_where_clauses = [];
          +
          +	/**
          +	 * Stores the last request run by the current query.
          +	 *
          +	 * @var string
          +	 */
          +	protected $last_request;
          +
          +	/**
          +	 * Tribe__Repository__Query_Filters constructor.
          +	 *
          +	 * @since 4.7.19
          +	 */
          +	public function __construct() {
          +		$this->query_vars = self::$initial_query_vars;
          +	}
          +
          +	/**
          +	 * Builds an "not exists or is not in" media query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|string     $meta_keys On what meta_keys the check should be made.
          +	 * @param int|string|array $values    A single value, an array of values or a CSV list of values.
          +	 * @param string           $query_slug
          +	 *
          +	 * @return array
          +	 */
          +	public static function meta_not_in( $meta_keys, $values, $query_slug ) {
          +		$meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys );
          +		$values    = Tribe__Utils__Array::list_to_array( $values );
          +
          +		if ( empty( $meta_keys ) || count( $values ) === 0 ) {
          +			return [];
          +		}
          +
          +		$args = [
          +			'meta_query' => [
          +				$query_slug => [
          +					'relation' => 'AND',
          +				],
          +			],
          +		];
          +
          +		foreach ( $meta_keys as $key ) {
          +			$args['meta_query'][ $query_slug ][ $key ] = [
          +				'not-exists' => [
          +					'key'     => $key,
          +					'compare' => 'NOT EXISTS',
          +				],
          +				'relation'   => 'OR',
          +			];
          +
          +			if ( count( $values ) > 1 ) {
          +				$args['meta_query'][ $query_slug ][ $key ]['not-in'] = [
          +					'key'     => $key,
          +					'compare' => 'NOT IN',
          +					'value'   => $values,
          +				];
          +			} else {
          +				$args['meta_query'][ $query_slug ][ $key ]['not-equals'] = [
          +					'key'     => $key,
          +					'value'   => $values[0],
          +					'compare' => '!=',
          +				];
          +			}
          +		}
          +
          +		return $args;
          +	}
          +
          +	/**
          +	 * Builds an "exists and is in" media query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|string     $meta_keys On what meta_keys the check should be made.
          +	 * @param int|string|array $values    A single value, an array of values or a CSV list of values.
          +	 * @param string           $query_slug
          +	 *
          +	 * @return array
          +	 */
          +	public static function meta_in( $meta_keys, $values, $query_slug ) {
          +		$meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys );
          +		$values    = Tribe__Utils__Array::list_to_array( $values );
          +
          +		if ( empty( $meta_keys ) || count( $values ) === 0 ) {
          +			return [];
          +		}
          +
          +		$args = [
          +			'meta_query' => [
          +				$query_slug => [
          +					'relation' => 'OR',
          +				],
          +			],
          +		];
          +
          +		foreach ( $meta_keys as $meta_key ) {
          +			if ( count( $values ) > 1 ) {
          +				$args['meta_query'][ $query_slug ][ $meta_key ] = [
          +					'key'     => $meta_key,
          +					'compare' => 'IN',
          +					'value'   => $values,
          +				];
          +			} else {
          +				$args['meta_query'][ $query_slug ][ $meta_key ] = [
          +					'key'     => $meta_key,
          +					'compare' => '=',
          +					'value'   => $values[0],
          +				];
          +			}
          +		}
          +
          +		return $args;
          +	}
          +
          +	/**
          +	 * Builds a meta query to check that at least of the meta key exists.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|string $meta_keys
          +	 * @param string       $query_slug
          +	 *
          +	 * @return array
          +	 */
          +	public static function meta_exists( $meta_keys, $query_slug ) {
          +		$meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys );
          +
          +		if ( empty( $meta_keys ) ) {
          +			return [];
          +		}
          +
          +		$args = [
          +			'meta_query' => [
          +				$query_slug => [
          +					'relation' => 'OR',
          +				],
          +			],
          +		];
          +
          +		foreach ( $meta_keys as $meta_key ) {
          +			$args['meta_query'][ $query_slug ][ $meta_key ] = [
          +				'key'     => $meta_key,
          +				'compare' => 'EXISTS',
          +			];
          +		}
          +
          +		return $args;
          +	}
          +
          +	/**
          +	 * Builds a meta query to check that a meta is either equal to a value or
          +	 * not exists.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|string $meta_keys
          +	 * @param array|string $values
          +	 * @param string       $query_slug
          +	 *
          +	 * @return array
          +	 */
          +	public static function meta_in_or_not_exists( $meta_keys, $values, $query_slug ) {
          +		$meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys );
          +		$values    = Tribe__Utils__Array::list_to_array( $values );
          +
          +		if ( empty( $meta_keys ) || count( $values ) === 0 ) {
          +			return [];
          +		}
          +
          +		$args = [
          +			'meta_query' => [
          +				$query_slug => [
          +					'relation' => 'AND',
          +				],
          +			],
          +		];
          +
          +		foreach ( $meta_keys as $meta_key ) {
          +			$args['meta_query'][ $query_slug ][ $meta_key ]['does-not-exist'] = [
          +				'key'     => $meta_key,
          +				'compare' => 'NOT EXISTS',
          +			];
          +			$args['meta_query'][ $query_slug ][ $meta_key ]['relation']       = 'OR';
          +			if ( count( $values ) > 1 ) {
          +				$args['meta_query'][ $query_slug ][ $meta_key ]['in'] = [
          +					'key'     => $meta_key,
          +					'compare' => 'IN',
          +					'value'   => $values,
          +				];
          +			} else {
          +				$args['meta_query'][ $query_slug ][ $meta_key ]['equals'] = [
          +					'key'     => $meta_key,
          +					'compare' => '=',
          +					'value'   => $values[0],
          +				];
          +			}
          +		}
          +
          +		return $args;
          +	}
          +
          +	/**
          +	 * Builds a meta query to check that a meta is either not equal to a value or
          +	 * not exists.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param array|string $meta_keys
          +	 * @param array|string $values
          +	 * @param string       $query_slug
          +	 *
          +	 * @return array
          +	 */
          +	public static function meta_not_in_or_not_exists( $meta_keys, $values, $query_slug ) {
          +		$meta_keys = Tribe__Utils__Array::list_to_array( $meta_keys );
          +		$values    = Tribe__Utils__Array::list_to_array( $values );
          +
          +		if ( empty( $meta_keys ) || count( $values ) === 0 ) {
          +			return [];
          +		}
          +
          +		$args = [
          +			'meta_query' => [
          +				$query_slug => [
          +					'relation' => 'AND',
          +				],
          +			],
          +		];
          +
          +		foreach ( $meta_keys as $meta_key ) {
          +			$args['meta_query'][ $query_slug ][ $meta_key ]['does-not-exist'] = [
          +				'key'     => $meta_key,
          +				'compare' => 'NOT EXISTS',
          +			];
          +			$args['meta_query'][ $query_slug ][ $meta_key ]['relation']       = 'OR';
          +
          +			if ( count( $values ) > 1 ) {
          +				$args['meta_query'][ $query_slug ][ $meta_key ]['not-in'] = [
          +					'key'     => $meta_key,
          +					'compare' => 'NOT IN',
          +					'value'   => $values,
          +				];
          +			} else {
          +				$args['meta_query'][ $query_slug ][ $meta_key ]['not-equals'] = [
          +					'key'     => $meta_key,
          +					'compare' => '!=',
          +					'value'   => $values[0],
          +				];
          +			}
          +		}
          +
          +		return $args;
          +	}
          +
          +	/**
          +	 * Filters the WHERE clause of the query to match posts with a field like.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $where
          +	 * @param WP_Query $query
          +	 *
          +	 * @return string
          +	 */
          +	public function filter_by_like( $where, WP_Query $query ) {
          +		if ( $query !== $this->current_query ) {
          +			return $where;
          +		}
          +
          +		if ( empty( $this->query_vars['like'] ) ) {
          +			return $where;
          +		}
          +
          +		foreach ( $this->query_vars['like'] as $field => $entries ) {
          +			foreach ( $entries as $entry ) {
          +				$where .= $this->and_field_like( $field, $entry );
          +			}
          +		}
          +
          +		return $where;
          +	}
          +
          +	/**
          +	 * Builds the escaped WHERE entry to match a field like the entry.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $field
          +	 * @param string $entry
          +	 *
          +	 * @return string
          +	 */
          +	protected function and_field_like( $field, $entry ) {
          +		/** @var wpdb $wpdb */
          +		global $wpdb;
          +
          +		$like       = $wpdb->esc_like( $entry );
          +		$variations = [
          +			$wpdb->prepare( "{$wpdb->posts}.{$field} LIKE %s ", "{$like}%" ),
          +			$wpdb->prepare( "{$wpdb->posts}.{$field} LIKE %s ", "%{$like}%" ),
          +			$wpdb->prepare( "{$wpdb->posts}.{$field} LIKE %s ", "%{$like}" ),
          +		];
          +
          +		return ' AND (' . implode( ' OR ', $variations ) . ')';
          +	}
          +
          +	/**
          +	 * Filters the found posts value to apply filtering and selections on the PHP
          +	 * side of things.
          +	 *
          +	 * Here we perform, after the query did run, further filtering operations that would
          +	 * result in more JOIN and/or sub-SELECT clauses being added to the query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param int      $found_posts The number of found posts.
          +	 * @param WP_Query $query       The current query object.
          +	 *
          +	 * @return string
          +	 */
          +	public function filter_found_posts( $found_posts, WP_Query $query ) {
          +		if ( $query !== $this->current_query ) {
          +			return $found_posts;
          +		}
          +
          +		if ( empty( $this->query_vars['found_posts_filters'] ) ) {
          +			return $found_posts;
          +		}
          +
          +		$filtered_found_posts = $found_posts;
          +		$ids_only             = $query->get( 'fields' ) === 'ids';
          +
          +		/** @var wpdb $wpdb */
          +		global $wpdb;
          +
          +		/**
          +		 * Handles meta-based relations between posts.
          +		 */
          +		foreach ( $this->query_vars['found_posts_filters']['meta_related'] as $info ) {
          +			list( $meta_keys, $field, $field_values, $compare ) = $info;
          +			$post_ids          = $ids_only ? $query->posts : wp_list_pluck( $query->posts, 'ID' );
          +			$post_ids_interval = '(' . implode( ',', $post_ids ) . ')';
          +			$meta_keys         = "('" . implode( "','", array_map( 'esc_sql', $meta_keys ) ) . "')";
          +			$field             = esc_sql( $field );
          +			$field_values      = is_array( $field_values )
          +				? "('" . implode( "','", array_map( 'esc_sql', $field_values ) ) . "')"
          +				: $wpdb->prepare( '%s', $field_values );
          +
          +			$relation_query = "
          +				SELECT DISTINCT( pm.post_id )
          +				FROM {$wpdb->posts} p
          +				JOIN {$wpdb->postmeta} pm
          +				ON pm.meta_value = p.ID
          +				WHERE pm.post_id IN {$post_ids_interval}
          +				AND pm.meta_key IN {$meta_keys}
          +				AND p.{$field} {$compare} {$field_values}
          +				";
          +
          +			$matching_ids = $wpdb->get_col( $relation_query );
          +
          +			if ( empty( $matching_ids ) ) {
          +				$query->posts         = [];
          +				$filtered_found_posts = 0;
          +				break;
          +			}
          +
          +			if ( $ids_only ) {
          +				$query->posts = array_intersect( $query->posts, $matching_ids );
          +			} else {
          +				$updated_query_posts = [];
          +				foreach ( $query->posts as $this_post ) {
          +					if ( in_array( $this_post->ID, $matching_ids ) ) {
          +						$updated_query_posts[] = $this_post;
          +					}
          +				}
          +				$query->posts = $updated_query_posts;
          +			}
          +			$filtered_found_posts = count( $query->posts );
          +		}
          +
          +		$query->post_count = $filtered_found_posts;
          +
          +		return $filtered_found_posts;
          +	}
          +
          +	/**
          +	 * Sets the current query object.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param WP_Query $query
          +	 */
          +	public function set_query( WP_Query $query ) {
          +		$this->current_query = $query;
          +	}
          +
          +	/**
          +	 * Sets up `posts_where` filtering to get posts with a title like the value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $value
          +	 */
          +	public function to_get_posts_with_title_like( $value ) {
          +		$this->query_vars['like']['post_title'][] = $value;
          +
          +		if ( ! has_filter( 'posts_where', [ $this, 'filter_by_like' ] ) ) {
          +			$this->add_filter( 'posts_where', [ $this, 'filter_by_like' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Proxy method to add a  filter calling the WordPress `add_filter` function
          +	 * and keep track of it.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $tag
          +	 * @param callable $function_to_add
          +	 * @param int      $priority
          +	 * @param int      $accepted_args
          +	 */
          +	protected function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
          +		$this->active_filters[] = [ $tag, $function_to_add, $priority ];
          +		add_filter( $tag, $function_to_add, $priority, $accepted_args );
          +	}
          +
          +	/**
          +	 * Sets up `posts_where` filtering to get posts with a content like the value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $value
          +	 */
          +	public function to_get_posts_with_content_like( $value ) {
          +		$this->query_vars['like']['post_content'][] = $value;
          +
          +		if ( ! has_filter( 'posts_where', [ $this, 'filter_by_like' ] ) ) {
          +			$this->add_filter( 'posts_where', [ $this, 'filter_by_like' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Sets up `posts_where` filtering to get posts with an excerpt like the value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $value
          +	 */
          +	public function to_get_posts_with_excerpt_like( $value ) {
          +		$this->query_vars['like']['post_excerpt'] = $value;
          +
          +		if ( ! has_filter( 'posts_where', [ $this, 'filter_by_like' ] ) ) {
          +			add_filter( 'posts_where', [ $this, 'filter_by_like' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Sets up `posts_where` filtering to get posts with a filtered content like the value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $value
          +	 */
          +	public function to_get_posts_with_filtered_content_like( $value ) {
          +		$this->query_vars['like']['post_content_filtered'][] = $value;
          +
          +		if ( ! has_filter( 'posts_where', [ $this, 'filter_by_like' ] ) ) {
          +			add_filter( 'posts_where', [ $this, 'filter_by_like' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Sets up `posts_where` filtering to get posts with a guid that equals the value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $value
          +	 */
          +	public function to_get_posts_with_guid_like( $value ) {
          +		$this->query_vars['like']['guid'][] = $value;
          +
          +		if ( ! has_filter( 'posts_where', [ $this, 'filter_by_like' ] ) ) {
          +			add_filter( 'posts_where', [ $this, 'filter_by_like' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Sets up `posts_where` filtering to get posts with a `to_ping` field equal to the value.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $value
          +	 */
          +	public function to_get_posts_to_ping( $value ) {
          +		$this->query_vars['to_ping'] = $value;
          +
          +		if ( ! has_filter( 'posts_where', [ $this, 'filter_by_to_ping' ] ) ) {
          +			add_filter( 'posts_where', [ $this, 'filter_by_to_ping' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Filters the WHERE clause of the query to match posts with a specific `to_ping`
          +	 * entry.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $where
          +	 * @param WP_Query $query
          +	 *
          +	 * @return string
          +	 */
          +	public function filter_by_to_ping( $where, WP_Query $query ) {
          +		return $this->where_field_is( $where, $query, 'ping_status' );
          +	}
          +
          +	/**
          +	 * Builds the escaped WHERE entry to match a field that equals the entry.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $where
          +	 * @param WP_Query $query
          +	 * @param string   $field
          +	 * @param string   $prepare
          +	 *
          +	 * @return string
          +	 */
          +	protected function where_field_is( $where, WP_Query $query, $field, $prepare = '%s' ) {
          +		if ( $query !== $this->current_query ) {
          +			return $where;
          +		}
          +
          +
          +		if ( empty( $this->query_vars[ $field ] ) ) {
          +			return $where;
          +		}
          +
          +		/** @var wpdb $wpdb */
          +		global $wpdb;
          +
          +		$where .= $wpdb->prepare( " AND {$wpdb->posts}.{$field} = {$prepare} ", $this->query_vars[ $field ] );
          +
          +		return $where;
          +	}
          +
          +	/**
          +	 * Clean up before the object destruction.
          +	 *
          +	 * @since 4.7.19
          +	 */
          +	public function __destruct() {
          +		// let's make sure we clean up when the object is dereferenced
          +		$this->remove_filters();
          +	}
          +
          +	/**
          +	 * Removes all the filters this class applied.
          +	 *
          +	 * @since 4.7.19
          +	 */
          +	public function remove_filters() {
          +		foreach ( $this->active_filters as $filters ) {
          +			list( $tag, $function_to_add, $priority ) = $filters;
          +			remove_filter( $tag, $function_to_add, $priority );
          +		}
          +	}
          +
          +	/**
          +	 * Add a custom WHERE clause to the query.
          +	 *
          +	 * @since 4.7.19
          +	 * @since 4.9.14 Added the `$id` and `$override` parameters.
          +	 *
          +	 * @param string $where_clause
          +	 * @param null|string $id          Optional WHERE ID to prevent duplicating clauses.
          +	 * @param boolean     $override    Whether to override the clause if a WHERE by the same ID exists or not.
          +	 */
          +	public function where( $where_clause, $id = null, $override =false  ) {
          +		if ( $this->buffer_where_clauses ) {
          +			if ( $id ) {
          +				if ( $override || ! isset( $this->buffered_where_clauses[ $id ] ) ) {
          +					$this->buffered_where_clauses[ $id ] = $where_clause;
          +				}
          +			} else {
          +				$this->buffered_where_clauses[] = '(' . $where_clause . ')';
          +			}
          +		} else {
          +			if ( $id ) {
          +				if ( $override || ! isset( $this->query_vars['where'][ $id ] ) ) {
          +					$this->query_vars['where'][ $id ] = '(' . $where_clause . ')';
          +				}
          +			} else {
          +				$this->query_vars['where'][] = '(' . $where_clause . ')';
          +			}
          +
          +			if ( ! has_filter( 'posts_where', [ $this, 'filter_posts_where' ] ) ) {
          +				add_filter( 'posts_where', [ $this, 'filter_posts_where' ], 10, 2 );
          +			}
          +		}
          +	}
          +
          +	/**
          +	 * Add a custom JOIN clause to the query.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string      $join_clause JOIN clause.
          +	 * @param null|string $id          Optional JOIN ID to prevent duplicating joins.
          +	 * @param boolean     $override    Whether to override the clause if a JOIN by the same ID exists.
          +	 */
          +	public function join( $join_clause, $id = null, $override = false ) {
          +		if ( $id ) {
          +			if ( $override || ! isset( $this->query_vars['join'][ $id ] ) ) {
          +				$this->query_vars['join'][ $id ] = $join_clause;
          +			}
          +		} else {
          +			$this->query_vars['join'][] = $join_clause;
          +		}
          +
          +		if ( ! has_filter( 'posts_join', [ $this, 'filter_posts_join' ] ) ) {
          +			add_filter( 'posts_join', [ $this, 'filter_posts_join' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Add a custom ORDER BY to the query.
          +	 *
          +	 * @since 4.9.5
          +	 * @since 4.9.14 Added the `$id` and `$override` parameters.
          +	 * @since 4.9.21 Added the `$order` and `$after` parameters.
          +	 *
          +	 * @param string|array $orderby       The order by criteria; this argument can be specified in array form to specify
          +	 *                                    multiple order by clauses and orders associated to each,
          +	 *                                    e.g. `[ '_meta_1' => 'ASC', '_meta_2' => 'DESC' ]`. If a simple array is
          +	 *                                    passed, then the order will be set to the default one for each entry.
          +	 *                                    This arguments supports the same formats of the `WP_Query` `orderby` argument.
          +	 * @param null|string  $id            Optional ORDER ID to prevent duplicating order-by clauses.
          +	 * @param boolean      $override      Whether to override the clause if another by the same ID exists.
          +	 * @param bool         $after         Whether to append the order by clause to the ones managed by WordPress or not.
          +	 *                                    Defaults to `false`,to prepend them to the ones managed by WordPress.
          +	 */
          +	public function orderby( $orderby, $id = null, $override = false, $after = false ) {
          +		$orderby_key = $after ? static::AFTER . 'orderby' : 'orderby';
          +		$entries = [];
          +
          +		foreach ( (array) $orderby as $key => $value ) {
          +			/*
          +			 * As WordPress does, we support "simple" entries, like `[ 'menu_order', 'post_date' ]` and entries in the
          +			 * shape `[ 'menu_order' => 'ASC', 'post_date' => 'DESC' ]`.
          +			 */
          +			$the_orderby = is_numeric( $key ) ? $value : $key;
          +			$the_order   = is_numeric( $key ) ? 'DESC' : $value;
          +
          +			$entries[] = [ $the_orderby, $the_order ];
          +		}
          +
          +		$id = $id ?: 'default';
          +
          +		// Use the `$id` parameter to allow later method calls to replace values set in previous calls.
          +		if ( $id ) {
          +			if ( $override || ! isset( $this->query_vars[ $orderby_key ][ $id ] ) ) {
          +				$this->query_vars[ $orderby_key ][ $id ] = $entries;
          +			}
          +		} else {
          +			$this->query_vars[ $orderby_key ][ $id ] = array_merge( $this->query_vars[ $orderby_key ][ $id ], $entries );
          +		}
          +
          +		if ( ! has_filter( 'posts_orderby', [ $this, 'filter_posts_orderby' ] ) ) {
          +			add_filter( 'posts_orderby', [ $this, 'filter_posts_orderby' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Add custom select fields to the query.
          +	 *
          +	 * @since 4.9.5
          +	 * @since 4.9.14 Added the `$id` and `$override` parameters.
          +	 *
          +	 * @param string $field The field to add to the result.
          +	 * @param null|string $id       Optional ORDER ID to prevent duplicating order-by clauses..
          +	 * @param boolean     $override Whether to override the clause if another by the same ID exists.
          +	 */
          +	public function fields( $field, $id = null, $override = false ) {
          +		if ( $id ) {
          +			if ( $override || ! isset( $this->query_vars['fields'][ $id ] ) ) {
          +				$this->query_vars['fields'][ $id ] = $field;
          +			}
          +		} else {
          +			$this->query_vars['fields'][] = $field;
          +		}
          +
          +		if ( ! has_filter( 'posts_fields', [ $this, 'filter_posts_fields' ] ) ) {
          +			add_filter( 'posts_fields', [ $this, 'filter_posts_fields' ], 10, 2 );
          +		}
          +	}
          +
          +	/**
          +	 * Whether WHERE clauses should be buffered or not.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param bool $buffer_clauses
          +	 */
          +	public function buffer_where_clauses( $buffer_clauses ) {
          +		$this->buffer_where_clauses = (bool) $buffer_clauses;
          +	}
          +
          +	/**
          +	 * Returns the buffered WHERE clause and, optionally, cleans
          +	 * and deactivates buffering.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param bool $get_clean Whether  to clean the buffered WHERE
          +	 *                        clauses and deactivate buffering before
          +	 *                        returning them or not.
          +	 *
          +	 * @return array
          +	 */
          +	public function get_buffered_where_clauses( $get_clean = false ) {
          +		$clauses = $this->buffered_where_clauses;
          +
          +		if ( $get_clean ) {
          +			$this->buffer_where_clauses   = false;
          +			$this->buffered_where_clauses = [];
          +		}
          +
          +		return $clauses;
          +	}
          +
          +	/**
          +	 * Builds the escaped WHERE entry to match a field not in the entry.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $where
          +	 * @param WP_Query $query
          +	 * @param string   $field
          +	 *
          +	 * @return string
          +	 */
          +	protected function where_field_not_in( $where, WP_Query $query, $field ) {
          +		if ( $query !== $this->current_query ) {
          +			return $where;
          +		}
          +
          +		if ( empty( $this->query_vars[ $field ] ) ) {
          +			return $where;
          +		}
          +
          +		$input = $this->query_vars[ $field ];
          +
          +		$stati_interval = $this->create_interval_of_strings( $input );
          +
          +		$where .= $this->and_field_not_in_interval( $field, $stati_interval );
          +
          +		return $where;
          +	}
          +
          +	/**
          +	 * Creates a SQL interval of strings.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string|array $input
          +	 *
          +	 * @return string
          +	 */
          +	public function create_interval_of_strings( $input ) {
          +		$buffer = [];
          +
          +		/** @var wpdb $wpdb */
          +		global $wpdb;
          +
          +		foreach ( $input as $string ) {
          +			$buffer[] = is_array( $string ) ? $string : [ $string ];
          +		}
          +
          +		$buffer = array_unique( call_user_func_array( 'array_merge', $buffer ) );
          +
          +		$safe_strings = [];
          +		foreach ( $buffer as $raw_status ) {
          +			$safe_strings[] = $wpdb->prepare( '%s', $raw_status );
          +		}
          +
          +		return implode( ',', $safe_strings );
          +	}
          +
          +	/**
          +	 * Builds a WHERE clause where field is not in interval.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $field
          +	 * @param string $interval
          +	 *
          +	 * @return string
          +	 */
          +	protected function and_field_not_in_interval( $field, $interval ) {
          +		/** @var wpdb $wpdb */
          +		global $wpdb;
          +
          +		return " AND {$wpdb->posts}.{$field} NOT IN ('{$interval}') ";
          +	}
          +
          +	/**
          +	 * Builds the escaped WHERE entry to match a field in the entry.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $where
          +	 * @param WP_Query $query
          +	 * @param string   $field
          +	 *
          +	 * @return string
          +	 */
          +	protected function where_field_in( $where, WP_Query $query, $field ) {
          +		if ( $query !== $this->current_query ) {
          +			return $where;
          +		}
          +
          +		if ( empty( $this->query_vars[ $field ] ) ) {
          +			return $where;
          +		}
          +
          +		$interval = $this->create_interval_of_strings( $this->query_vars[ $field ] );
          +
          +		$where .= $this->and_field_in_interval( $field, $interval );
          +
          +		return $where;
          +	}
          +
          +	/**
          +	 * Builds a AND WHERE clause.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string $field
          +	 * @param string $interval
          +	 *
          +	 * @return string
          +	 */
          +	protected function and_field_in_interval( $field, $interval ) {
          +		/** @var wpdb $wpdb */
          +		global $wpdb;
          +
          +		return " AND {$wpdb->posts}.{$field} IN ('{$interval}') ";
          +	}
          +
          +	/**
          +	 * Filter the `posts_where` filter to add custom WHERE clauses.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $where
          +	 * @param WP_Query $query
          +	 *
          +	 * @return string
          +	 */
          +	public function filter_posts_where( $where, WP_Query $query ) {
          +		if ( $query !== $this->current_query ) {
          +			return $where;
          +		}
          +
          +		if ( empty( $this->query_vars['where'] ) ) {
          +			return $where;
          +		}
          +
          +		$where .= ' AND ' . implode( "\nAND ", $this->query_vars['where'] ) . ' ';
          +
          +		return $where;
          +	}
          +
          +	/**
          +	 * Filter the `posts_join` filter to add custom JOIN clauses.
          +	 *
          +	 * @since 4.7.19
          +	 *
          +	 * @param string   $join
          +	 * @param WP_Query $query
          +	 *
          +	 * @return string
          +	 */
          +	public function filter_posts_join( $join, WP_Query $query ) {
          +		if ( $query !== $this->current_query ) {
          +			return $join;
          +		}
          +
          +		if ( empty( $this->query_vars['join'] ) ) {
          +			return $join;
          +		}
          +
          +		$join .= "\n" . implode( "\n ", $this->query_vars['join'] ) . ' ';
          +
          +		return $join;
          +	}
          +
          +	/**
          +	 * Filter the `posts_orderby` filter to add custom JOIN clauses.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param string   $orderby The `ORDER BY` clause of the query being filtered.
          +	 * @param WP_Query $query   The query object currently being filtered.
          +	 *
          +	 * @return string The filtered `ORDER BY` clause.
          +	 */
          +	public function filter_posts_orderby( $orderby, WP_Query $query ) {
          +		if ( $query !== $this->current_query ) {
          +			return $orderby;
          +		}
          +
          +		if ( empty( $this->query_vars['orderby'] ) && empty( $this->query_vars[ static::AFTER . 'orderby' ] ) ) {
          +			return $orderby;
          +		}
          +
          +		$frags = [ $orderby ];
          +
          +		/*
          +		 * Entries will be set, from the `orderby` method, to the `[ [ ,  ], [ ,  ] ]`
          +		 * format.
          +		 */
          +		$build_entry = static function ( $entries ) {
          +			$buffer  = [];
          +
          +			foreach ( $entries as list( $orderby, $order ) ) {
          +				$buffer[] = sprintf( '%s %s', $orderby, $order );
          +			}
          +
          +			return implode( ', ', $buffer );
          +		};
          +
          +		if ( ! empty( $this->query_vars['orderby'] ) ) {
          +			$before = implode( ', ', array_map( $build_entry, $this->query_vars['orderby'] ) );
          +			$frags  = [ $before, $orderby ];
          +		}
          +
          +		if ( ! empty( $this->query_vars[ static::AFTER . 'orderby' ] ) ) {
          +			$frags[] = implode( ', ', array_map( $build_entry, $this->query_vars[ static::AFTER . 'orderby' ] ) );
          +		}
          +
          +		return implode( ', ', $frags );
          +	}
          +
          +	/**
          +	 * Filter the `posts_fields` filter to amend fields to be selected.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param array    $fields
          +	 * @param WP_Query $query
          +	 *
          +	 * @return string
          +	 */
          +	public function filter_posts_fields( $fields, WP_Query $query ) {
          +		if ( $query !== $this->current_query ) {
          +			return $fields;
          +		}
          +
          +		if ( empty( $this->query_vars['fields'] ) ) {
          +			return $fields;
          +		}
          +
          +		$fields .= ', ' . implode( ', ', $this->query_vars['fields'] );
          +
          +		return $fields;
          +	}
          +
          +	/**
          +	 * Captures the request SQL as built from the query class.
          +	 *
          +	 * This happens on the `posts_pre_query` filter and
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param null|array $posts A pre-filled array of post results.
          +	 * @param \WP_Query  $query The current query object; this is used by the
          +	 *                          method to intercept only the request generated by
          +	 *                          its attached query.
          +	 *
          +	 * @return array|null An empty array to short-circuit the `get_posts` request; the input
          +	 *                    value, if the query is not the one attached to this filter or the method
          +	 *                    is called not in the context of the `posts_pre_query` filter;
          +	 */
          +	public function capture_request( $posts = null, WP_Query $query = null ) {
          +		if ( ! doing_filter( 'posts_pre_query' ) ) {
          +			// Let's make sure nothing bad happens if this runs outside of its natural context.
          +			return null;
          +		}
          +
          +		if ( $query !== $this->current_query ) {
          +			return $posts;
          +		}
          +
          +		$this->last_request = $query->request;
          +
          +		remove_filter( 'posts_pre_query', [ $this, 'capture_request' ] );
          +
          +		// This will short-circuit the query not running it.
          +		return [];
          +	}
          +
          +	/**
          +	 * Returns the controlled query request SQL.
          +	 *
          +	 * It's not possible to build the SQL for a query outside of a request to `get_posts`
          +	 * so what this class does is fire such a request intercepting it before it actually
          +	 * runs and returning an empty post array.
          +	 * To really run the query it's sufficien to run `get_posts` again on it.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @return string The request SQL, as built from the `WP_Query` class including all the
          +	 *                possible filtering applied by this class and other classes.
          +	 */
          +	public function get_request() {
          +		add_filter( 'posts_pre_query', [ $this, 'capture_request' ], 10, 2 );
          +
          +		$this->current_query->get_posts();
          +
          +		return $this->last_request;
          +	}
          +
          +	/**
          +	 * Returns the fields, join, where and orderby clauses for an id.
          +	 *
          +	 * @since 4.9.14
          +	 *
          +	 * @param string $id The identifier of the group to remove.
          +	 *
          +	 * @return array An associative array of identifiable filters and their values, if any.
          +	 *
          +	 * @see Tribe__Repository__Query_Filters::$identifiable_filters
          +	 */
          +	public function get_filters_by_id( $id ) {
          +		$entries = [];
          +
          +		foreach ( static::$identifiable_filters as $key ) {
          +			if ( empty( $this->query_vars[ $key ][ $id ] ) ) {
          +				continue;
          +			}
          +			$entries[ $key ] = $this->query_vars[ $key ][ $id ];
          +		}
          +
          +		return $entries;
          +	}
          +
          +	/**
          +	 * Removes fields, join, where and orderby clauses for an id.
          +	 *
          +	 * @since 4.9.14
          +	 *
          +	 * @param string $id The identifier of the group to remove.
          +	 */
          +	public function remove_filters_by_id( $id ) {
          +		array_walk(
          +			$this->query_vars,
          +			static function ( array &$filters, $key ) use ( $id ) {
          +				if ( ! in_array( $key, static::$identifiable_filters, true ) ) {
          +					return;
          +				}
          +				unset( $filters[ $id ] );
          +			}
          +		);
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Read_Interface.php b/tribe-common/src/Tribe/Repository/Read_Interface.php
          new file mode 100644
          index 0000000000..57dc581cd2
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Read_Interface.php
          @@ -0,0 +1,173 @@
          +where( 'post__in' , $ids )->get_query()` is
          +	 * to avoid all the overhead of a query that, probably did run already.
          +	 *
          +	 * @since 4.9.5
          +	 *
          +	 * @param array $posts An array of post objects or post IDs the query should return as if fetched.
          +	 *
          +	 * @return WP_Query A query object ready to return, and operate, on the posts.
          +	 */
          +	public function get_query_for_posts( array $posts );
          +}
          diff --git a/tribe-common/src/Tribe/Repository/Setter_Interface.php b/tribe-common/src/Tribe/Repository/Setter_Interface.php
          new file mode 100644
          index 0000000000..c57ca92d0e
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Repository/Setter_Interface.php
          @@ -0,0 +1,46 @@
          +`.
          +	 *
          +	 * @since 4.11.5
          +	 *
          +	 * @var string
          +	 */
          +	protected static $localized_matcher_delimiter = '~';
          +
          +	/**
          +	 * WP_Rewrite Instance
          +	 *
          +	 * @var WP_Rewrite
          +	 */
          +	public $rewrite;
          +
          +	/**
          +	 * Rewrite rules Holder
          +	 *
          +	 * @var array
          +	 */
          +	public $rules = [];
          +
          +	/**
          +	 * Base slugs for rewrite urls
          +	 *
          +	 * @var array
          +	 */
          +	public $bases = [];
          +
          +	/**
          +	 * After creating the Hooks on WordPress we lock the usage of the function.
          +	 *
          +	 * @var boolean
          +	 */
          +	protected $hook_lock = false;
          +
          +	/**
          +	 * An array cache of resolved canonical URLs in the shape `[  =>  ]`.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @var array
          +	 */
          +	protected $canonical_url_cache = null;
          +
          +	/**
          +	 * An array cache of parsed URLs in the shape `[  =>  ]`.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @var array
          +	 */
          +	protected $parse_request_cache = null;
          +
          +	/**
          +	 * And array cache of cleaned URLs.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @var array
          +	 */
          +	protected $clean_url_cache = null;
          +
          +	/**
          +	 * Static Singleton Factory Method
          +	 *
          +	 * @return self
          +	 */
          +	public static function instance() {
          +		if ( ! static::$instance ) {
          +			static::$instance = new static;
          +		}
          +
          +		return static::$instance;
          +	}
          +
          +	/**
          +	 * Tribe__Rewrite constructor.
          +	 *
          +	 * @param WP_Rewrite|null $wp_rewrite
          +	 */
          +	public function __construct( WP_Rewrite $wp_rewrite = null ) {
          +		$this->rewrite = $wp_rewrite;
          +	}
          +
          +	/**
          +	 * When you are going to use any of the functions to create new rewrite rules you need to setup first
          +	 *
          +	 * @param  WP_Rewrite|null $wp_rewrite Pass the WP_Rewrite if you have it
          +	 *
          +	 * @return Tribe__Rewrite       The modified version of the class with the required variables in place
          +	 */
          +	public function setup( $wp_rewrite = null ) {
          +		if ( ! $wp_rewrite instanceof WP_Rewrite ) {
          +			global $wp_rewrite;
          +		}
          +
          +		$this->rewrite = $wp_rewrite;
          +		$this->bases   = $this->get_bases( 'regex' );
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * Generate the Rewrite Rules
          +	 *
          +	 * @param  WP_Rewrite $wp_rewrite WordPress Rewrite that will be modified, pass it by reference (&$wp_rewrite)
          +	 */
          +	public function filter_generate( WP_Rewrite $wp_rewrite ) {
          +		// Gets the rewrite bases and completes any other required setup work
          +		$this->setup( $wp_rewrite );
          +
          +		/**
          +		 * Use this to change the Tribe__Rewrite instance before new rules
          +		 * are committed.
          +		 *
          +		 * Should be used when you want to add more rewrite rules without having to
          +		 * deal with the array merge, noting that rules for The Events Calendar are
          +		 * themselves added via this hook (default priority).
          +		 *
          +		 * @var Tribe__Rewrite $rewrite
          +		 */
          +		do_action( 'tribe_pre_rewrite', $this );
          +	}
          +
          +
          +	/**
          +	 * Do not allow people to Hook methods twice by mistake
          +	 */
          +	public function hooks( $remove = false ) {
          +		if ( false === $this->hook_lock ) {
          +			// Don't allow people do Double the hooks
          +			$this->hook_lock = true;
          +
          +			$this->add_hooks();
          +		} elseif ( true === $remove ) {
          +			$this->remove_hooks();
          +		}
          +	}
          +
          +	/**
          +	 * Converts any percentage placeholders in the array keys back to % symbols.
          +	 *
          +	 * @param  array $rules
          +	 *
          +	 * @return array
          +	 */
          +	public function remove_percent_placeholders( array $rules ) {
          +		foreach ( $rules as $key => $value ) {
          +			$this->replace_array_key( $rules, $key, str_replace( self::PERCENT_PLACEHOLDER, '%', $key ) );
          +		}
          +
          +		return $rules;
          +	}
          +
          +	protected function add_hooks() {
          +		add_filter( 'generate_rewrite_rules', [ $this, 'filter_generate' ] );
          +
          +		// Remove percent Placeholders on all items
          +		add_filter( 'rewrite_rules_array', [ $this, 'remove_percent_placeholders' ], 25 );
          +
          +		add_action( 'shutdown', [ $this, 'dump_cache' ] );
          +	}
          +
          +	protected function remove_hooks() {
          +		remove_filter( 'generate_rewrite_rules', [ $this, 'filter_generate' ] );
          +		remove_filter( 'rewrite_rules_array', [ $this, 'remove_percent_placeholders' ], 25 );
          +
          +		remove_action( 'shutdown', [ $this, 'dump_cache' ] );
          +	}
          +
          +	/**
          +	 * Determines if we have plain permalink.
          +	 *
          +	 * @since 4.11.2
          +	 *
          +	 * @return bool If we use plain permalink or not.
          +	 */
          +	public static function is_plain_permalink() {
          +		return tribe_context()->is( 'plain_permalink' );
          +	}
          +
          +	/**
          +	 * Get the base slugs for the rewrite rules.
          +	 *
          +	 * WARNING: Don't mess with the filters below if you don't know what you are doing
          +	 *
          +	 * @param  string $method Use "regex" to return a Regular Expression with the possible Base Slugs using l10n
          +	 *
          +	 * @return object         Return Base Slugs with l10n variations
          +	 */
          +	public function get_bases( $method = 'regex' ) {
          +		return new stdClass();
          +	}
          +
          +	/**
          +	 * The base method for creating a new Rewrite rule
          +	 *
          +	 * @param array|string $regex The regular expression to catch the URL
          +	 * @param array        $args  The arguments in which the regular expression "alias" to
          +	 *
          +	 * @return Tribe__Events__Rewrite
          +	 */
          +	public function add( $regex, $args = [] ) {
          +		$regex = (array) $regex;
          +
          +		$default = [];
          +		$args    = array_filter( wp_parse_args( $args, $default ) );
          +
          +		$url = add_query_arg( $args, 'index.php' );
          +
          +		// Optional Trailing Slash
          +		$regex[] = '?$';
          +
          +		// Glue the pieces with slashes
          +		$regex = implode( '/', array_filter( $regex ) );
          +
          +		// Add the Bases to the regex
          +		foreach ( $this->bases as $key => $value ) {
          +			$regex = str_replace( [ '{{ ' . $key . ' }}', '{{' . $key . '}}' ], $value, $regex );
          +		}
          +
          +		// Apply the Preg Indexes to the URL
          +		preg_match_all( '/%([0-9])/', $url, $matches );
          +		foreach ( end( $matches ) as $index ) {
          +			$url = str_replace( '%' . $index, $this->rewrite->preg_index( $index ), $url );
          +		}
          +
          +		// Add the rule
          +		$this->rules[ $regex ] = $url;
          +
          +		return $this;
          +	}
          +
          +	/**
          +	 * Returns a sanitized version of $slug that can be used in rewrite rules.
          +	 *
          +	 * This is ideal for those times where we wish to support internationalized
          +	 * URLs (ie, where "venue" in "venue/some-slug" may be rendered in non-ascii
          +	 * characters).
          +	 *
          +	 * In the case of registering new post types, $permastruct_name should
          +	 * generally match the CPT name itself.
          +	 *
          +	 * @param  string $slug
          +	 * @param  string $permastruct_name
          +	 * @param  string $is_regular_exp
          +	 *
          +	 * @return string
          +	 */
          +	public function prepare_slug( $slug, $permastruct_name, $is_regular_exp = true ) {
          +		$needs_handling = false;
          +		$sanitized_slug = sanitize_title( $slug );
          +
          +		// Was UTF8 encoding required for the slug? %a0 type entities are a tell-tale of this
          +		if ( preg_match( '/(%[0-9a-f]{2})+/', $sanitized_slug ) ) {
          +			/**
          +			 * Controls whether special UTF8 URL handling is setup for the set of
          +			 * rules described by $permastruct_name.
          +			 *
          +			 * This only fires if Tribe__Events__Rewrite::prepare_slug() believes
          +			 * handling is required.
          +			 *
          +			 * @var string $permastruct_name
          +			 * @var string $slug
          +			 */
          +			$needs_handling = apply_filters(
          +				'tribe_events_rewrite_utf8_handling', true, $permastruct_name, $slug
          +			);
          +		}
          +
          +		if ( $needs_handling ) {
          +			// User agents encode things the same way but in uppercase
          +			$sanitized_slug = strtoupper( $sanitized_slug );
          +
          +			// UTF8 encoding results in lots of "%" chars in our string which play havoc
          +			// with WP_Rewrite::generate_rewrite_rules(), so we swap them out temporarily
          +			$sanitized_slug = str_replace( '%', Tribe__Rewrite::PERCENT_PLACEHOLDER, $sanitized_slug );
          +		}
          +
          +		$prepared_slug = $is_regular_exp ? preg_quote( $sanitized_slug ) : $sanitized_slug;
          +
          +		/**
          +		 * Provides an opportunity to modify the sanitized slug which will be used
          +		 * in rewrite rules relating to $permastruct_name.
          +		 *
          +		 * @var string $prepared_slug
          +		 * @var string $permastruct_name
          +		 * @var string $original_slug
          +		 */
          +		return apply_filters( 'tribe_rewrite_prepared_slug', $prepared_slug, $permastruct_name, $slug );
          +	}
          +
          +	/**
          +	 * A way to replace an Array key without destroying the array ordering
          +	 *
          +	 * @since  4.0.6
          +	 *
          +	 * @param  array  &$array  The Rules Array should be used here
          +	 * @param  string $search  Search for this Key
          +	 * @param  string $replace Replace with this key]
          +	 *
          +	 * @return bool            Did we replace anything?
          +	 */
          +	protected function replace_array_key( &$array, $search, $replace ) {
          +		$keys  = array_keys( $array );
          +		$index = array_search( $search, $keys );
          +
          +		if ( false !== $index ) {
          +			$keys[ $index ] = $replace;
          +			$array          = array_combine( $keys, $array );
          +
          +			return true;
          +		}
          +
          +		return false;
          +	}
          +
          +	/**
          +	 * Returns the canonical URLs associated with a ugly link.
          +	 *
          +	 * This method will handle "our" URLs to go from their ugly form, filled with query vars, to the "pretty" one, if
          +	 * possible.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @param string $url The URL to try and translate into its canonical form.
          +	 * @param bool   $force Whether to try and use the cache or force a new canonical URL conversion.
          +	 *
          +	 * @return string The canonical URL, or the input URL if it could not be resolved to a canonical one.
          +	 */
          +	public function get_canonical_url( $url, $force = false ) {
          +		if ( get_class( $this ) === Tribe__Rewrite::class ) {
          +			throw new BadMethodCallException(
          +				'Method get_canonical_url should only be called on extending classes.'
          +			);
          +		}
          +
          +		if ( null === $this->rewrite ) {
          +			// We re-do this check here as the object might have been initialized before the global rewrite was set.
          +			$this->setup();
          +		}
          +
          +		/**
          +		 * Filters the canonical URL for an input URL before any kind of logic runs.
          +		 *
          +		 * @since 4.9.11
          +		 *
          +		 * @param string|null    $canonical_url The canonical URL, defaults to `null`; returning a non `null` value will
          +		 *                                      make the logic bail and return the value.
          +		 * @param string         $url           The input URL to resolve to a canonical one.
          +		 * @param Tribe__Rewrite $this          This rewrite object.
          +		 */
          +		$canonical_url = apply_filters( 'tribe_rewrite_pre_canonical_url', null, $url );
          +		if ( null !== $canonical_url ) {
          +			return $canonical_url;
          +		}
          +
          +		$home_url = home_url();
          +
          +		// It's not a path we, or WP, could possibly handle.
          +		$has_http_scheme = (bool) parse_url( $url, PHP_URL_SCHEME );
          +		if (
          +			$home_url === $url
          +			|| ( $has_http_scheme && false === strpos( $url, $home_url ) )
          +		) {
          +			return $url;
          +		}
          +
          +		$canonical_url = $url;
          +		// To avoid issues with missing `path` component let's always add a trailing '/'.
          +		if ( false !== strpos( $url, '?' ) ) {
          +			$canonical_url = preg_replace( '~(\\/)*\\?~', '/?', $canonical_url );
          +		} elseif ( false !== strpos( $url, '#' ) ) {
          +			$canonical_url = preg_replace( '~(\\/)*#~', '/#', $canonical_url );
          +		}
          +
          +		// Canonical URLs are supposed to contain the home URL.
          +		if ( false === strpos( $canonical_url, $home_url ) ) {
          +			$canonical_url = home_url( $canonical_url );
          +		}
          +
          +		if ( empty( $canonical_url ) ) {
          +			return $home_url;
          +		}
          +
          +		// Passthru vars are additional salts for the cache that would render it useless: parse them here.
          +		$query = (string) parse_url( $url, PHP_URL_QUERY );
          +		wp_parse_str( $query, $query_vars );
          +		// Non-scalar value query vars should not be handled, but they should survive the resolution and not be cached.
          +		$scalar_query_vars = array_filter( $query_vars, 'is_scalar' );
          +		$passthru_vars     = array_diff_key( $query_vars, $scalar_query_vars );
          +		// Remove the passthru query vars from the URL to match the correct cache.
          +		$url = remove_query_arg( array_keys( $passthru_vars ), $url );
          +		// Normalize the URL to make sure there's a trailing slash at the end of the path, before the query or fragment.
          +		$url = preg_replace( '~(?warmup_cache(
          +				'canonical_url',
          +				WEEK_IN_SECONDS,
          +				Listener::TRIGGER_GENERATE_REWRITE_RULES
          +			);
          +			if ( isset( $this->canonical_url_cache[ $url ] ) ) {
          +				// Re-apply passthru vars now, if any.
          +				return add_query_arg( $passthru_vars, $this->canonical_url_cache[ $url ] );
          +			}
          +		}
          +
          +		$query_vars = array_intersect_key( $query_vars, $scalar_query_vars );
          +
          +		if ( isset( $query_vars['paged'] ) && 1 === (int) $query_vars['paged'] ) {
          +			// Remove the `paged` query var if it's 1.
          +			unset( $query_vars['paged'] );
          +		}
          +
          +		ksort( $query_vars );
          +
          +		$our_rules          = $this->get_handled_rewrite_rules();
          +		$handled_query_vars = $this->get_rules_query_vars( $our_rules );
          +		$handled_post_types = $this->get_post_types();
          +
          +		if (
          +			// The rules we handle should not be empty.
          +			empty( $our_rules )
          +			|| ! (
          +				// Supported post types should be either keys or values, of the `post_type` argument, in the query vars.
          +				count( array_intersect_key( array_flip( $handled_post_types ), $query_vars ) )
          +				|| in_array( Arr::get( $query_vars, 'post_type', 'post' ), $handled_post_types, true )
          +			)
          +		) {
          +			$wp_canonical = redirect_canonical( $canonical_url, false );
          +			if ( empty( $wp_canonical ) ) {
          +				$wp_canonical = $canonical_url;
          +			}
          +
          +			$this->canonical_url_cache[ $url ] = $wp_canonical;
          +
          +			return $wp_canonical;
          +		}
          +
          +		$bases = (array) $this->get_bases();
          +		ksort( $bases );
          +
          +		$localized_matchers = $this->get_localized_matchers();
          +		$dynamic_matchers   = $this->get_dynamic_matchers( $query_vars );
          +
          +		// Try to match only on the query vars we're actually handling.
          +		$matched_vars   = array_intersect_key( $query_vars, array_combine( $handled_query_vars, $handled_query_vars ) );
          +		$unmatched_vars = array_diff_key( $query_vars, array_combine( $handled_query_vars, $handled_query_vars ) );
          +
          +		if ( empty( $matched_vars ) ) {
          +			// The URL does contain query vars, but none we handle.
          +			$wp_canonical = trailingslashit( redirect_canonical( $url, false ) );
          +			$this->canonical_url_cache[ $url ] = $wp_canonical;
          +
          +			return $wp_canonical;
          +		}
          +
          +		$found = false;
          +
          +		foreach ( $our_rules as $link_template => $index_path ) {
          +			wp_parse_str( (string) parse_url( $index_path, PHP_URL_QUERY ), $link_vars );
          +			ksort( $link_vars );
          +
          +			if ( array_keys( $link_vars ) !== array_keys( $matched_vars ) ) {
          +				continue;
          +			}
          +
          +			if ( ! (
          +				Arr::get( $matched_vars, 'post_type', '' ) === Arr::get( $link_vars, 'post_type', '' )
          +				&& Arr::get( $matched_vars, 'eventDisplay', '' ) === Arr::get( $link_vars, 'eventDisplay', '' )
          +			) ) {
          +				continue;
          +			}
          +
          +			$replace = array_map( function ( $localized_matcher ) use ( $matched_vars ) {
          +				if ( ! is_array( $localized_matcher ) ) {
          +					// For the dates.
          +					return isset( $matched_vars[ $localized_matcher ] )
          +						? $matched_vars[ $localized_matcher ]
          +						: '';
          +				}
          +
          +				$query_var  = $localized_matcher['query_var'];
          +				$query_vars = [ $query_var ];
          +
          +				if ( $query_var === 'name' ) {
          +					$query_vars = array_merge( $query_vars, $this->get_post_types() );
          +				}
          +
          +				if ( ! array_intersect( array_keys( $matched_vars ), $query_vars ) ) {
          +					return '';
          +				}
          +
          +				if ( isset( $localized_matcher['localized_slug'] ) ) {
          +					// If available, then return the localized slug instead of inferring it as we do below.
          +					return $localized_matcher['localized_slug'];
          +				}
          +
          +				/*
          +				 * We use `end` as, by default, the localized version of the slug in the current language will be at the
          +				 * end of the array.
          +				 */
          +				return end( $localized_matcher['localized_slugs'] );
          +			}, $localized_matchers );
          +
          +			// Include dynamic matchers now.
          +			$replace = array_merge( $dynamic_matchers, $replace );
          +
          +			/*
          +			 * Prune from the replacements the empty values. This will resolve conflicts (e.g. single and archive w/
          +			 * same slug) as no two can be true at the same time.
          +			 * Remove the `` prefix added to localized matchers, if any.
          +			 */
          +			$replace = array_filter( $replace );
          +			$replace = array_combine(
          +				array_map( static function ( $key ) {
          +					return preg_replace(
          +						'/' . preg_quote( Tribe__Rewrite::$localized_matcher_delimiter ) . '\\w*$/',
          +						'',
          +						$key
          +					);
          +				}, array_keys( $replace ) ),
          +				$replace
          +			);
          +
          +			// Use case-insensitive replace to make sure to work with some decoding using uppercase escaped chars.
          +			$replaced = str_ireplace( array_keys( $replace ), $replace, $link_template );
          +
          +			// Remove trailing chars.
          +			$path     = rtrim( $replaced, '?$' );
          +			$resolved = trailingslashit( home_url( $path ) );
          +			$found = true;
          +
          +			break;
          +		}
          +
          +		if ( empty( $resolved ) ) {
          +			$wp_canonical = redirect_canonical( $canonical_url, false );
          +			$resolved     = empty( $wp_canonical ) ? $canonical_url : $wp_canonical;
          +		}
          +
          +		if ( $canonical_url !== $resolved ) {
          +			// Be sure to add a trailing slash to the URL; before `?` or `#`.
          +			$resolved = preg_replace( '/(?canonical_url_cache[ $url ] = $resolved;
          +		}
          +
          +		// Re-apply passthru vars now, if any. After the caching to allow salting the cache key too much.
          +		$resolved = add_query_arg( $passthru_vars, $resolved );
          +
          +		return $resolved;
          +	}
          +
          +	/**
          +	 * Returns an array of rewrite rules handled by the implementation.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @return array An array of rewrite rules handled by the implementation in the shape `[  =>  ]`.
          +	 */
          +	protected function get_handled_rewrite_rules() {
          +		static $cache_var_name = __METHOD__;
          +
          +		$our_rules = tribe_get_var( $cache_var_name, null );
          +
          +		// We need to make sure we are have WP_Rewrite setup
          +		if ( ! $this->rewrite ) {
          +			$this->setup();
          +		}
          +
          +		$all_rules     = isset( $this->rewrite->rules ) ? (array) $this->rewrite->rules : [];
          +
          +		if ( null === $our_rules ) {
          +			// While this is specific to The Events Calendar we're handling a small enough post type base to keep it here.
          +			$pattern = '/post_type=tribe_(events|venue|organizer)/';
          +			// Reverse the rules to try and match the most complex first.
          +			$our_rules = array_filter( $all_rules,
          +				static function ( $rule_query_string ) use ( $pattern ) {
          +					return preg_match( $pattern, $rule_query_string );
          +				}
          +			);
          +
          +			tribe_set_var( $cache_var_name, $our_rules );
          +		}
          +
          +		/**
          +		 * Filters the list of rewrite rules handled by our code to add or remove some as required.
          +		 *
          +		 * @since  4.9.18
          +		 *
          +		 * @param array $our_rules An array of rewrite rules handled by our code, in the shape
          +		 *                         `[  =>  ]`.
          +		 *                         E.g. `[ '(?:events)/(?:list)/?$' => 'index.php?post_type=tribe_events&eventDisplay=list' ]`.
          +		 * @param array All the current rewrite rules, before any filtering is applied; these have the
          +		 *                             same ` rewrite >` format as the previous argument, which is the
          +		 *                             format used by WordPress rewrite rules.
          +		 */
          +		$our_rules = apply_filters( 'tribe_rewrite_handled_rewrite_rules', $our_rules, $all_rules );
          +
          +		return $our_rules;
          +	}
          +
          +	/**
          +	 * Returns a map relating localized regex matchers to query vars.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @return array A map of localized regex matchers in the shape `[  =>  ]`.
          +	 */
          +	protected function get_localized_matchers() {
          +		static $cache_var_name = __METHOD__;
          +
          +		$bases         = (array) $this->get_bases();
          +
          +		$query_var_map = $this->get_matcher_to_query_var_map();
          +
          +		$localized_matchers = tribe_get_var( $cache_var_name, [] );
          +
          +		foreach ( $bases as $base => $localized_matcher ) {
          +			// Use the base too to allow possible conflicts if the slugs are the same for single and archive.
          +			$localized_matcher_key = $localized_matcher . static::$localized_matcher_delimiter . $base;
          +
          +			if ( isset( $localized_matchers[ $localized_matcher_key ] ) ) {
          +				continue;
          +			}
          +
          +			if ( isset( $query_var_map[ $base ] ) ) {
          +				$localized_matchers[ $localized_matcher_key ] = [
          +					'base'            => $base,
          +					'query_var'       => $query_var_map[ $base ],
          +					'en_slug'         => $base,
          +					'localized_slugs' => [ $base ],
          +				];
          +				// If we have the localized slug version then let's parse it.
          +				preg_match( '/^\\(\\?:(?[^\\)]+)\\)$/u', $localized_matcher, $buffer );
          +				if ( ! empty( $buffer['slugs'] ) ) {
          +					$slugs = explode( '|', $buffer['slugs'] );
          +
          +					$localized_matchers[ $localized_matcher_key ]['localized_slugs'] = array_map(
          +						static function ( $localized_slug ) {
          +							return str_replace( '\-', '-', $localized_slug );
          +						},
          +						$slugs
          +					);
          +
          +					// The English version is the first.
          +					$localized_matchers[ $localized_matcher_key ]['en_slug'] = reset( $slugs );
          +				}
          +			}
          +		}
          +
          +		tribe_set_var( $cache_var_name, $localized_matchers );
          +
          +		return $localized_matchers;
          +	}
          +
          +	/**
          +	 * Returns a map relating localized matcher slugs to the corresponding query var.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @return array A map relating localized matcher slugs to the corresponding query var.
          +	 */
          +	protected function get_matcher_to_query_var_map() {
          +		throw new BadMethodCallException(
          +			'This method should not be called on the base class (' . __CLASS__ . '); only on extending classes.'
          +		);
          +	}
          +
          +	/**
          +	 * Return a list of the query vars handled in the input rewrite rules.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @param array $rules A set of rewrite rules in the shape `[  =>  ]`.
          +	 *
          +	 * @return array A list of all the query vars handled in the rules.
          +	 */
          +	protected function get_rules_query_vars( array $rules ) {
          +		static $cache_var_name = __METHOD__;
          +
          +		$cached_rules = tribe_get_var( $cache_var_name, [] );
          +		$cache_key = md5( json_encode( $rules ) );
          +
          +		if ( ! isset( $cached_rules[ $cache_key ] ) ) {
          +			$cached_rules[ $cache_key ] = array_unique(
          +				array_filter(
          +					array_merge(
          +						[],
          +						...array_values(
          +							array_map(
          +								static function ( $rule_string ) {
          +									wp_parse_str( parse_url( $rule_string, PHP_URL_QUERY ), $vars );
          +									return array_keys( $vars );
          +								},
          +								$rules
          +							)
          +						)
          +					)
          +				)
          +			);
          +
          +			tribe_set_var( $cache_var_name, $cached_rules );
          +		}
          +
          +		return $cached_rules[ $cache_key ];
          +	}
          +
          +	/**
          +	 * Sets up the dynamic matchers based on the link query vars.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @param array $query_vars An map of query vars and their values.
          +	 *
          +	 * @return array A map of dynamic matchers in the shape `[  =>  ]`.
          +	 */
          +	protected function get_dynamic_matchers( array $query_vars ) {
          +		$bases            = (array) $this->get_bases();
          +		$dynamic_matchers = [];
          +
          +		/*
          +		 * In some instance we use the `page` (w/o `d`) to paginate a dynamic archive.
          +		 * Let's support that too.
          +		 * It's important to add `page` after `paged` to try and match the longest (`paged`) first.
          +		 */
          +		foreach ( [ 'paged', 'page' ] as $page_var ) {
          +			if ( isset( $query_vars[ $page_var ] ) ) {
          +				$page_regex = $bases['page'];
          +				preg_match( '/^\(\?:(?[^\\)]+)\)/', $page_regex, $matches );
          +				if ( isset( $matches['slugs'] ) ) {
          +					$slugs = explode( '|', $matches['slugs'] );
          +					// The localized version is the last.
          +					$localized_slug = end( $slugs );
          +					// We use two different regular expressions to read pages, let's add both.
          +					$dynamic_matchers["{$page_regex}/(\d+)"]       = "{$localized_slug}/{$query_vars[$page_var]}";
          +					$dynamic_matchers["{$page_regex}/([0-9]{1,})"] = "{$localized_slug}/{$query_vars[$page_var]}";
          +				}
          +			}
          +		}
          +
          +		if ( isset( $query_vars['tag'] ) ) {
          +			$tag      = $query_vars['tag'];
          +			$tag_term = get_term_by( 'slug', $tag, 'post_tag' );
          +
          +			if ( $tag_term instanceof WP_Term ) {
          +				// Let's actually add the matcher only if the tag exists.
          +				$tag_regex = $bases['tag'];
          +				preg_match( '/^\(\?:(?[^\\)]+)\)/', $tag_regex, $matches );
          +				if ( isset( $matches['slugs'] ) ) {
          +					$slugs = explode( '|', $matches['slugs'] );
          +					// The localized version is the last.
          +					$localized_slug                           = end( $slugs );
          +					$dynamic_matchers["{$tag_regex}/([^/]+)"] = "{$localized_slug}/{$tag}";
          +				}
          +			}
          +		}
          +
          +		if ( isset( $query_vars['feed'] ) ) {
          +			$feed_regex                      = 'feed/(feed|rdf|rss|rss2|atom)';
          +			$dynamic_matchers[ $feed_regex ] = "feed/{$query_vars['feed']}";
          +		}
          +
          +		return $dynamic_matchers;
          +	}
          +
          +	/**
          +	 * Returns a list of post types supported by the implementation.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @return array An array of post types supported and handled by the rewrite implementation.
          +	 */
          +	protected function get_post_types() {
          +		throw new BadMethodCallException( 'Method get_post_types should be implemented by extending classes.' );
          +	}
          +
          +	/**
          +	 * Parses a URL to produce an array of query variables.
          +	 *
          +	 * Most of this functionality was copied from `WP::parse_request()` method
          +	 * with some changes to avoid conflicts and removing non-required behaviors.
          +	 *
          +	 * @since  4.9.11
          +	 *
          +	 * @param string $url              The URLto parse.
          +	 * @param array  $extra_query_vars An associative array of extra query vars to use for the parsing. These vars will
          +	 *                                 be read before the WordPress defined ones overriding them.
          +	 * @param bool   $force Whether to try and use the cache or force a new canonical URL conversion.
          +	 *
          +	 * @return array An array of query vars, as parsed from the input URL.
          +	 */
          +	public function parse_request( $url, array $extra_query_vars = [], $force = false ) {
          +		if ( null === $this->rewrite ) {
          +			// We re-do this check here as the object might have been initialized before the global rewrite was set.
          +			$this->setup();
          +		}
          +
          +		/**
          +		 * Allows short-circuiting the URL parsing.
          +		 *
          +		 * This filter will run before any logic runs, its result will not be cached and this filter will be called on
          +		 * each call to this method.
          +		 * Returning a non `null` value here will short-circuit this logic.
          +		 *
          +		 * @since 4.9.11
          +		 *
          +		 * @param array  $query_vars       The parsed query vars array.
          +		 * @param array  $extra_query_vars An associative array of extra query vars that will be processed before the
          +		 *                                 WordPress defined ones.
          +		 * @param string $url              The URL to parse.
          +		 */
          +		$parsed = apply_filters( 'tribe_rewrite_pre_parse_query_vars', null, $extra_query_vars, $url );
          +		if ( null !== $parsed ) {
          +			return $parsed;
          +		}
          +
          +		if ( ! $force ) {
          +			$this->warmup_cache(
          +				'parse_request',
          +				WEEK_IN_SECONDS,
          +				Listener::TRIGGER_GENERATE_REWRITE_RULES
          +			);
          +			if ( isset( $this->parse_request_cache[ $url ] ) ) {
          +				return $this->parse_request_cache[ $url ];
          +			}
          +		}
          +
          +		$query_vars           = [];
          +		$post_type_query_vars = [];
          +		$perma_query_vars     = [];
          +		$url_components = parse_url($url);
          +		$url_path = Arr::get( $url_components, 'path', '/' );
          +		$site_path = parse_url( home_url(), PHP_URL_PATH );
          +		if ( ! empty( $site_path ) && '/' !== $site_path ) {
          +			// The current site is in a sub-directory: the site path should be dropped from the request path.
          +			$url_path = str_replace( $site_path, '', $url_path );
          +		}
          +		$url_query = Arr::get( $url_components, 'query', '' );
          +		parse_str( $url_query, $url_query_vars );
          +		// Look for matches, removing leading `/` char.
          +		$request_match         = ltrim( $url_path, '/' );
          +		$decoded_request_match = urldecode( $request_match );
          +
          +		// Fetch the rewrite rules.
          +		$rewrite_rules = $this->rewrite->wp_rewrite_rules();
          +		$matched_rule = false;
          +
          +		if ( ! empty( $rewrite_rules ) ) {
          +			foreach ( (array) $rewrite_rules as $match => $query ) {
          +				$matches_regex = preg_match( "#^$match#", $request_match, $matches )
          +				                 || preg_match( "#^$match#", $decoded_request_match, $matches );
          +
          +				if ( ! $matches_regex ) {
          +					continue;
          +				}
          +
          +				if (
          +					$this->rewrite->use_verbose_page_rules
          +					&& preg_match( '/pagename=\$matches\[([0-9]+)\]/', $query, $varmatch )
          +				) {
          +					// This is a verbose page match, let's check to be sure about it.
          +					$page = get_page_by_path( $matches[ $varmatch[1] ] );
          +					if ( ! $page ) {
          +						continue;
          +					}
          +					$post_status_obj = get_post_status_object( $page->post_status );
          +					if (
          +						! $post_status_obj->public
          +						&& ! $post_status_obj->protected
          +						&& ! $post_status_obj->private
          +						&& $post_status_obj->exclude_from_search
          +					) {
          +						continue;
          +					}
          +				}
          +
          +				// Got a match.
          +				$matched_rule = $match;
          +				break;
          +			}
          +
          +			if ( false !== $matched_rule ) {
          +				// Trim the query of everything up to the '?'.
          +				$query = preg_replace( '!^.+\?!', '', $query );
          +				// Substitute the substring matches into the query.
          +				$query = addslashes( WP_MatchesMapRegex::apply( $query, $matches ) );
          +				// Parse the query.
          +				parse_str( $query, $perma_query_vars );
          +			}
          +		}
          +
          +		foreach ( get_post_types( [], 'objects' ) as $post_type => $t ) {
          +			if (
          +				is_post_type_viewable( $t )
          +				&& $t->query_var
          +			) {
          +				$post_type_query_vars[ $t->query_var ] = $post_type;
          +			}
          +		}
          +
          +		global $wp;
          +
          +		/*
          +		 * WordPress would apply this filter in the `parse_request` method to allow the registration of additional query
          +		 * vars. They might not have been registered at this point so we do this again making sure to avoid duplicates.
          +		 */
          +		$public_query_vars = array_unique( apply_filters( 'query_vars', $wp->public_query_vars ) );
          +
          +		foreach ( $public_query_vars as $wpvar ) {
          +			if ( isset( $extra_query_vars[ $wpvar ] ) ) {
          +				$query_vars[ $wpvar ] = $extra_query_vars[ $wpvar ];
          +			} elseif ( isset( $perma_query_vars[ $wpvar ] ) ) {
          +				$query_vars[ $wpvar ] = $perma_query_vars[ $wpvar ];
          +			}
          +			if ( ! empty( $query_vars[ $wpvar ] ) ) {
          +				if ( ! is_array( $query_vars[ $wpvar ] ) ) {
          +					$query_vars[ $wpvar ] = (string) $query_vars[ $wpvar ];
          +				} else {
          +					foreach ( $query_vars[ $wpvar ] as $vkey => $v ) {
          +						if ( is_scalar( $v ) ) {
          +							$query_vars[ $wpvar ][ $vkey ] = (string) $v;
          +						}
          +					}
          +				}
          +				if ( isset( $post_type_query_vars[ $wpvar ] ) ) {
          +					$query_vars['post_type'] = $post_type_query_vars[ $wpvar ];
          +					$query_vars['name']      = $query_vars[ $wpvar ];
          +				}
          +			}
          +		}
          +
          +		// Convert urldecoded spaces back into `+`.
          +		foreach ( get_taxonomies( [], 'objects' ) as $taxonomy => $t ) {
          +			if ( $t->query_var && isset( $query_vars[ $t->query_var ] ) ) {
          +				$query_vars[ $t->query_var ] = str_replace( ' ', '+', $query_vars[ $t->query_var ] );
          +			}
          +		}
          +
          +		// Don't allow non-publicly queryable taxonomies to be queried from the front end.
          +		if ( ! is_admin() ) {
          +			foreach ( get_taxonomies( [ 'publicly_queryable' => false ], 'objects' ) as $taxonomy => $t ) {
          +				/*
          +				 * Disallow when set to the 'taxonomy' query var.
          +				 * Non-publicly queryable taxonomies cannot register custom query vars. See register_taxonomy().
          +				 */
          +				if ( isset( $query_vars['taxonomy'] ) && $taxonomy === $query_vars['taxonomy'] ) {
          +					unset( $query_vars['taxonomy'], $query_vars['term'] );
          +				}
          +			}
          +		}
          +
          +		// Limit publicly queried post_types to those that are publicly_queryable
          +		if ( isset( $query_vars['post_type'] ) ) {
          +			$queryable_post_types = get_post_types( [ 'publicly_queryable' => true ] );
          +			if ( ! is_array( $query_vars['post_type'] ) ) {
          +				if ( ! in_array( $query_vars['post_type'], $queryable_post_types ) ) {
          +					unset( $query_vars['post_type'] );
          +				}
          +			} else {
          +				$query_vars['post_type'] = array_intersect( $query_vars['post_type'], $queryable_post_types );
          +			}
          +		}
          +
          +		// Resolve conflicts between posts with numeric slugs and date archive queries.
          +		$query_vars = wp_resolve_numeric_slug_conflicts( $query_vars );
          +
          +		foreach ( (array) $wp->private_query_vars as $var ) {
          +			if ( isset( $extra_query_vars[ $var ] ) ) {
          +				$query_vars[ $var ] = $extra_query_vars[ $var ];
          +			}
          +		}
          +
          +		/*
          +		 * If we have both the `name` query var and the post type one, then let's remove the `name` one.
          +		 */
          +		if ( array_intersect( array_keys( $query_vars ), $this->get_post_types() ) ) {
          +			unset( $query_vars['name'] );
          +		}
          +
          +		if ( ! empty( $url_query_vars ) ) {
          +			// If the URL did have query vars keep them if not overridden by our resolution.
          +			$query_vars = array_merge( $url_query_vars, $query_vars );
          +		}
          +
          +		// Prune the query vars to drop the empty `page` or `paged` ones.
          +		$query_vars = array_filter( $query_vars, static function ( $value, $key ) {
          +			return ! in_array( $key, [ 'paged', 'page' ] ) || (int) $value !== 0;
          +		}, ARRAY_FILTER_USE_BOTH );
          +
          +		/**
          +		 * Filters the array of parsed query variables after the class logic has been applied to it.
          +		 *
          +		 * Due to the costly nature of this operation the results will be cached. The logic, and this filter, will
          +		 * not run a second time for the same URL in the context of the same request.
          +		 *
          +		 * @since 4.9.11
          +		 *
          +		 * @param array  $query_vars       The parsed query vars array.
          +		 * @param array  $extra_query_vars An associative array of extra query vars that will be processed before the
          +		 *                                 WordPress defined ones.
          +		 * @param string $url              The URL to parse.
          +		 */
          +		$query_vars = apply_filters( 'tribe_rewrite_parse_query_vars', $query_vars, $extra_query_vars, $url );
          +
          +		if ( $matched_rule ) {
          +			// Since we're caching let's not cache unmatchec URLs to allow for their later, valid matching.
          +			$this->parse_request_cache[ $url ] = $query_vars;
          +		}
          +
          +		return $query_vars;
          +	}
          +
          +	/**
          +	 * Returns the "clean" version of a URL.
          +	 *
          +	 * The URL is first parsed then resolved to a canonical URL.
          +	 * As an example the URL `/events/list/?post_type=tribe_events` is "dirty" in that the `post_type` query variable
          +	 * is redundant. The clean version of the URL is `/events/list/`, where the query variable is removed.
          +	 *
          +	 * @since 4.9.11
          +	 *
          +	 * @param string $url The URL to clean.
          +	 * @param bool   $force Whether to try and use the cache or force a new URL cleaning run.
          +	 *
          +	 * @return string The cleaned URL, or the input URL if it could not be resolved to a clean one.
          +	 */
          +	public function get_clean_url( $url, $force = false ) {
          +		if ( ! $force ) {
          +			$this->warmup_cache(
          +				'clean_url',
          +				WEEK_IN_SECONDS,
          +				Listener::TRIGGER_GENERATE_REWRITE_RULES
          +			);
          +			if ( isset( $this->clean_url_cache[ $url ] ) ) {
          +				return $this->clean_url_cache[ $url ];
          +			}
          +		}
          +
          +		$parsed_vars = $this->parse_request( $url );
          +
          +		if ( empty( $parsed_vars ) ) {
          +			return home_url();
          +		}
          +
          +		$clean = $this->get_canonical_url( add_query_arg( $parsed_vars, home_url( '/' ) ), $force );
          +
          +		$this->clean_url_cache[ $url ] = $clean;
          +
          +		return $clean;
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Body_Classes.php b/tribe-common/src/Tribe/Service_Providers/Body_Classes.php
          new file mode 100644
          index 0000000000..e47b477c7f
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Body_Classes.php
          @@ -0,0 +1,86 @@
          +hooks();
          +	}
          +
          +	/**
          +	 * Set up hooks for classes.
          +	 *
          +	 * @since 4.12.6
          +	 */
          +	private function hooks() {
          +		add_filter( 'body_class', [ $this, 'add_body_classes' ] );
          +		add_filter( 'admin_body_class', [ $this, 'add_admin_body_classes' ] );
          +
          +		/**
          +		 * Allows plugins to hook into the hooks action to register their own hooks.
          +		 *
          +		 * @since 4.12.6
          +		 *
          +		 * @param Tribe\Service_Providers\Dialog $dialog
          +		 */
          +		do_action( 'tribe_body_classes_hooks', $this );
          +	}
          +
          +	/**
          +	 * Hook in and add FE body classes.
          +	 *
          +	 * @since 4.12.6
          +	 *
          +	 * @param array $classes An array of body class names.
          +	 * @return array The modified array of body class names.
          +	 */
          +	public function add_body_classes( $classes = [] ) {
          +		/** @var Body_Class_Object $body_classes */
          +		$body_classes = tribe( Body_Class_Object::class );
          +
          +		return $body_classes->add_body_classes( $classes );
          +	}
          +
          +	/**
          +	 * Hook in and add admin body classes.
          +	 *
          +	 * @since 4.12.6
          +	 *
          +	 * @param array $classes An array of body class names.
          +	 * @return array The modified array of body class names.
          +	 */
          +	public function add_admin_body_classes( $classes = [] ) {
          +		/** @var Body_Class_Object $body_classes */
          +		$body_classes = tribe( Body_Class_Object::class );
          +
          +		return $body_classes->add_admin_body_classes( $classes );
          +	}
          +
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Crons.php b/tribe-common/src/Tribe/Service_Providers/Crons.php
          new file mode 100644
          index 0000000000..7a5daf4e17
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Crons.php
          @@ -0,0 +1,37 @@
          + 0 ) {
          +			$panels = array_merge( $panels, $tribe_panels );
          +		}
          +
          +		return $panels;
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Dialog.php b/tribe-common/src/Tribe/Service_Providers/Dialog.php
          new file mode 100644
          index 0000000000..b5e5acc5e1
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Dialog.php
          @@ -0,0 +1,110 @@
          +hooks();
          +	}
          +
          +	/**
          +	 * Set up hooks for classes.
          +	 *
          +	 * @since 4.10.0
          +	 */
          +	private function hooks() {
          +		add_action( 'tribe_common_loaded', [ $this, 'register_dialog_assets' ] );
          +		add_filter( 'tribe_template_public_namespace', [ $this, 'template_public_namespace' ], 10, 2 );
          +
          +		/**
          +		 * Allows plugins to hook into the hooks action to register their own hooks
          +		 *
          +		 * @since 4.10.0
          +		 *
          +		 * @param Tribe\Service_Providers\Dialog $dialog
          +		 */
          +		do_action( 'tribe_dialog_hooks', $this );
          +	}
          +
          +	/**
          +	  * {@inheritdoc}
          +	 *
          +	 * @since  4.10.0
          +	 */
          +	public function template_public_namespace( $namespace, $obj ) {
          +		if ( ! empty( $obj->template_namespace ) && 'dialog' === $obj->template_namespace ) {
          +			array_push( $namespace, 'dialog' );
          +		}
          +
          +		return $namespace;
          +	}
          +
          +	/**
          +	 * Register assets associated with dialog
          +	 *
          +	 * @since 4.10.0
          +	 */
          +	public function register_dialog_assets() {
          +		$main = \Tribe__Main::instance();
          +
          +		tribe_asset(
          +			$main,
          +			'tribe-dialog',
          +			'dialog.css',
          +			[],
          +			[],
          +			[ 'groups' => 'tribe-dialog' ]
          +		);
          +
          +		tribe_asset(
          +			$main,
          +			'mt-a11y-dialog',
          +			'node_modules/mt-a11y-dialog/a11y-dialog.js',
          +			[ 'underscore', 'tribe-common' ],
          +			[],
          +			[ 'groups' => 'tribe-dialog' ]
          +		);
          +
          +		tribe_asset(
          +			$main,
          +			'tribe-dialog-js',
          +			'dialog.js',
          +			[ 'mt-a11y-dialog' ],
          +			[],
          +			[ 'groups' => 'tribe-dialog' ]
          +		);
          +
          +		/**
          +		 * Allows plugins to hook into the assets action to register their own assets
          +		 *
          +		 * @since 4.10.0
          +		 *
          +		 * @param Tribe\Service_Providers\Dialog $dialog
          +		 */
          +		do_action( 'tribe_dialog_assets_registered', $this );
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/PUE.php b/tribe-common/src/Tribe/Service_Providers/PUE.php
          new file mode 100644
          index 0000000000..31918120d2
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/PUE.php
          @@ -0,0 +1,50 @@
          +container->singleton( Update_Prevention::class, Update_Prevention::class );
          +
          +		// Setup all of WP hooks associated with PUE.
          +		$this->register_hooks();
          +	}
          +
          +	/**
          +	 * Registers the provider handling all the 1st level filters and actions for PUE.
          +	 *
          +	 * @since 4.9.2
          +	 */
          +	protected function register_hooks() {
          +		add_filter( 'upgrader_source_selection', [ $this, 'filter_upgrader_source_selection' ], 15, 4 );
          +	}
          +
          +	/**
          +	 * Filters the source file location for the upgrade package for the PUE Update_Prevention engine.
          +	 *
          +	 * @since  4.9.12
          +	 *
          +	 * @param string      $source        File source location.
          +	 * @param string      $remote_source Remote file source location.
          +	 * @param WP_Upgrader $upgrader      WP_Upgrader instance.
          +	 * @param array       $extra         Extra arguments passed to hooked filters.
          +	 */
          +	public function filter_upgrader_source_selection( $source, $remote_source, $upgrader, $extras ) {
          +		return $this->container->make( Update_Prevention::class )->filter_upgrader_source_selection( $source, $remote_source, $upgrader, $extras );
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Processes.php b/tribe-common/src/Tribe/Service_Providers/Processes.php
          new file mode 100644
          index 0000000000..be8ddbb99b
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Processes.php
          @@ -0,0 +1,278 @@
          +context = tribe( 'context' );
          +
          +		// If the context of this request is neither AJAX or Cron bail.
          +		if ( ! ( $this->context->doing_ajax() || $this->context->doing_cron() ) ) {
          +			return;
          +		}
          +
          +		/** @var Tribe__Feature_Detection $feature_detection */
          +		$feature_detection         = tribe( 'feature-detection' );
          +		$action                    = tribe_get_request_var( 'action', false );
          +		$testing_for_async_support = $action === $this->get_handler_action( 'Tribe__Process__Tester' );
          +
          +		 // Dispatch in async mode if testing for it (w/o re-checking) or if async processes are supported.
          +		if ( $testing_for_async_support || $feature_detection->supports_async_process() ) {
          +			$this->dispatch_async();
          +
          +			return;
          +		}
          +
          +		$this->dispatch_cron();
          +	}
          +
          +	/**
          +	 * Hooks the correct handler for the action.
          +	 *
          +	 * @since 4.7.12
          +	 *
          +	 * @param string $action
          +	 */
          +	protected function hook_handler_for( $action ) {
          +		if ( null === $this->handler_actions ) {
          +			$handlers = [
          +				'Tribe__Process__Tester',
          +				'Tribe__Process__Post_Thumbnail_Setter',
          +			];
          +
          +			/**
          +			 * Filters the process handler classes the Service Provider should handle.
          +			 *
          +			 * All handlers should extend the `Tribe__Process__Handler` base class.
          +			 *
          +			 * @since 4.7.12
          +			 *
          +			 * @param array $handlers
          +			 */
          +			$handlers = array_unique( apply_filters( 'tribe_process_handlers', $handlers ) );
          +
          +			$this->handler_actions = array_combine(
          +				$handlers,
          +				array_map( [ $this, 'get_handler_action' ], $handlers )
          +			);
          +		}
          +
          +		$array_search = array_search( $action, $this->handler_actions, true );
          +
          +		if ( false === $handler_class = $array_search ) {
          +			return;
          +		}
          +
          +		// the handler will handle the hooking
          +		$this->container->make( $handler_class );
          +	}
          +
          +	/**
          +	 * Hooks the correct queue for the action.
          +	 *
          +	 * @since 4.7.12
          +	 *
          +	 * @param string $action
          +	 */
          +	protected function hook_queue_for( $action ) {
          +		if ( null === $this->queue_actions ) {
          +			$queues = [
          +				'Tribe__Promise',
          +			];
          +
          +			/**
          +			 * Filters the queue processing classes the Service Provider should handle.
          +			 *
          +			 * All queues should extend the `Tribe__Process__Queue` base class.
          +			 *
          +			 * @since 4.7.12
          +			 *
          +			 * @param array $queues An array of class names, each extending the `Tribe__Process__Queue` base class.
          +			 */
          +			$queues = array_unique( apply_filters( 'tribe_process_queues', $queues ) );
          +
          +			$all_queues_actions = array_combine(
          +				$queues,
          +				array_map( [ $this, 'get_queue_action' ], $queues )
          +			);
          +		}
          +
          +		$array_search = array_search( $action, $all_queues_actions, true );
          +
          +		if ( false === $queue_class = $array_search ) {
          +			return;
          +		}
          +
          +		// the queue will handle the hooking
          +		$this->container->make( $queue_class );
          +	}
          +
          +	/**
          +	 * Returns the action for the handler.
          +	 *
          +	 * @since 4.7.12
          +	 *
          +	 * @param string $handler_class
          +	 *
          +	 * @return string
          +	 */
          +	protected function get_handler_action( $handler_class ) {
          +		/** @var Tribe__Process__Handler handler_class */
          +		return 'tribe_process_' . call_user_func( [ $handler_class, 'action' ] );
          +	}
          +
          +	/**
          +	 * Returns the action for the queue.
          +	 *
          +	 * @since 4.7.12
          +	 *
          +	 * @param string $queue_class
          +	 *
          +	 * @return string
          +	 */
          +	protected function get_queue_action( $queue_class ) {
          +		/** @var Tribe__Process__Queue queue_class */
          +		return 'tribe_queue_' . call_user_func( [ $queue_class, 'action' ] );
          +	}
          +
          +	/**
          +	 * Dispatches the request, if in AJAX context of a valid queue processing request,
          +	 *  to the correct handler.
          +	 *
          +	 * @since 4.7.23
          +	 */
          +	protected function dispatch_async() {
          +		if ( ! (
          +			$this->context->doing_ajax()
          +			&& false !== $action = tribe_get_request_var( 'action', false )
          +		) ) {
          +			return;
          +		}
          +
          +		$this->hook_handler_for_action( $action );
          +	}
          +
          +	/**
          +	 * Start the process handlers if in the context of a cron process and
          +	 * if any is registered.
          +	 *
          +	 * @since 4.7.23
          +	 */
          +	protected function dispatch_cron() {
          +		if ( ! $this->context->doing_cron() ) {
          +			return;
          +		}
          +
          +		/*
          +		 * Here we parse the scheduled cron events to get those scheduled by a queue
          +		 * or process handler.
          +		 */
          +		$hooks = $this->get_scheduled_like( [ 'tribe_process_', 'tribe_queue_' ] );
          +
          +		if ( empty( $hooks ) ) {
          +			return;
          +		}
          +
          +		foreach ( $hooks as $action ) {
          +			/*
          +			 * Building the queue or process handler for an action will make it
          +			 * so the handler, in its `__construct` method, will hook on the action
          +			 * triggered by its cron event.
          +			 */
          +			$this->hook_handler_for_action( $action );
          +		}
          +	}
          +
          +	/**
          +	 * Hooks the correct queue or process handler for an action if any.
          +	 *
          +	 * @since 4.7.23
          +	 *
          +	 * @param string $action The action to hook the handler, or queue, for.
          +	 */
          +	protected function hook_handler_for_action( $action ) {
          +		if (
          +			0 !== strpos( $action, 'tribe_process_' )
          +			&& 0 !== strpos( $action, 'tribe_queue_' )
          +		) {
          +			return;
          +		}
          +
          +		if ( 0 === strpos( $action, 'tribe_process_' ) ) {
          +			$this->hook_handler_for( $action );
          +		} else {
          +			$this->hook_queue_for( $action );
          +		}
          +	}
          +
          +	/**
          +	 * Parses the `cron` array to return the hook names starting with a pattern.
          +	 *
          +	 * @since 4.7.23
          +	 *
          +	 * @param string|array $needles A pattern to look for or an array of patterns; if
          +	 *                              this is an array then a match will be an hook that
          +	 *                              matches at least one pattern.
          +	 *
          +	 * @return array An array of hook names matching the pattern.
          +	 */
          +	protected function get_scheduled_like( $needles ) {
          +		$cron = get_option( 'cron', false );
          +
          +		if ( empty( $cron ) ) {
          +			return [];
          +		}
          +
          +		$needles  = (array) $needles;
          +		$matching = [];
          +
          +		foreach ( $cron as $time ) {
          +			if ( ! is_array( $time ) ) {
          +				continue;
          +			}
          +			foreach ( $time as $hook => $entry ) {
          +				foreach ( $needles as $needle ) {
          +					if ( false !== strpos( $hook, $needle ) ) {
          +						$matching[] = $hook;
          +					}
          +				}
          +			}
          +		}
          +
          +		return $matching;
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Promoter.php b/tribe-common/src/Tribe/Service_Providers/Promoter.php
          new file mode 100644
          index 0000000000..60e351024e
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Promoter.php
          @@ -0,0 +1,108 @@
          +hook();
          +	}
          +
          +	/**
          +	 * Setup hooks for classes.
          +	 */
          +	private function hook() {
          +		add_action( 'template_redirect', tribe_callback( 'promoter.view', 'display_auth_check_view' ), 10, 0 );
          +		add_action( 'init', tribe_callback( 'promoter.view', 'add_rewrites' ) );
          +
          +		/** @var Tribe__Promoter__PUE $pue */
          +		$pue = tribe( 'promoter.pue' );
          +
          +		// Only add the setting if a promoter key is present.
          +		if ( $pue->has_license_key() ) {
          +			add_action(
          +				'init',
          +				tribe_callback( 'promoter.auth', 'register_setting' )
          +			);
          +		}
          +
          +		// The usage of a high priority so we can push the icon to the end
          +		add_action( 'admin_bar_menu', [ $this, 'add_promoter_logo_on_admin_bar' ], 1000 );
          +		add_action( 'tribe_common_loaded', [ $this, 'add_promoter_assets' ] );
          +	}
          +
          +	/**
          +	 * Add Admin Bar link to the promoter website
          +	 *
          +	 * @since 4.9.2
          +	 * @param $wp_admin_bar
          +	 */
          +	public function add_promoter_logo_on_admin_bar( $wp_admin_bar ) {
          +		/** @var Tribe__Promoter__PUE $pue */
          +		$pue = tribe( 'promoter.pue' );
          +		if ( ! $pue->has_license_key() ) {
          +			return;
          +		}
          +
          +		/**
          +		 * It uses and inline SVG as will provider more flexibility for styling so we can change
          +		 * the fill of the path property of the SVG so we can match the WP installations.
          +		 */
          +		$args = [
          +			'id'    => 'promoter-admin-bar',
          +			'title' => sprintf(
          +				"%s%s",
          +				'',
          +				'Promoter'
          +			),
          +			'href'  => 'https://promoter.theeventscalendar.com/',
          +			'meta'  => [
          +				'target' => '_blank',
          +				'class'  => 'promoter-admin-bar-link',
          +			],
          +		];
          +		$wp_admin_bar->add_node( $args );
          +	}
          +
          +	/**
          +	 * Register assets associated with promoter
          +	 *
          +	 * @since 4.9.2
          +	 */
          +	public function add_promoter_assets() {
          +		tribe_asset(
          +			Tribe__Main::instance(),
          +			'promoter',
          +			'promoter.css',
          +			[],
          +			[ 'wp_enqueue_scripts', 'admin_enqueue_scripts' ],
          +			[
          +				'conditionals' => [ $this, 'should_load_promoter_styles' ],
          +			]
          +		);
          +	}
          +
          +	/**
          +	 * Only load the styles related to promoter if user is logged in and there's a valid license
          +	 * for promoter
          +	 *
          +	 * @since 4.9.2
          +	 *
          +	 * @return bool
          +	 */
          +	public function should_load_promoter_styles() {
          +		return is_user_logged_in() && tribe( 'promoter.pue' )->has_license_key();
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Shortcodes.php b/tribe-common/src/Tribe/Service_Providers/Shortcodes.php
          new file mode 100644
          index 0000000000..ccebc45225
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Shortcodes.php
          @@ -0,0 +1,121 @@
          +container->singleton( Manager::class, Manager::class );
          +		$this->container->singleton(
          +			'shortcode.manager',
          +			function() {
          +				return $this->container->make( Manager::class );
          +			}
          +		);
          +
          +		$this->register_hooks();
          +		$this->register_assets();
          +
          +		$this->container->singleton( static::class, $this );
          +
          +	}
          +
          +	/**
          +	 * Static method wrapper around a filter to allow full deactivation of this provider
          +	 *
          +	 * @since 4.12.0
          +	 *
          +	 * @return boolean If this service provider is active.
          +	 */
          +	public static function is_active() {
          +		/**
          +		 * Allows filtering to deactivate all shortcodes loading.
          +		 *
          +		 * @since 4.12.0
          +		 *
          +		 * @param boolean $is_active If shortcodes should be loaded or not.
          +		 */
          +		return apply_filters( 'tribe_shortcodes_is_active', true );
          +	}
          +
          +	/**
          +	 * Register all the assets associated with this service provider.
          +	 *
          +	 * @since 4.12.0
          +	 */
          +	protected function register_assets() {
          +
          +	}
          +
          +	/**
          +	 * Registers the provider handling all the 1st level filters and actions for this service provider.
          +	 *
          +	 * @since 4.12.0
          +	 */
          +	protected function register_hooks() {
          +		add_action( 'init', [ $this, 'action_add_shortcodes' ], 20 );
          +		add_filter( 'pre_do_shortcode_tag', [ $this, 'filter_pre_do_shortcode_tag' ], 10, 4 );
          +		add_filter( 'do_shortcode_tag', [ $this, 'filter_do_shortcode_tag' ], 10, 4 );
          +	}
          +
          +	/**
          +	 * Adds the new shortcodes, this normally will trigger on `init@P20` due to how we the
          +	 * v1 is added on `init@P10` and we remove them on `init@P15`.
          +	 *
          +	 * It's important to leave gaps on priority for better injection.
          +	 *
          +	 * @since 4.12.0
          +	 */
          +	public function action_add_shortcodes() {
          +		$this->container->make( Manager::class )->add_shortcodes();
          +	}
          +
          +	/**
          +	 * Filters `pre_do_shortcode_tag` to mark that a tribe shortcode is currently being done.
          +	 *
          +	 * @since 4.12.9
          +	 *
          +	 * @param bool|string $return      Short-circuit return value. Either false or the value to replace the shortcode with.
          +	 * @param string      $tag         Shortcode name.
          +	 * @param array       $attr        Shortcode attributes array,
          +	 * @param array       $m           Regular expression match array.
          +	 *
          +	 * @return bool|string Short-circuit return value.
          +	 */
          +	public function filter_pre_do_shortcode_tag( $false, $tag, $attr, $m ) {
          +		return $this->container->make( Manager::class )->filter_pre_do_shortcode_tag( $false, $tag, $attr, $m );
          +	}
          +
          +	/**
          +	 * * Filters `do_shortcode_tag` to mark that a tribe shortcode is complete, and remove it from the current list.
          +	 *
          +	 * @since 4.12.9
          +	 *
          +	 * @param string       $output Shortcode output.
          +	 * @param string       $tag    Shortcode name.
          +	 * @param array|string $attr   Shortcode attributes array or empty string.
          +	 * @param array        $m      Regular expression match array.
          +	 *
          +	 * @return string Shortcode output.
          +	 */
          +	public function filter_do_shortcode_tag( $output, $tag, $attr, $m ) {
          +		return $this->container->make( Manager::class )->filter_do_shortcode_tag( $output, $tag, $attr, $m );
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Tooltip.php b/tribe-common/src/Tribe/Service_Providers/Tooltip.php
          new file mode 100644
          index 0000000000..6cbad8bf8d
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Tooltip.php
          @@ -0,0 +1,59 @@
          +hook();
          +	}
          +
          +	/**
          +	 * Setup hooks for classes.
          +	 *
          +	 * @since 4.9.8
          +	 */
          +	private function hook() {
          +		add_action( 'tribe_common_loaded', [ $this, 'add_tooltip_assets' ] );
          +	}
          +
          +	/**
          +	 * Register assets associated with tooltip
          +	 *
          +	 * @since 4.9.8
          +	 */
          +	public function add_tooltip_assets() {
          +		$main = \Tribe__Main::instance();
          +
          +		tribe_asset(
          +			$main,
          +			'tribe-tooltip',
          +			'tooltip.css',
          +			[ 'tribe-common-skeleton-style' ],
          +			[ 'wp_enqueue_scripts', 'admin_enqueue_scripts' ],
          +			[ 'groups' => 'tribe-tooltip' ]
          +		);
          +
          +		tribe_asset(
          +			$main,
          +			'tribe-tooltip-js',
          +			'tooltip.js',
          +			[ 'jquery', 'tribe-common' ],
          +			[],
          +			[ 'groups' => 'tribe-tooltip' ]
          +		);
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Service_Providers/Widgets.php b/tribe-common/src/Tribe/Service_Providers/Widgets.php
          new file mode 100644
          index 0000000000..9ad83af1a2
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Service_Providers/Widgets.php
          @@ -0,0 +1,77 @@
          +container->singleton( Manager::class, Manager::class );
          +		$this->container->singleton(
          +			'widget.manager',
          +			function() {
          +				return $this->container->make( Manager::class );
          +			}
          +		);
          +
          +		$this->register_hooks();
          +
          +		$this->container->singleton( static::class, $this );
          +		$this->container->singleton( 'widgets', $this );
          +	}
          +
          +	/**
          +	 * Static method wrapper around a filter to allow full deactivation of this provider.
          +	 *
          +	 * @since 4.12.12
          +	 *
          +	 * @return boolean If this service provider is active.
          +	 */
          +	public static function is_active() {
          +		/**
          +		 * Allows filtering to prevent all Tribe widgets from loading.
          +		 *
          +		 * @since 4.12.12
          +		 *
          +		 * @param boolean $is_active If widgets should be loaded or not.
          +		 */
          +		return apply_filters( 'tribe_widgets_is_active', true );
          +	}
          +
          +	/**
          +	 * Registers the provider handling all the 1st level filters and actions for this service provider.
          +	 *
          +	 * @since 4.12.12
          +	 */
          +	protected function register_hooks() {
          +		add_action( 'widgets_init', [ $this, 'register_widgets_with_wp' ], 20 );
          +	}
          +
          +	/**
          +	 * Adds the new widgets.
          +	 *
          +	 * This triggers on `init@P20` due to how v1 is added on `init@P10` and removed on `init@P15`,
          +	 * as it's important to leave gaps on priority for future flexibility.
          +	 *
          +	 * @since 4.12.12
          +	 */
          +	public function register_widgets_with_wp() {
          +		$this->container->make( Manager::class )->register_widgets_with_wp();
          +	}
          +}
          diff --git a/tribe-common/src/Tribe/Settings.php b/tribe-common/src/Tribe/Settings.php
          new file mode 100755
          index 0000000000..1b556721e7
          --- /dev/null
          +++ b/tribe-common/src/Tribe/Settings.php
          @@ -0,0 +1,788 @@
          + => array(...) ]
          +		 * @var array
          +		 */
          +		protected $fields_for_save = [];
          +
          +		/**
          +		 * An array that contains the fields that are currently being validated.
          +		 * @var array
          +		 */
          +		protected $current_fields = [];
          +
          +		/**
          +		 * Static Singleton Factory Method
          +		 *
          +		 * @return Tribe__Settings
          +		 */
          +		public static function instance() {
          +			return tribe( 'settings' );
          +		}
          +
          +		/**
          +		 * Class constructor
          +		 *
          +		 * @return void
          +		 */
          +		public function __construct() {
          +
          +			// set instance variables
          +			$this->menuName    = apply_filters( 'tribe_settings_menu_name', esc_html__( 'Events', 'tribe-common' ) );
          +			$this->requiredCap = apply_filters( 'tribe_settings_req_cap', 'manage_options' );
          +			$this->adminSlug   = apply_filters( 'tribe_settings_admin_slug', 'tribe-common' );
          +			$this->help_slug   = apply_filters( 'tribe_settings_help_slug', 'tribe-common-help' );
          +			$this->errors      = get_option( 'tribe_settings_errors', [] );
          +			$this->major_error = get_option( 'tribe_settings_major_error', false );
          +			$this->sent_data   = get_option( 'tribe_settings_sent_data', [] );
          +			$this->validated   = [];
          +			$this->defaultTab  = null;
          +			$this->currentTab  = null;
          +
          +			$this->hook();
          +		}
          +
          +		/**
          +		 * Hooks the actions and filters required for the class to work.
          +		 */
          +		public function hook() {
          +			// run actions & filters
          +			add_action( 'admin_menu', [ $this, 'addPage' ] );
          +			add_action( 'network_admin_menu', [ $this, 'addNetworkPage' ] );
          +			add_action( 'admin_init', [ $this, 'initTabs' ] );
          +			add_action( 'tribe_settings_below_tabs', [ $this, 'displayErrors' ] );
          +			add_action( 'tribe_settings_below_tabs', [ $this, 'displaySuccess' ] );
          +		}
          +
          +		/**
          +		 * Determines whether or not the full admin pages should be initialized.
          +		 *
          +		 * When running in parallel with TEC 3.12.4, TEC should be relied on to handle the admin screens
          +		 * that version of TEC (and lower) is tribe-common ignorant. Therefore, tribe-common has to be
          +		 * the smarter, more lenient codebase.
          +		 *
          +		 * @return boolean
          +		 */
          +		public function should_setup_pages() {
          +			if ( ! class_exists( 'Tribe__Events__Main' ) ) {
          +				return true;
          +			}
          +
          +			if ( version_compare( Tribe__Events__Main::VERSION, '4.0beta', '>=' ) ) {
          +				return true;
          +			}
          +
          +			return false;
          +		}
          +
          +		/**
          +		 * create the main option page
          +		 *
          +		 * @return void
          +		 */
          +		public function addPage() {
          +			if ( ! $this->should_setup_pages() ) {
          +				return;
          +			}
          +
          +			if ( ! is_multisite() || ( is_multisite() && '0' == Tribe__Settings_Manager::get_network_option( 'allSettingsTabsHidden', '0' ) ) ) {
          +				if ( post_type_exists( 'tribe_events' ) ) {
          +					self::$parent_page = 'edit.php?post_type=tribe_events';
          +				} else {
          +					self::$parent_page = 'admin.php?page=tribe-common';
          +
          +					add_menu_page(
          +						esc_html__( 'Events', 'tribe-common' ),
          +						esc_html__( 'Events', 'tribe-common' ),
          +						apply_filters( 'tribe_common_event_page_capability', 'manage_options' ),
          +						self::$parent_slug,
          +						null,
          +						'dashicons-calendar',
          +						6
          +					);
          +				}
          +
          +				$this->admin_page = add_submenu_page(
          +					$this->get_parent_slug(),
          +					esc_html__( 'Events Settings', 'tribe-common' ),
          +					esc_html__( 'Settings', 'tribe-common' ),
          +					$this->requiredCap,
          +					self::$parent_slug,
          +					[ $this, 'generatePage' ]
          +				);
          +			}
          +		}
          +
          +		/**
          +		 * create the network options page
          +		 *
          +		 * @return void
          +		 */
          +		public function addNetworkPage() {
          +			if ( ! $this->should_setup_network_pages() ) {
          +				return;
          +			}
          +
          +			$this->admin_page = add_submenu_page(
          +				'settings.php', esc_html__( 'Events Settings', 'tribe-common' ), esc_html__( 'Events Settings', 'tribe-common' ), $this->requiredCap, $this->adminSlug, [
          +					$this,
          +					'generatePage',
          +				]
          +			);
          +
          +			$this->admin_page = add_submenu_page(
          +				'settings.php',
          +				esc_html__( 'Events Help', 'tribe-common' ),
          +				esc_html__( 'Events Help', 'tribe-common' ),
          +				$this->requiredCap,
          +				$this->help_slug,
          +				[
          +					tribe( 'settings.manager' ),
          +					'do_help_tab',
          +				]
          +			);
          +		}
          +
          +		/**
          +		 * init all the tabs
          +		 *
          +		 * @return void
          +		 */
          +		public function initTabs() {
          +			if (
          +				empty( $_GET['page'] )
          +				|| $_GET['page'] != $this->adminSlug
          +			) {
          +				return;
          +			}
          +
          +			// Load settings tab-specific helpers and enhancements
          +			Tribe__Admin__Live_Date_Preview::instance();
          +
          +			do_action( 'tribe_settings_do_tabs' ); // this is the hook to use to add new tabs
          +			$this->tabs       = (array) apply_filters( 'tribe_settings_tabs', [] );
          +			$this->allTabs    = (array) apply_filters( 'tribe_settings_all_tabs', [] );
          +			$this->noSaveTabs = (array) apply_filters( 'tribe_settings_no_save_tabs', [] );
          +
          +			if ( is_network_admin() ) {
          +				$this->defaultTab = apply_filters( 'tribe_settings_default_tab_network', 'network' );
          +				$this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
          +				$this->url        = apply_filters(
          +					'tribe_settings_url', add_query_arg(
          +						[
          +							'page' => $this->adminSlug,
          +							'tab'  => $this->currentTab,
          +						], network_admin_url( 'settings.php' )
          +					)
          +				);
          +			} else {
          +				$tabs_keys        = array_keys( $this->tabs );
          +				$this->defaultTab = in_array( apply_filters( 'tribe_settings_default_tab', 'general' ), $tabs_keys ) ? apply_filters( 'tribe_settings_default_tab', 'general' ) : $tabs_keys[0];
          +				$this->currentTab = apply_filters( 'tribe_settings_current_tab', ( isset( $_GET['tab'] ) && $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : $this->defaultTab );
          +				$this->url        = apply_filters(
          +					'tribe_settings_url', add_query_arg(
          +						[
          +							'page' => $this->adminSlug,
          +							'tab'  => $this->currentTab,
          +						],
          +						admin_url( self::$parent_page )
          +					)
          +				);
          +			}
          +
          +			$this->fields_for_save = (array) apply_filters( 'tribe_settings_fields', [] );
          +			do_action( 'tribe_settings_after_do_tabs' );
          +			$this->fields = (array) apply_filters( 'tribe_settings_fields', [] );
          +			$this->validate();
          +		}
          +
          +		/**
          +		 * generate the main option page
          +		 * includes the view file
          +		 *
          +		 * @return void
          +		 */
          +		public function generatePage() {
          +			do_action( 'tribe_settings_top' );
          +			echo '
          '; + echo '

          '; + printf( esc_html__( '%s Settings', 'tribe-common' ), $this->menuName ); + echo '

          '; + do_action( 'tribe_settings_above_tabs' ); + $this->generateTabs( $this->currentTab ); + do_action( 'tribe_settings_below_tabs' ); + do_action( 'tribe_settings_below_tabs_tab_' . $this->currentTab ); + echo '
          '; + do_action( 'tribe_settings_above_form_element' ); + do_action( 'tribe_settings_above_form_element_tab_' . $this->currentTab ); + echo apply_filters( 'tribe_settings_form_element_tab_' . $this->currentTab, '
          ' ); + do_action( 'tribe_settings_before_content' ); + do_action( 'tribe_settings_before_content_tab_' . $this->currentTab ); + do_action( 'tribe_settings_content_tab_' . $this->currentTab ); + if ( ! has_action( 'tribe_settings_content_tab_' . $this->currentTab ) ) { + echo '

          ' . esc_html__( "You've requested a non-existent tab.", 'tribe-common' ) . '

          '; + } + do_action( 'tribe_settings_after_content_tab_' . $this->currentTab ); + do_action( 'tribe_settings_after_content' ); + if ( has_action( 'tribe_settings_content_tab_' . $this->currentTab ) && ! in_array( $this->currentTab, $this->noSaveTabs ) ) { + wp_nonce_field( 'saving', 'tribe-save-settings' ); + echo '
          '; + echo ''; + echo ''; + } + echo apply_filters( 'tribe_settings_closing_form_element', '
          ' ); + do_action( 'tribe_settings_after_form_element' ); + do_action( 'tribe_settings_after_form_element_tab_' . $this->currentTab ); + echo '
          '; + do_action( 'tribe_settings_after_form_div' ); + echo '
          '; + do_action( 'tribe_settings_bottom' ); + } + + /** + * generate the tabs in the settings screen + * + * @return void + */ + public function generateTabs() { + if ( is_array( $this->tabs ) && ! empty( $this->tabs ) ) { + echo ''; + } + } + + /** + * validate the settings + * + * @return void + */ + public function validate() { + + do_action( 'tribe_settings_validate_before_checks' ); + + // check that the right POST && variables are set + if ( isset( $_POST['tribeSaveSettings'] ) && isset( $_POST['current-settings-tab'] ) ) { + // check permissions + if ( ! current_user_can( 'manage_options' ) ) { + $this->errors[] = esc_html__( "You don't have permission to do that.", 'tribe-common' ); + $this->major_error = true; + } + + // check the nonce + if ( ! wp_verify_nonce( $_POST['tribe-save-settings'], 'saving' ) ) { + $this->errors[] = esc_html__( 'The request was sent insecurely.', 'tribe-common' ); + $this->major_error = true; + } + + // check that the request originated from the current tab + if ( $_POST['current-settings-tab'] != $this->currentTab ) { + $this->errors[] = esc_html__( "The request wasn't sent from this tab.", 'tribe-common' ); + $this->major_error = true; + } + + // bail if we have errors + if ( count( $this->errors ) ) { + remove_action( 'shutdown', [ $this, 'deleteOptions' ] ); + add_option( 'tribe_settings_errors', $this->errors ); + add_option( 'tribe_settings_major_error', $this->major_error ); + wp_redirect( $this->url ); + exit; + } + + // some hooks + do_action( 'tribe_settings_validate' ); + do_action( 'tribe_settings_validate_tab_' . $this->currentTab ); + + // set the current tab and current fields + $tab = $this->currentTab; + $fields = $this->current_fields = $this->fields_for_save[ $tab ]; + + if ( is_array( $fields ) ) { + // loop through the fields and validate them + foreach ( $fields as $field_id => $field ) { + // get the value + $value = ( isset( $_POST[ $field_id ] ) ) ? $_POST[ $field_id ] : null; + $value = apply_filters( 'tribe_settings_validate_field_value', $value, $field_id, $field ); + + // make sure it has validation set up for it, else do nothing + if ( + ( ! isset( $field['conditional'] ) || $field['conditional'] ) + && ( ! empty( $field['validation_type'] ) || ! empty( $field['validation_callback'] ) ) + ) { + // some hooks + do_action( 'tribe_settings_validate_field', $field_id, $value, $field ); + do_action( 'tribe_settings_validate_field_' . $field_id, $value, $field ); + + // validate this field + $validate = new Tribe__Validate( $field_id, $field, $value ); + + if ( isset( $validate->result->error ) ) { + // uh oh; validation failed + $this->errors[ $field_id ] = $validate->result->error; + } elseif ( $validate->result->valid ) { + // validation passed + $this->validated[ $field_id ] = new stdClass; + $this->validated[ $field_id ]->field = $validate->field; + $this->validated[ $field_id ]->value = $validate->value; + } + } + } + + // do not generate errors for dependent fields that should not show + if ( ! empty( $this->errors ) ) { + $keep = array_filter( array_keys( $this->errors ), [ $this, 'dependency_checks' ] ); + $compare = empty( $keep ) ? [] : array_combine( $keep, $keep ); + $this->errors = array_intersect_key( $this->errors, $compare ); + } + + // run the saving method + $this->save(); + } + } + + } + + /** + * save the settings + * + * @return void + */ + public function save() { + + // some hooks + do_action( 'tribe_settings_save' ); + do_action( 'tribe_settings_save_tab_' . $this->currentTab ); + + // we'll need this later + $parent_options = []; + + /** + * loop through each validated option and either + * save it as is or figure out its parent option ID + * (in that case, it's a serialized option array and + * will be saved in the next loop) + */ + if ( ! empty( $this->validated ) ) { + foreach ( $this->validated as $field_id => $validated_field ) { + // get the value and filter it + $value = $validated_field->value; + $value = apply_filters( 'tribe_settings_save_field_value', $value, $field_id, $validated_field ); + + // figure out the parent option [could be set to false] and filter it + if ( is_network_admin() ) { + $parent_option = ( isset( $validated_field->field['parent_option'] ) ) ? $validated_field->field['parent_option'] : Tribe__Main::OPTIONNAMENETWORK; + } + if ( ! is_network_admin() ) { + $parent_option = ( isset( $validated_field->field['parent_option'] ) ) ? $validated_field->field['parent_option'] : Tribe__Main::OPTIONNAME; + } + + $parent_option = apply_filters( 'tribe_settings_save_field_parent_option', $parent_option, $field_id ); + $network_option = isset( $validated_field->field['network_option'] ) ? (bool) $validated_field->field['network_option'] : false; + + // some hooks + do_action( 'tribe_settings_save_field', $field_id, $value, $validated_field ); + do_action( 'tribe_settings_save_field_' . $field_id, $value, $validated_field ); + + if ( ! $parent_option ) { + if ( $network_option || is_network_admin() ) { + update_site_option( $field_id, $value ); + } else { + update_option( $field_id, $value ); + } + } else { + // set the parent option + $parent_options[ $parent_option ][ $field_id ] = $value; + } + } + } + + /** + * loop through parent option arrays + * and save them + * NOTE: in the case of the main option Tribe Options, + * this will save using the Tribe__Settings_Manager::set_options method. + */ + foreach ( $parent_options as $option_id => $new_options ) { + // get the old options + if ( is_network_admin() ) { + $old_options = (array) get_site_option( $option_id ); + } else { + $old_options = (array) get_option( $option_id ); + } + + // set the options by parsing old + new and filter that + $options = apply_filters( 'tribe_settings_save_option_array', wp_parse_args( $new_options, $old_options ), $option_id ); + + if ( $option_id == Tribe__Main::OPTIONNAME ) { + // save using the Tribe__Settings_Manager method + Tribe__Settings_Manager::set_options( $options ); + } elseif ( $option_id == Tribe__Main::OPTIONNAMENETWORK ) { + Tribe__Settings_Manager::set_network_options( $options ); + } else { + // save using regular WP method + if ( is_network_admin() ) { + update_site_option( $option_id, $options ); + } else { + update_option( $option_id, $options ); + } + } + } + + do_action( 'tribe_settings_after_save' ); + do_action( 'tribe_settings_after_save_' . $this->currentTab ); + remove_action( 'shutdown', [ $this, 'deleteOptions' ] ); + add_option( 'tribe_settings_sent_data', $_POST ); + add_option( 'tribe_settings_errors', $this->errors ); + add_option( 'tribe_settings_major_error', $this->major_error ); + wp_redirect( esc_url_raw( add_query_arg( [ 'saved' => true ], $this->url ) ) ); + exit; + } + + /** + * display errors, if any, after saving + * + * @return void + */ + public function displayErrors() { + + // fetch the errors and filter them + $errors = (array) apply_filters( 'tribe_settings_display_errors', $this->errors ); + $count = apply_filters( 'tribe_settings_count_errors', count( $errors ) ); + + if ( apply_filters( 'tribe_settings_display_errors_or_not', ( $count > 0 ) ) ) { + // output a message if we have errors + + $output = '

          '; + $output .= esc_html__( 'Your form had the following errors:', 'tribe-common' ); + $output .= '

            '; + + // loop through each error + foreach ( $errors as $error ) { + $output .= '
          • ' . (string) $error . '
          • '; + } + + if ( count( $errors ) ) { + $message = ( isset( $this->major_error ) && $this->major_error ) + ? esc_html__( 'None of your settings were saved. Please try again.' ) + : esc_html( _n( 'The above setting was not saved. Other settings were successfully saved.', 'The above settings were not saved. Other settings were successfully saved.', $count, 'tribe-common' ) ); + } + + $output .= '

          ' . $message . '

          '; + + // final output, filtered of course + echo apply_filters( 'tribe_settings_error_message', $output ); + } + } + + /** + * display success message after saving + * + * @return void + */ + public function displaySuccess() { + $errors = (array) apply_filters( 'tribe_settings_display_errors', $this->errors ); + $count = apply_filters( 'tribe_settings_count_errors', count( $errors ) ); + + // are we coming from the saving place? + if ( isset( $_GET['saved'] ) && ! apply_filters( 'tribe_settings_display_errors_or_not', ( $count > 0 ) ) ) { + // output the filtered message + $message = esc_html__( 'Settings saved.', 'tribe-common' ); + $output = '

          ' . $message . '

          '; + echo apply_filters( 'tribe_settings_success_message', $output, $this->currentTab ); + } + + //Delete Temporary Options After Display Errors and Success + $this->deleteOptions(); + } + + /** + * delete temporary options + * + * @return void + */ + public function deleteOptions() { + delete_option( 'tribe_settings_errors' ); + delete_option( 'tribe_settings_major_error' ); + delete_option( 'tribe_settings_sent_data' ); + } + + /** + * Returns the main admin settings URL. + * + * @return string + */ + public function get_url( array $args = [] ) { + $defaults = [ + 'page' => $this->adminSlug, + 'parent' => self::$parent_page, + ]; + + // Allow the link to be "changed" on the fly + $args = wp_parse_args( $args, $defaults ); + + $url = admin_url( $args['parent'] ); + + // keep the resulting URL args clean + unset( $args['parent'] ); + + return apply_filters( 'tribe_settings_url', add_query_arg( $args, $url ), $args, $url ); + } + + /** + * The "slug" used for adding submenu pages + * + * @return string + */ + public function get_parent_slug() { + $slug = self::$parent_page; + + // if we don't have an event post type, then we can just use the tribe-common slug + if ( 'edit.php' === $slug || 'admin.php?page=tribe-common' === $slug ) { + $slug = self::$parent_slug; + } + + return $slug; + } + + /** + * @return string + */ + public function get_help_slug() { + return $this->help_slug; + } + + /** + * Determines whether or not the network admin pages should be initialized. + * + * When running in parallel with TEC 3.12.4, TEC should be relied on to handle the admin screens + * that version of TEC (and lower) is tribe-common ignorant. Therefore, tribe-common has to be + * the smarter, more lenient codebase. + * Beyond this at least one of the two "root" plugins (The Events Calendar and Event Tickets) + * should be network activated to add the page. + * + * @return boolean + */ + public function should_setup_network_pages() { + $root_plugin_is_mu_activated = array_sum( array_map( 'is_plugin_active_for_network', $this->root_plugins ) ) >= 1; + + if ( ! $root_plugin_is_mu_activated ) { + return false; + } + + if ( ! class_exists( 'Tribe__Events__Main' ) ) { + return true; + } + + if ( version_compare( Tribe__Events__Main::VERSION, '4.0beta', '>=' ) ) { + return true; + } + + return false; + + } + + /** + * Sets what `common` should consider root plugins. + * + * @param array $root_plugins An array of plugins in the `/` format. + */ + public function set_root_plugins( array $root_plugins ) { + $this->root_plugins = $root_plugins; + } + + /** + * Whether the specified field dependency condition is valid or not depending on + * its parent field value. + * + * @since 4.7.7 + * + * @param string $field_id The id of the field that might be removed. + * + * @return bool `true` if the field dependency condition is valid, `false` if the field + * dependency condition is not valid. + */ + protected function dependency_checks( $field_id ) { + $does_not_exist = ! array_key_exists( $field_id, $this->current_fields ); + + if ( $does_not_exist ) { + return false; + } + + $has_no_dependency = ! isset( $this->current_fields[ $field_id ]['validate_if'] ); + + if ( $has_no_dependency ) { + return true; + } + + $condition = $this->current_fields[ $field_id ]['validate_if']; + + if ( $condition instanceof Tribe__Field_Conditional ) { + $parent_field = Tribe__Utils__Array::get( $this->validated, $condition->depends_on(), null ); + + return $condition->check( $parent_field->value, $this->current_fields ); + } + + return is_callable( $condition ) + ? call_user_func( $condition, $this->current_fields ) + : true == $condition; + } + } // end class +} // endif class_exists diff --git a/tribe-common/src/Tribe/Settings_Manager.php b/tribe-common/src/Tribe/Settings_Manager.php new file mode 100644 index 0000000000..80d5cfa222 --- /dev/null +++ b/tribe-common/src/Tribe/Settings_Manager.php @@ -0,0 +1,367 @@ +add_hooks(); + + // Load multisite defaults + if ( is_multisite() ) { + $tribe_events_mu_defaults = []; + if ( file_exists( WP_CONTENT_DIR . '/tribe-events-mu-defaults.php' ) ) { + require_once WP_CONTENT_DIR . '/tribe-events-mu-defaults.php'; + } + self::$tribe_events_mu_defaults = apply_filters( 'tribe_events_mu_defaults', $tribe_events_mu_defaults ); + } + } + + public function add_hooks() { + // option pages + add_action( '_network_admin_menu', [ $this, 'init_options' ] ); + add_action( '_admin_menu', [ $this, 'init_options' ] ); + + add_action( 'admin_menu', [ $this, 'add_help_admin_menu_item' ], 50 ); + add_action( 'tribe_settings_do_tabs', [ $this, 'do_setting_tabs' ] ); + add_action( 'tribe_settings_do_tabs', [ $this, 'do_network_settings_tab' ], 400 ); + add_action( 'tribe_settings_validate_tab_network', [ $this, 'save_all_tabs_hidden' ] ); + add_action( 'updated_option', [ $this, 'update_options_cache' ], 10, 3 ); + } + + /** + * For performance reasons our options are saved in memory, but we need to make sure we update it when WordPress + * updates the variable directly. + * + * @since 4.11.0 + * + * @param string $option Name of the updated option. + * @param mixed $old_value The old option value. + * @param mixed $value The new option value. + * + * @return void + */ + public function update_options_cache( $option, $old_value, $value ) { + // Bail when no our option. + if ( Tribe__Main::OPTIONNAME !== $option ) { + return; + } + + tribe_set_var( self::OPTION_CACHE_VAR_NAME, $value ); + } + + /** + * Init the settings API and add a hook to add your own setting tabs + * + * @return void + */ + public function init_options() { + Tribe__Settings::instance(); + } + + /** + * Create setting tabs + * + * @return void + */ + public function do_setting_tabs() { + // Make sure Thickbox is available regardless of which admin page we're on + add_thickbox(); + + include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-general.php'; + include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-display.php'; + + $showNetworkTabs = $this->get_network_option( 'showSettingsTabs', false ); + + new Tribe__Settings_Tab( 'general', esc_html__( 'General', 'tribe-common' ), $generalTab ); + new Tribe__Settings_Tab( 'display', esc_html__( 'Display', 'tribe-common' ), $displayTab ); + + $this->do_licenses_tab(); + } + + /** + * Get all options for the Events Calendar + * + * @return array of options + */ + public static function get_options() { + $options = tribe_get_var( self::OPTION_CACHE_VAR_NAME, [] ); + + if ( empty( $options ) ) { + $options = (array) get_option( Tribe__Main::OPTIONNAME, [] ); + + tribe_set_var( self::OPTION_CACHE_VAR_NAME, $options ); + } + + return $options; + } + + /** + * Get value for a specific option + * + * @param string $option_name name of option + * @param string $default default value + * + * @return mixed results of option query + */ + public static function get_option( $option_name, $default = '' ) { + if ( ! $option_name ) { + return null; + } + $options = static::get_options(); + + $option = $default; + if ( array_key_exists( $option_name, $options ) ) { + $option = $options[ $option_name ]; + } elseif ( is_multisite() && isset( self::$tribe_events_mu_defaults ) && is_array( self::$tribe_events_mu_defaults ) && in_array( $option_name, array_keys( self::$tribe_events_mu_defaults ) ) ) { + $option = self::$tribe_events_mu_defaults[ $option_name ]; + } + + return apply_filters( 'tribe_get_single_option', $option, $default, $option_name ); + } + + /** + * Saves the options for the plugin + * + * @param array $options formatted the same as from get_options() + * @param bool $apply_filters + * + * @return bool + */ + public static function set_options( $options, $apply_filters = true ) { + if ( ! is_array( $options ) ) { + return false; + } + if ( true === $apply_filters ) { + $options = apply_filters( 'tribe-events-save-options', $options ); + } + $updated = update_option( Tribe__Main::OPTIONNAME, $options ); + + if ( $updated ) { + tribe_set_var( self::OPTION_CACHE_VAR_NAME, $options ); + } + + return $updated; + } + + /** + * Set an option + * + * @param string $name + * @param mixed $value + * + * @return bool + */ + public static function set_option( $name, $value ) { + $options = self::get_options(); + $options[ $name ] = $value; + + return self::set_options( $options ); + } + + /** + * Get all network options for the Events Calendar + * + * @return array of options + * @TODO add force option, implement in setNetworkOptions + */ + public static function get_network_options() { + if ( ! isset( self::$network_options ) ) { + $options = get_site_option( Tribe__Main::OPTIONNAMENETWORK, [] ); + self::$network_options = apply_filters( 'tribe_get_network_options', $options ); + } + + return self::$network_options; + } + + /** + * Get value for a specific network option + * + * @param string $option_name name of option + * @param string $default default value + * + * @return mixed results of option query + */ + public static function get_network_option( $option_name, $default = '' ) { + if ( ! $option_name ) { + return null; + } + + if ( ! isset( self::$network_options ) ) { + self::get_network_options(); + } + + if ( isset( self::$network_options[ $option_name ] ) ) { + $option = self::$network_options[ $option_name ]; + } else { + $option = $default; + } + + return apply_filters( 'tribe_get_single_network_option', $option, $default ); + } + + /** + * Saves the network options for the plugin + * + * @param array $options formatted the same as from get_options() + * @param bool $apply_filters + * + * @return void + */ + public static function set_network_options( $options, $apply_filters = true ) { + if ( ! is_array( $options ) ) { + return; + } + + if ( $apply_filters == true ) { + $options = apply_filters( 'tribe-events-save-network-options', $options ); + } + + if ( update_site_option( Tribe__Main::OPTIONNAMENETWORK, $options ) ) { + self::$network_options = apply_filters( 'tribe_get_network_options', $options ); + } else { + self::$network_options = self::get_network_options(); + } + } + + /** + * Add the network admin options page + * + * @return void + */ + public static function add_network_options_page() { + $tribe_settings = Tribe__Settings::instance(); + add_submenu_page( + 'settings.php', + $tribe_settings->menuName, + $tribe_settings->menuName, + 'manage_network_options', + 'tribe-common', + [ + $tribe_settings, + 'generatePage', + ] + ); + } + + /** + * Render network admin options view + * + * @return void + */ + public static function do_network_settings_tab() { + include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-network.php'; + + new Tribe__Settings_Tab( 'network', esc_html__( 'Network', 'tribe-common' ), $networkTab ); + } + + /** + * Registers the license key management tab in the Events > Settings screen, + * only if premium addons are detected. + */ + protected function do_licenses_tab() { + $show_tab = ( current_user_can( 'activate_plugins' ) && $this->have_addons() ); + + /** + * Provides an oppotunity to override the decision to show or hide the licenses tab + * + * Normally it will only show if the current user has the "activate_plugins" capability + * and there are some currently-activated premium plugins. + * + * @var bool + */ + if ( ! apply_filters( 'tribe_events_show_licenses_tab', $show_tab ) ) { + return; + } + + /** + * @var $licenses_tab + */ + include Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-licenses.php'; + + /** + * Allows the fields displayed in the licenses tab to be modified. + * + * @var array + */ + $license_fields = apply_filters( 'tribe_license_fields', $licenses_tab ); + + new Tribe__Settings_Tab( 'licenses', esc_html__( 'Licenses', 'tribe-common' ), [ + 'priority' => '40', + 'fields' => $license_fields, + 'network_admin' => is_network_admin() ? true : false, + ] ); + } + + /** + * Create the help tab + */ + public function do_help_tab() { + /** + * Include Help tab Assets here + */ + + include_once Tribe__Main::instance()->plugin_path . 'src/admin-views/tribe-options-help.php'; + } + + /** + * Add help menu item to the admin (unless blocked via network admin settings). + * + * @todo move to an admin class + */ + public function add_help_admin_menu_item() { + $hidden_settings_tabs = self::get_network_option( 'hideSettingsTabs', [] ); + if ( in_array( 'help', $hidden_settings_tabs ) ) { + return; + } + + $parent = class_exists( 'Tribe__Events__Main' ) ? Tribe__Settings::$parent_page : Tribe__Settings::$parent_slug; + $title = esc_html__( 'Help', 'tribe-common' ); + $slug = 'tribe-help'; + + add_submenu_page( $parent, $title, $title, 'manage_options', $slug, [ $this, 'do_help_tab' ] ); + } + + /** + * Tries to discover if licensable addons are activated on the same site. + * + * @return bool + */ + protected function have_addons() { + $addons = apply_filters( 'tribe_licensable_addons', [] ); + + return ! empty( $addons ); + } + + /** + * Save hidden tabs + * + * @return void + */ + public function save_all_tabs_hidden() { + $all_tabs_keys = array_keys( apply_filters( 'tribe_settings_all_tabs', [] ) ); + + $network_options = (array) get_site_option( Tribe__Main::OPTIONNAMENETWORK ); + + if ( isset( $_POST['hideSettingsTabs'] ) && $_POST['hideSettingsTabs'] == $all_tabs_keys ) { + $network_options['allSettingsTabsHidden'] = '1'; + } else { + $network_options['allSettingsTabsHidden'] = '0'; + } + + $this->set_network_options( $network_options ); + } + + /** + * Static Singleton Factory Method + * + * @return Tribe__Settings_Manager + */ + public static function instance() { + return tribe( 'settings.manager' ); + } +} diff --git a/tribe-common/src/Tribe/Settings_Tab.php b/tribe-common/src/Tribe/Settings_Tab.php new file mode 100755 index 0000000000..11e15a5aad --- /dev/null +++ b/tribe-common/src/Tribe/Settings_Tab.php @@ -0,0 +1,227 @@ +defaults = [ + 'fields' => [], + 'priority' => 50, + 'show_save' => true, + 'display_callback' => false, + 'network_admin' => false, + ]; + + // parse args with defaults + $this->args = wp_parse_args( $args, $this->defaults ); + + // set each instance variable and filter + $this->id = apply_filters( 'tribe_settings_tab_id', $id ); + $this->name = apply_filters( 'tribe_settings_tab_name', $name ); + foreach ( $this->defaults as $key => $value ) { + $this->{$key} = apply_filters( 'tribe_settings_tab_' . $key, $this->args[ $key ], $id ); + } + + // run actions & filters + if ( ! $this->network_admin ) { + add_filter( 'tribe_settings_all_tabs', [ $this, 'addAllTabs' ] ); + } + add_filter( 'tribe_settings_tabs', [ $this, 'addTab' ], $this->priority ); + } + + /** + * filters the tabs array from Tribe__Settings + * and adds the current tab to it + * does not add a tab if it's empty + * + * @param array $tabs the $tabs from Tribe__Settings + * + * @return array $tabs the filtered tabs + */ + public function addTab( $tabs ) { + $hideSettingsTabs = Tribe__Settings_Manager::get_network_option( 'hideSettingsTabs', [] ); + if ( ( isset( $this->fields ) || has_action( 'tribe_settings_content_tab_' . $this->id ) ) && ( empty( $hideSettingsTabs ) || ! in_array( $this->id, $hideSettingsTabs ) ) ) { + if ( ( is_network_admin() && $this->args['network_admin'] ) || ( ! is_network_admin() && ! $this->args['network_admin'] ) ) { + $tabs[ $this->id ] = $this->name; + add_filter( 'tribe_settings_fields', [ $this, 'addFields' ] ); + add_filter( 'tribe_settings_no_save_tabs', [ $this, 'showSaveTab' ] ); + add_filter( 'tribe_settings_content_tab_' . $this->id, [ $this, 'doContent' ] ); + } + } + + return $tabs; + } + + /** + * Adds this tab to the list of total tabs, even if it is not displayed. + * + * @param array $allTabs All the tabs from Tribe__Settings. + * + * @return array $allTabs All the tabs. + */ + public function addAllTabs( $allTabs ) { + $allTabs[ $this->id ] = $this->name; + + return $allTabs; + } + + + /** + * filters the fields array from Tribe__Settings + * and adds the current tab's fields to it + * + * @param array $field the $fields from Tribe__Settings + * + * @return array $fields the filtered fields + */ + public function addFields( $fields ) { + if ( ! empty ( $this->fields ) ) { + $fields[ $this->id ] = $this->fields; + } elseif ( has_action( 'tribe_settings_content_tab_' . $this->id ) ) { + $fields[ $this->id ] = $this->fields = [ 0 => null ]; // just to trick it + } + + return $fields; + } + + /** + * sets whether the current tab should show the save + * button or not + * + * @param array $noSaveTabs the $noSaveTabs from Tribe__Settings + * + * @return array $noSaveTabs the filtered non saving tabs + */ + public function showSaveTab( $noSaveTabs ) { + if ( ! $this->show_save || empty( $this->fields ) ) { + $noSaveTabs[ $this->id ] = $this->id; + } + + return $noSaveTabs; + } + + /** + * displays the content for the tab + * + * @return void + */ + public function doContent() { + if ( $this->display_callback && is_callable( $this->display_callback ) ) { + call_user_func( $this->display_callback ); + + return; + } + + $sent_data = get_option( 'tribe_settings_sent_data', [] ); + + if ( is_array( $this->fields ) && ! empty( $this->fields ) ) { + foreach ( $this->fields as $key => $field ) { + if ( isset( $sent_data[ $key ] ) ) { + // If we just saved [or attempted to], get the value that was input. + $value = $sent_data[ $key ]; + } else { + // Some options should always be stored at network level + $network_option = isset( $field['network_option'] ) ? (bool) $field['network_option'] : false; + + if ( is_network_admin() ) { + $parent_option = ( isset( $field['parent_option'] ) ) ? $field['parent_option'] : Tribe__Main::OPTIONNAMENETWORK; + } + if ( ! is_network_admin() ) { + $parent_option = ( isset( $field['parent_option'] ) ) ? $field['parent_option'] : Tribe__Main::OPTIONNAME; + } + // get the field's parent_option in order to later get the field's value + $parent_option = apply_filters( 'tribe_settings_do_content_parent_option', $parent_option, $key ); + $default = ( isset( $field['default'] ) ) ? $field['default'] : null; + $default = apply_filters( 'tribe_settings_field_default', $default, $field ); + + if ( ! $parent_option ) { + // no parent option, get the straight up value + if ( $network_option || is_network_admin() ) { + $value = get_site_option( $key, $default ); + } else { + $value = get_option( $key, $default ); + } + } else { + // there's a parent option + if ( $parent_option == Tribe__Main::OPTIONNAME ) { + // get the options from Tribe__Settings_Manager if we're getting the main array + $value = Tribe__Settings_Manager::get_option( $key, $default ); + } elseif ( $parent_option == Tribe__Main::OPTIONNAMENETWORK ) { + $value = Tribe__Settings_Manager::get_network_option( $key, $default ); + } else { + // else, get the parent option normally + if ( is_network_admin() ) { + $options = (array) get_site_option( $parent_option ); + } else { + $options = (array) get_option( $parent_option ); + } + $value = ( isset( $options[ $key ] ) ) ? $options[ $key ] : $default; + } + } + } + + // escape the value for display + if ( ! empty( $field['esc_display'] ) && function_exists( $field['esc_display'] ) ) { + $value = $field['esc_display']( $value ); + } elseif ( is_string( $value ) ) { + $value = esc_attr( stripslashes( $value ) ); + } + + // filter the value + $value = apply_filters( 'tribe_settings_get_option_value_pre_display', $value, $key, $field ); + + // create the field + new Tribe__Field( $key, $field, $value ); + } + } else { + // no fields setup for this tab yet + echo '

          ' . esc_html__( 'There are no fields setup for this tab yet.', 'tribe-common' ) . '

          '; + } + } + + } // end class +} // endif class_exists diff --git a/tribe-common/src/Tribe/Shortcode/Manager.php b/tribe-common/src/Tribe/Shortcode/Manager.php new file mode 100644 index 0000000000..0dabc730bc --- /dev/null +++ b/tribe-common/src/Tribe/Shortcode/Manager.php @@ -0,0 +1,182 @@ + => ]` + */ + public function get_registered_shortcodes() { + $shortcodes = []; + + /** + * Allow the registering of shortcodes into the our Tribe plugins. + * + * @since 4.12.0 + * + * @var array An associative array of shortcodes in the shape `[ => ]`. + */ + $shortcodes = apply_filters( 'tribe_shortcodes', $shortcodes ); + + return $shortcodes; + } + + /** + * Verifies if a given shortcode slug is registered for handling. + * + * @since 4.12.0 + * + * @param string $slug Which slug we are checking if is registered. + * + * @return bool Whether a shortcode is registered or not. + */ + public function is_shortcode_registered( $slug ) { + $registered_shortcodes = $this->get_registered_shortcodes(); + return isset( $registered_shortcodes[ $slug ] ); + } + + /** + * Verifies if a given shortcode class name is registered for handling. + * + * @since 4.12.0 + * + * @param string $class_name Which class name we are checking if is registered. + * + * @return bool Whether a shortcode is registered, by class. + */ + public function is_shortcode_registered_by_class( $class_name ) { + $registered_shortcodes = $this->get_registered_shortcodes(); + return in_array( $class_name, $registered_shortcodes ); + } + + /** + * Add new shortcodes handler to catch the correct strings. + * + * @since 4.12.0 + */ + public function add_shortcodes() { + $registered_shortcodes = $this->get_registered_shortcodes(); + + // Add to WordPress all of the registered Shortcodes + foreach ( $registered_shortcodes as $shortcode => $class_name ) { + add_shortcode( $shortcode, [ $this, 'render_shortcode' ] ); + } + } + + /** + * Makes sure we are correctly handling the Shortcodes we manage. + * + * @since 4.12.0 + * + * @param array $arguments Set of arguments passed to the Shortcode at hand. + * @param string $content Contents passed to the shortcode, inside of the open and close brackets. + * @param string $shortcode Which shortcode tag are we handling here. + * + * @return string The rendered shortcode HTML. + */ + public function render_shortcode( $arguments, $content, $shortcode ) { + $registered_shortcodes = $this->get_registered_shortcodes(); + + // Bail when we try to handle an unregistered shortcode (shouldn't happen) + if ( ! $this->is_shortcode_registered( $shortcode ) ) { + return false; + } + + /** @var Shortcode_Interface $instance */ + $instance = new $registered_shortcodes[ $shortcode ]; + $instance->setup( $arguments, $content ); + + return $instance->get_html(); + } + + /** + * Filter `pre_do_shortcode_tag` to add the current shortcode. + * + * @since 4.12.9 + * + * @param bool|string $return Short-circuit return value. Either false or the value to replace the shortcode with. + * @param string $tag Shortcode name. + * @param array $attr Shortcode attributes array, + * @param array $m Regular expression match array. + * + * @return bool|string Short-circuit return value. + */ + public function filter_pre_do_shortcode_tag( $return, $tag, $attr, $m ) { + if ( ! $this->is_shortcode_registered( $tag ) ) { + return $return; + } + + // Add to the doing shortcode. + $this->current_shortcode[] = $tag; + + return $return; + } + + /** + * Filter `do_shortcode_tag` to remove the shortcode from the `$tribe_current_shortcode` list. + * + * @since 4.12.9 + * + * @param string $output Shortcode output. + * @param string $tag Shortcode name. + * @param array|string $attr Shortcode attributes array or empty string. + * @param array $m Regular expression match array. + * + * @return string Shortcode output. + */ + public function filter_do_shortcode_tag( $output, $tag, $attr, $m ) { + if ( ! $this->is_shortcode_registered( $tag ) ) { + return $output; + } + + if ( isset( $this->current_shortcode[ $tag ] ) ) { + unset( $this->current_shortcode[ $tag ] ); + } + + return $output; + } + + /** + * Check if a shortcode is being done. + * + * @since 4.12.9 + * + * @param null|string $tag The shortcode tag name, or null to check if doing any shortcode. + * + * @return bool If the shortcode is being done or not. + */ + public function is_doing_shortcode( $tag = null ) { + if ( null === $tag ) { + return ! empty( $this->current_shortcode ); + } + + return in_array( $tag, $this->current_shortcode, true ); + } +} diff --git a/tribe-common/src/Tribe/Shortcode/Shortcode_Abstract.php b/tribe-common/src/Tribe/Shortcode/Shortcode_Abstract.php new file mode 100644 index 0000000000..d855760fbd --- /dev/null +++ b/tribe-common/src/Tribe/Shortcode/Shortcode_Abstract.php @@ -0,0 +1,254 @@ + 'canonical', 'from' => 'to', 'that' => 'becomes_this' ] + * Example shortcode usage: [some_tag alias=17 to='Fred'] will be parsed as [some_tag canonical=17 to='Fred'] + * + * @since 4.12.2 + * + * @var array + */ + protected $aliased_arguments = []; + + /** + * Array of callbacks for arguments validation. + * + * @since 4.12.0 + * + * @var array + */ + protected $validate_arguments_map = []; + + /** + * Arguments of the current shortcode. + * + * @since 4.12.0 + * + * @var array + */ + protected $arguments; + + /** + * Content of the current shortcode. + * + * @since 4.12.0 + * + * @var string + */ + protected $content; + + /** + * {@inheritDoc} + */ + public function setup( $arguments, $content ) { + $this->arguments = $this->parse_arguments( (array) $arguments ); + $this->content = $content; + } + + /** + * {@inheritDoc} + */ + public function set_aliased_arguments( array $alias_map ) { + $this->aliased_arguments = Arr::filter_to_flat_scalar_associative_array( (array) $alias_map ); + } + + /** + * {@inheritDoc} + */ + public function get_aliased_arguments() { + return $this->aliased_arguments; + } + + /** + * {@inheritDoc} + */ + public function parse_arguments( array $arguments ) { + $arguments = Arr::parse_associative_array_alias( (array) $arguments, (array) $this->get_aliased_arguments() ); + $arguments = shortcode_atts( $this->get_default_arguments(), $arguments, $this->slug ); + + return $this->validate_arguments( $arguments ); + } + + /** + * {@inheritDoc} + */ + public function validate_arguments( array $arguments ) { + $validate_arguments_map = $this->filter_validated_arguments_map( $this->get_validated_arguments_map() ); + foreach ( $validate_arguments_map as $key => $callback ) { + $arguments[ $key ] = $callback( isset( $arguments[ $key ] ) ? $arguments[ $key ] : null ); + } + + return $arguments; + } + + /** + * {@inheritDoc} + */ + public function get_registration_slug() { + return $this->slug; + } + + /** + * {@inheritDoc} + */ + public function get_validated_arguments_map() { + return $this->validate_arguments_map; + } + + /** + * {@inheritDoc} + */ + public function filter_validated_arguments_map( $validate_arguments_map ) { + /** + * Applies a filter to instance arguments validation callbacks. + * + * @since 4.12.0 + * + * @param array $validate_arguments_map Current set of callbacks for arguments. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $validate_arguments_map = apply_filters( 'tribe_shortcode_validate_arguments_map', $validate_arguments_map, $this ); + + $registration_slug = $this->get_registration_slug(); + + /** + * Applies a filter to instance arguments validation callbacks based on the registration slug of the shortcode. + * + * @since 4.12.0 + * + * @param array $validate_arguments_map Current set of callbacks for arguments. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $validate_arguments_map = apply_filters( "tribe__shortcode_{$registration_slug}_validate_arguments_map", $validate_arguments_map, $this ); + + return $validate_arguments_map; + } + + /** + * {@inheritDoc} + */ + public function get_arguments() { + /** + * Applies a filter to instance arguments. + * + * @since 4.12.0 + * + * @param array $arguments Current set of arguments. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $arguments = apply_filters( 'tribe_shortcode_arguments', $this->arguments, $this ); + + $registration_slug = $this->get_registration_slug(); + + /** + * Applies a filter to instance arguments based on the registration slug of the shortcode. + * + * @since 4.12.0 + * + * @param array $arguments Current set of arguments. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $arguments = apply_filters( "tribe_shortcode_{$registration_slug}_arguments", $arguments, $this ); + + return $arguments; + } + + /** + * {@inheritDoc} + */ + public function get_argument( $index, $default = null ) { + $arguments = $this->get_arguments(); + $argument = Arr::get( $arguments, $index, $default ); + + /** + * Applies a filter to a specific shortcode argument, catch all for all shortcodes. + * + * @since 4.12.0 + * + * @param mixed $argument The argument. + * @param array $index Which index we indent to fetch from the arguments. + * @param array $default Default value if it doesn't exist. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $argument = apply_filters( 'tribe_shortcode_argument', $argument, $index, $default, $this ); + + $registration_slug = $this->get_registration_slug(); + + /** + * Applies a filter to a specific shortcode argument, to a particular registration slug. + * + * @since 4.12.0 + * + * @param mixed $argument The argument value. + * @param array $index Which index we indent to fetch from the arguments. + * @param array $default Default value if it doesn't exist. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $argument = apply_filters( "tribe_shortcode_{$registration_slug}_argument", $argument, $index, $default, $this ); + + return $argument; + } + + /** + * {@inheritDoc} + */ + public function get_default_arguments() { + /** + * Applies a filter to instance default arguments. + * + * @since 4.12.0 + * + * @param array $default_arguments Current set of default arguments. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $default_arguments = apply_filters( 'tribe_shortcode_default_arguments', $this->default_arguments, $this ); + + $registration_slug = $this->get_registration_slug(); + + /** + * Applies a filter to instance default arguments based on the registration slug of the shortcode. + * + * @since 4.12.0 + * + * @param array $default_arguments Current set of default arguments. + * @param static $instance Which instance of shortcode we are dealing with. + */ + $default_arguments = apply_filters( "tribe_shortcode_{$registration_slug}_default_arguments", $default_arguments, $this ); + + return $default_arguments; + } + +} diff --git a/tribe-common/src/Tribe/Shortcode/Shortcode_Interface.php b/tribe-common/src/Tribe/Shortcode/Shortcode_Interface.php new file mode 100644 index 0000000000..ca3e77a7f1 --- /dev/null +++ b/tribe-common/src/Tribe/Shortcode/Shortcode_Interface.php @@ -0,0 +1,125 @@ + 'canonical', 'from' => 'to', 'that' => 'becomes_this' ] + */ + public function set_aliased_arguments( array $alias_map ); + + /** + * Gets the aliased arguments array. + * + * @since 4.12.2 + * + * @return array The associative array map of aliases and their canonical arguments. + */ + public function get_aliased_arguments(); + + /** + * Returns the arguments for the shortcode parsed correctly with defaults applied. + * + * @since 4.12.0 + * + * @param array $arguments Set of arguments passed to the Shortcode at hand. + * + * @return array The parsed shortcode arguments map. + */ + public function parse_arguments( array $arguments ); + + /** + * Returns the array of arguments for this shortcode after applying the validation callbacks. + * + * @since 4.12.0 + * + * @param array $arguments Set of arguments passed to the Shortcode at hand. + * + * @return array The validated shortcode arguments map. + */ + public function validate_arguments( array $arguments ); + + /** + * Returns the array of callbacks for this shortcode's arguments. + * + * @since 4.12.0 + * + * @return array A map of the shortcode arguments that have survived validation. + */ + public function get_validated_arguments_map(); + + /** + * Returns a shortcode default arguments. + * + * @since 4.12.0 + * + * @return array The shortcode default arguments map. + */ + public function get_default_arguments(); + + /** + * Returns a shortcode arguments after been parsed. + * + * @since 4.12.0 + * + * @return array The shortcode arguments, as set by the user in the shortcode string. + */ + public function get_arguments(); + + /** + * Returns a shortcode argument after it has been parsed. + * + * @since 4.12.0 + * + * @param array|string $index Which index we indent to fetch from the arguments. + * @param array $default Default value if it doesn't exist. + * + * @uses Tribe__Utils__Array::get For index fetching and Default. + * + * @return mixed Value for the Index passed as the first argument. + */ + public function get_argument( $index, $default = null ); + + /** + * Returns a shortcode's HTML. + * + * @since 4.12.0 + * + * @return string The shortcode rendered HTML code. + */ + public function get_html(); +} diff --git a/tribe-common/src/Tribe/Shortcode/Utils.php b/tribe-common/src/Tribe/Shortcode/Utils.php new file mode 100644 index 0000000000..9584f53dfe --- /dev/null +++ b/tribe-common/src/Tribe/Shortcode/Utils.php @@ -0,0 +1,45 @@ + $settings Widget settings. + * @param array $allowed Allowed settings for shortcode. + * + * @return string Shortcode attributes string. + */ + public static function get_attributes_string( $settings, $allowed = [] ) { + $settings_string = ''; + + $allowed = array_flip( $allowed ); + + foreach ( $settings as $key => $value ) { + if ( ! empty( $allowed ) && ! isset( $allowed[ $key ] ) ) { + continue; + } + + $key = esc_attr( $key ); + + if ( is_array( $value ) ) { + $value = implode( ', ', $value ); + } + + $value = esc_attr( $value ); + + $settings_string .= " {$key}=\"{$value}\""; + } + + return $settings_string; + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Simple_Table.php b/tribe-common/src/Tribe/Simple_Table.php new file mode 100644 index 0000000000..4c3e2ec08c --- /dev/null +++ b/tribe-common/src/Tribe/Simple_Table.php @@ -0,0 +1,166 @@ + 'tribe_table', 'border' => '0' ); + */ + public $table_attributes; + public $tr_attributes; + public $th_attributes; + public $td_attributes; + + /** + * Will HTML escape all table cells + * + * @var bool + */ + public $html_escape_td_values = true; + + /** + * Tribe__Simple_Table constructor. + * + * @param array $tbody Multidimension array containing table rows/columns + * @param array $thead Single dimension array containing table headings + */ + public function __construct( $tbody, $thead = [] ) { + $this->thead = $thead; + $this->tbody = $tbody; + } + + /** + * @param bool $vertical Whether heading appears vertically (above) data or horizontally (to the side) + * + * @return string HTML table + */ + public function output_table( $vertical = true ) { + + if ( $vertical ) { + return $this->output_table_vertical(); + } else { + return $this->output_table_horizontal(); + } + } + + /** + * Outputs table with heading above data + * + * @return string HTML table + */ + private function output_table_vertical() { + + $table_contents = ''; + + // Create thead + if ( ! empty( $this->thead ) ) { + foreach ( $this->thead as $th ) { + $table_contents .= $this->output_element( 'th', $th, $this->th_attributes ); + } + $table_contents = $this->output_element( 'tr', $table_contents, $this->tr_attributes ); + } + + // Create tbody + foreach ( $this->tbody as $tr ) { + $tr_str = ''; + + foreach ( $tr as $td ) { + $tr_str .= $this->output_element( 'td', $td, $this->td_attributes ); + } + + $table_contents .= $this->output_element( 'tr', $tr_str, $this->tr_attributes ); + } + + // Wrap it all up in a table + $output = $this->output_element( 'table', $table_contents, $this->table_attributes ); + + return $output; + } + + /** + * Outputs table with heading to the left of the data + * + * @return string HTML table + */ + private function output_table_horizontal() { + + $table_contents = ''; + + // Finds the table row with the most columns + $max_col = isset( $this->thead ) ? count( $this->thead ) : 1; + foreach ( $this->tbody as $table_item ) { + if ( $max_col < count( $table_item ) ) { + $max_col = count( $table_item ); + } + } + + // Create table rows + for ( $i = 0; $i < $max_col; $i++ ) { + $tr_contents = ''; + + // row heading + if ( isset( $this->thead[ $i ] ) ) { + $tr_contents .= $this->output_element( 'th', $this->thead[ $i ], $this->th_attributes ); + } + + // columns + foreach ( $this->tbody as $table_item ) { + if ( ! isset( $table_item[ $i ] ) ) { + continue; + } + $tr_contents .= $this->output_element( 'td', $table_item[ $i ], $this->td_attributes ); + } + + $table_contents .= $this->output_element( 'tr', $tr_contents, $this->tr_attributes ); + } + + // Wrap it all up in a table + $output = $this->output_element( 'table', $table_contents, $this->table_attributes ); + + return $output; + } + + /** + * Outputs an HTML element, mostly useful for elements that have attributes + * + * @param string $html_tag HTML element name. Example: 'table' + * @param string $data Text/HTML contained inside of the element + * @param array $attributes HTML attributes for element + * + * @return string HTML element + */ + private function output_element( $html_tag, $data = null, $attributes = [] ) { + $output = '<' . tag_escape( $html_tag ); + + if ( ! empty( $attributes ) ) { + foreach ( $attributes as $att => $val ) { + $output .= ' ' . $att . '="' . esc_attr( $val ) . '"'; + } + } + + if ( is_string( $data ) ) { + $output .= '>'; + $output .= ( 'td' === $html_tag && $this->html_escape_td_values ) ? esc_html( $data ) : $data; + $output .= ''; + } else { + $output .= ' />'; + } + + return $output; + } + +} diff --git a/tribe-common/src/Tribe/Support.php b/tribe-common/src/Tribe/Support.php new file mode 100755 index 0000000000..3f94018591 --- /dev/null +++ b/tribe-common/src/Tribe/Support.php @@ -0,0 +1,467 @@ +must_escape = (array) apply_filters( 'tribe_help_must_escape_fields', $this->must_escape ); + + add_action( 'tribe_help_pre_get_sections', [ $this, 'append_system_info' ], 10 ); + add_action( 'delete_option_rewrite_rules', [ $this, 'log_rewrite_rule_purge' ] ); + + add_action( 'rest_api_init', [ __CLASS__, 'create_sysinfo_endpoint' ] ); + add_action( 'wp_ajax_tribe_toggle_sysinfo_optin', [ __CLASS__, 'ajax_sysinfo_optin' ] ); + } + + /** + * Display help tab info in events settings + * + * @param Tribe__Admin__Help_Page $help The Help Page Instance + */ + public function append_system_info( Tribe__Admin__Help_Page $help ) { + $help->add_section_content( 'system-info', $this->formattedSupportStats(), 10 ); + } + + /** + * Collect system information for support + * + * @return array of system data for support + */ + public function getSupportStats() { + global $wpdb; + $user = wp_get_current_user(); + + $plugins = []; + if ( function_exists( 'get_plugin_data' ) ) { + $plugins_raw = wp_get_active_and_valid_plugins(); + foreach ( $plugins_raw as $k => $v ) { + $plugin_details = get_plugin_data( $v ); + $plugin = $plugin_details['Name']; + if ( ! empty( $plugin_details['Version'] ) ) { + $plugin .= sprintf( ' version %s', $plugin_details['Version'] ); + } + if ( ! empty( $plugin_details['Author'] ) ) { + $plugin .= sprintf( ' by %s', $plugin_details['Author'] ); + } + if ( ! empty( $plugin_details['AuthorURI'] ) ) { + $plugin .= sprintf( ' (%s)', $plugin_details['AuthorURI'] ); + } + $plugins[] = $plugin; + } + } + + $network_plugins = []; + if ( is_multisite() && function_exists( 'get_plugin_data' ) ) { + $plugins_raw = wp_get_active_network_plugins(); + foreach ( $plugins_raw as $k => $v ) { + $plugin_details = get_plugin_data( $v ); + $plugin = $plugin_details['Name']; + if ( ! empty( $plugin_details['Version'] ) ) { + $plugin .= sprintf( ' version %s', $plugin_details['Version'] ); + } + if ( ! empty( $plugin_details['Author'] ) ) { + $plugin .= sprintf( ' by %s', $plugin_details['Author'] ); + } + if ( ! empty( $plugin_details['AuthorURI'] ) ) { + $plugin .= sprintf( ' (%s)', $plugin_details['AuthorURI'] ); + } + $network_plugins[] = $plugin; + } + } + + $mu_plugins = []; + if ( function_exists( 'get_mu_plugins' ) ) { + $mu_plugins_raw = get_mu_plugins(); + foreach ( $mu_plugins_raw as $k => $v ) { + $plugin = $v['Name']; + if ( ! empty( $v['Version'] ) ) { + $plugin .= sprintf( ' version %s', $v['Version'] ); + } + if ( ! empty( $v['Author'] ) ) { + $plugin .= sprintf( ' by %s', $v['Author'] ); + } + if ( ! empty( $v['AuthorURI'] ) ) { + $plugin .= sprintf( ' (%s)', $v['AuthorURI'] ); + } + $mu_plugins[] = $plugin; + } + } + + $keys = apply_filters( 'tribe-pue-install-keys', [] ); + //Obfuscate the License Keys for Security + if ( is_array( $keys ) && ! empty( $keys ) ) { + $secure_keys = []; + foreach ( $keys as $plugin => $license ) { + $secure_keys[ $plugin ] = preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', 32 ) . '$2', $license ); + } + $keys = $secure_keys; + } + + //Server + $server = explode( ' ', $_SERVER['SERVER_SOFTWARE'] ); + $server = explode( '/', reset( $server ) ); + + //PHP Information + $php_info = []; + $php_vars = [ + 'max_execution_time', + 'memory_limit', + 'upload_max_filesize', + 'post_max_size', + 'display_errors', + 'log_errors', + ]; + + foreach ( $php_vars as $php_var ) { + if ( isset( $wpdb->qm_php_vars ) && isset( $wpdb->qm_php_vars[ $php_var ] ) ) { + $val = $wpdb->qm_php_vars[ $php_var ]; + } else { + $val = ini_get( $php_var ); + } + $php_info[ $php_var ] = $val; + } + + $homepage = get_option( 'show_on_front' ); + $homepage_page_id = get_option( 'page_on_front' ); + + if ( 'page' === $homepage ) { + if ( -10 === (int) $homepage_page_id ) { + $homepage_page_id .= ' (Main Events Page)'; + } else { + $homepage_page_id .= ' (' . esc_html( get_the_title( $homepage_page_id ) ) . ')'; + } + } + + $site_url = get_site_url(); + $systeminfo = [ + 'Home URL' => get_home_url(), + 'Site URL' => $site_url, + 'Site Language' => get_option( 'WPLANG' ) ? get_option( 'WPLANG' ) : esc_html__( 'English', 'tribe-common' ), + 'Character Set' => get_option( 'blog_charset' ), + 'Name' => $user->display_name, + 'Email' => $user->user_email, + 'Install keys' => $keys, + 'WordPress version' => get_bloginfo( 'version' ), + 'Permalink Structure' => $site_url . get_option( 'permalink_structure' ), + 'Your homepage displays' => $homepage, + 'Homepage page ID' => $homepage_page_id, + 'PHP version' => phpversion(), + 'PHP' => $php_info, + 'Server' => $server[0], + 'SAPI' => php_sapi_name(), + 'Plugins' => $plugins, + 'Network Plugins' => $network_plugins, + 'MU Plugins' => $mu_plugins, + 'Theme' => wp_get_theme()->get( 'Name' ), + 'Multisite' => is_multisite(), + 'Settings' => Tribe__Settings_Manager::get_options(), + 'WP Timezone' => get_option( 'timezone_string' ) ? get_option( 'timezone_string' ) : esc_html__( 'Unknown or not set', 'tribe-common' ), + 'WP GMT Offset' => get_option( 'gmt_offset' ) ? ' ' . get_option( 'gmt_offset' ) : esc_html__( 'Unknown or not set', 'tribe-common' ), + 'Default PHP Timezone' => date_default_timezone_get(), + 'WP Date Format' => get_option( 'date_format' ), + 'WP Time Format' => get_option( 'time_format' ), + 'Week Starts On' => get_option( 'start_of_week' ), + 'Common Library Dir' => $GLOBALS['tribe-common-info']['dir'], + 'Common Library Version' => $GLOBALS['tribe-common-info']['version'], + ]; + + if ( $this->rewrite_rules_purged ) { + $systeminfo['rewrite rules purged'] = esc_html__( 'Rewrite rules were purged on load of this help page. Chances are there is a rewrite rule flush occurring in a plugin or theme!', 'tribe-common' ); + } + + /** + * Allow for customization of the array of information that's turned into the "System Information" screen in the "Help" admin page. + * + * @param array $systeminfo The array of information turned into the "System Information" screen. + */ + $systeminfo = apply_filters( 'tribe-events-pro-support', $systeminfo ); + + return $systeminfo; + } + + /** + * Render system information into a pretty output + * + * @return string pretty HTML + */ + public function formattedSupportStats() { + $systeminfo = $this->getSupportStats(); + $output = ''; + $output .= '
          '; + + foreach ( $systeminfo as $k => $v ) { + + switch ( $k ) { + case 'name' : + case 'email' : + continue 2; + break; + case 'url' : + $v = sprintf( '%s', $v, $v ); + break; + } + + if ( is_array( $v ) ) { + $keys = array_keys( $v ); + $key = array_shift( $keys ); + $is_numeric_array = is_numeric( $key ); + unset( $keys ); + unset( $key ); + } + + $output .= sprintf( '
          %s
          ', $k ); + if ( empty( $v ) ) { + $output .= '
          -
          '; + } elseif ( is_bool( $v ) ) { + $output .= sprintf( '
          %s
          ', $v ); + } elseif ( is_string( $v ) ) { + $output .= sprintf( '
          %s
          ', $v ); + } elseif ( is_array( $v ) && $is_numeric_array ) { + $output .= sprintf( '
          • %s
          ', join( '
        • ', $v ) ); + } else { + $formatted_v = []; + foreach ( $v as $obj_key => $obj_val ) { + if ( in_array( $obj_key, $this->must_escape ) ) { + $obj_val = esc_html( $obj_val ); + } + + $obj_val = $this->obfuscator->obfuscate( $obj_key, $obj_val ); + + if ( is_array( $obj_val ) ) { + $formatted_v[] = sprintf( '
        • %s =
          %s
        • ', $obj_key, print_r( $obj_val, true ) ); + } else { + $formatted_v[] = sprintf( '
        • %s = %s
        • ', $obj_key, $obj_val ); + } + } + $v = join( "\n", $formatted_v ); + $output .= sprintf( '
            %s
          ', print_r( $v, true ) ); + } + } + + $output .= '
          '; + + return $output; + } + + /** + * Logs the occurrence of rewrite rule purging + */ + public function log_rewrite_rule_purge() { + $this->rewrite_rules_purged = true; + }//end log_rewrite_rule_purge + + /** + * Sets the obfuscator to be used. + * + * @param Tribe__Support__Obfuscator $obfuscator + */ + public function set_obfuscator( Tribe__Support__Obfuscator $obfuscator ) { + $this->obfuscator = $obfuscator; + } + + /** + * Creates Fields in Help Tab to Opt In to System Info + * + * @return string + */ + public static function opt_in() { + + $checked = ''; + $optin_key = get_option( 'tribe_systeminfo_optin' ); + if ( $optin_key ) { + $checked = 'checked'; + } + + $opt_in = '

          '; + $opt_in .= '

          ' . esc_html__( 'Your system information will only be used by The Events Calendar\'s support team. All information is stored securely. We do not share this information with any third parties.', 'tribe-common' ) . '

          '; + $opt_in .= '

          '; + + return $opt_in; + } + + /** + * Method to send back sysinfo + * + * @param $query + * + * @return string|void + * + */ + public static function sysinfo_query( $query ) { + + $optin_key = get_option( 'tribe_systeminfo_optin' ); + + if ( ! $optin_key ) { + wp_send_json_error( __( 'Invalid Key', 'tribe-common' ) ); + } + + $key = $query['key']; + if ( $key != $optin_key ) { + wp_send_json_error( __( 'Invalid Key', 'tribe-common' ) ); + } + + $support = Tribe__Support::getInstance(); + $systeminfo = $support->formattedSupportStats(); + + return $systeminfo; + } + + /* + * Create Unique Enpoint Per Site + */ + public static function create_sysinfo_endpoint() { + $optin_key = get_option( 'tribe_systeminfo_optin' ); + if ( $optin_key ) { + register_rest_route( + 'tribe_events/v2', + '/(?P[a-z0-9\-]+)/sysinfo/', + [ + 'methods' => 'GET', + 'callback' => [ 'Tribe__Support', 'sysinfo_query' ], + 'permission_callback' => '__return_true', + ] + ); + } + } + + /** + * Ajax Method to Create Unique Key and send to tec.com + */ + public static function ajax_sysinfo_optin() { + + if ( ! isset( $_POST['confirm'] ) || ! wp_verify_nonce( $_POST['confirm'], 'sysinfo_optin_nonce' ) ) { + wp_send_json_error( __( 'Permission Error', 'tribe-common' ) ); + } + + if ( 'generate' == $_POST['generate_key'] ) { + + $random = base_convert( rand( 0, getrandmax() ), 10, 36 ); + $optin_key = hash( 'sha1', $random ); + update_option( 'tribe_systeminfo_optin', $optin_key ); + + //Only Connect If a License Exists + $keys = apply_filters( 'tribe-pue-install-keys', [] ); + if ( is_array( $keys ) && ! empty( $keys ) ) { + Tribe__Support::send_sysinfo_key( $optin_key ); + } else { + wp_send_json_success( __( 'Unique System Info Key Generated', 'tribe-common' ) ); + } + + } elseif ( 'remove' == $_POST['generate_key'] ) { + $optin_key = get_option( 'tribe_systeminfo_optin' ); + + delete_option( 'tribe_systeminfo_optin' ); + + Tribe__Support::send_sysinfo_key( $optin_key, null, 'remove' ); + + } + + wp_send_json_error( __( 'Permission Error', 'tribe-common' ) ); + } + + /** + * Contact Tribe Website to Add SysInfo Key + * + * @param null $optin_key provide key for system info + * @param null $url domain of current site + * @param null $remove string used if removing $optin_key from tec.com + * @param null $pueadd boolean to disable messaging when coming from pue script + */ + public static function send_sysinfo_key( $optin_key = null, $url = null, $remove = null, $pueadd = false ) { + + $url = $url ? $url : urlencode( str_replace( [ 'http://', 'https://' ], '', get_site_url() ) ); + + $teccom_url = 'https://theeventscalendar.com/'; + + if ( defined( 'TEC_URL' ) ) { + $teccom_url = trailingslashit( TEC_URL ); + } + + $query = $teccom_url . 'wp-json/tribe_system/v2/customer-info/' . $optin_key . '/' . $url; + + if ( $remove ) { + $query .= '?status=remove'; + } + + $response = wp_remote_get( esc_url( $query ) ); + + $response = json_decode( wp_remote_retrieve_body( $response ) ); + + if ( ! $pueadd ) { + // make sure the response came back okay + if ( ! isset( $response->success ) ) { + //on error delete the key + delete_option( 'tribe_systeminfo_optin' ); + + //send error response + wp_send_json_error( $response ); + } + + wp_send_json_success( $response->data ); + } + } + + + /****************** SINGLETON GUTS ******************/ + + /** + * Enforce Singleton Pattern + */ + private static $instance; + + + public static function getInstance() { + if ( null == self::$instance ) { + $instance = new self; + $instance->set_obfuscator( new Tribe__Support__Obfuscator( $instance->must_obfuscate_prefixes ) ); + self::$instance = $instance; + } + + return self::$instance; + } + } + +} diff --git a/tribe-common/src/Tribe/Support/Obfuscator.php b/tribe-common/src/Tribe/Support/Obfuscator.php new file mode 100644 index 0000000000..af60e6a594 --- /dev/null +++ b/tribe-common/src/Tribe/Support/Obfuscator.php @@ -0,0 +1,68 @@ +prefixes = $prefixes; + } + + /** + * Whether a value should be obfuscated or not. + * + * @param string $key + * + * @return bool + */ + public function should_obfuscate( $key ) { + foreach ( $this->prefixes as $prefix ) { + if ( strpos( $key, $prefix ) === 0 ) { + return true; + } + } + + return false; + } + + /** + * Conditionally obfuscates a string value. + * + * @param string $key + * @param mixed $string_value + * + * @return mixed Either the obfuscated string or the original value if not a string. + */ + public function obfuscate( $key, $string_value ) { + if ( ! is_string( $string_value ) ) { + return $string_value; + } + if ( ! $this->should_obfuscate( $key ) ) { + return $string_value; + } + + $length = strlen( $string_value ); + if ( $length <= 3 ) { + return preg_replace( "/./", "#", $string_value ); + } elseif ( $length > 3 && $length <= 5 ) { + return preg_replace( '/^(.{1}).*$/', '$1' . str_repeat( '#', $length - 1 ) . '$2', $string_value ); + } elseif ( $length > 5 && $length <= 9 ) { + return preg_replace( '/^(.{1}).*(.{1})$/', '$1' . str_repeat( '#', $length - 2 ) . '$2', $string_value ); + } elseif ( $length > 9 && $length <= 19 ) { + return preg_replace( '/^(.{2}).*(.{2})$/', '$1' . str_repeat( '#', $length - 4 ) . '$2', $string_value ); + } elseif ( $length > 19 && $length <= 31 ) { + return preg_replace( '/^(.{3}).*(.{3})$/', '$1' . str_repeat( '#', $length - 6 ) . '$2', $string_value ); + } + + return preg_replace( '/^(.{4}).*(.{4})$/', '$1' . str_repeat( '#', $length - 8 ) . '$2', $string_value ); + } +} diff --git a/tribe-common/src/Tribe/Support/Template_Checker.php b/tribe-common/src/Tribe/Support/Template_Checker.php new file mode 100644 index 0000000000..4bbad8789c --- /dev/null +++ b/tribe-common/src/Tribe/Support/Template_Checker.php @@ -0,0 +1,275 @@ +plugin_version = $this->base_version_number( $plugin_version ); + $this->plugin_views_dir = $plugin_views_dir; + $this->theme_views_dir = $theme_views_dir; + + $this->scan_view_directory(); + $this->scan_for_overrides(); + } + + /** + * Given a version number with an alpha/beta type suffix, strips that suffix and + * returns the "base" version number. + * + * For example, given "9.8.2beta1" this method will return "9.8.2". + * + * The utility of this is that if the author of a template change sets the + * version tag in the template header to 9.8.2 (to continue the same example) we + * don't need to worry about updating that for each alpha, beta or RC we put out. + * + * @param string $version_number + * + * @return string + */ + protected function base_version_number( $version_number ) { + return preg_replace( '/[a-z]+[a-z0-9]*$/i', '', $version_number ); + } + + /** + * Recursively scans the plugin's view directory and examines the template headers + * of each file it finds within. + */ + protected function scan_view_directory() { + // If the provided directory is invalid flag the problem and go no further + if ( $this->bad_directory( $this->plugin_views_dir ) ) { + return; + } + + $view_directory = new RecursiveDirectoryIterator( $this->plugin_views_dir ); + $directory_list = new RecursiveIteratorIterator( $view_directory ); + + foreach ( $directory_list as $file ) { + $this->scan_view( $file ); + } + } + + /** + * Scans an individual view file, adding it's version number (if found) to the + * $this->views array. + * + * @param SplFileInfo $file + */ + protected function scan_view( SplFileInfo $file ) { + if ( ! $file->isFile() || ! $file->isReadable() ) { + return; + } + + $version = $this->get_template_version( $file->getPathname() ); + $this->originals[ $this->short_name( $file->getPathname() ) ] = $version; + } + + protected function scan_for_overrides() { + // If the provided directory is invalid flag the problem and go no further + if ( $this->bad_directory( $this->theme_views_dir ) ) { + return; + } + + foreach ( $this->originals as $view_file => $current_version ) { + $override_path = trailingslashit( $this->theme_views_dir ) . $view_file; + + if ( ! is_file( $override_path ) || ! is_readable( $override_path ) ) { + continue; + } + + $this->overrides[ $view_file ] = $this->get_template_version( $override_path ); + } + } + + /** + * Tests to ensure the provided view directory path is invalid or unreadable. + * + * @param string $directory + * @return bool + */ + protected function bad_directory( $directory ) { + if ( is_dir( $directory ) && is_readable( $directory ) ) { + return false; + } + + return true; + } + + /** + * Inspects the template header block within the specified file and extracts the + * version number, if one can be found. + * + * @param string $template_filepath + * @return string + */ + protected function get_template_version( $template_filepath ) { + if ( ! is_file( $template_filepath ) || ! is_readable( $template_filepath ) ) { + return ''; + } + + $view_content = file_get_contents( $template_filepath ); + + if ( ! preg_match( '/^\s*\*\s*@version\s*([0-9\.]+)/mi', $view_content, $matches ) ) { + return ''; + } + + return $matches[1]; + } + + /** + * Given a full filepath (ie, to a view file), chops off the base path found + * in $this->plugin_views_dir. + * + * For example, given: + * + * $this->plugin_views_dir = '/srv/project/wp-content/plugins/my-plugin/views' + * $full_filepath = '/srv/project/wp-content/plugins/my-plugin/views/modules/icon.php' + * + * Returns: + * + * 'modules/icon.php' + * + * @param string $full_filepath + * @return string + */ + protected function short_name( $full_filepath ) { + if ( 0 === strpos( $full_filepath, $this->plugin_views_dir ) ) { + return trim( substr( $full_filepath, strlen( $this->plugin_views_dir ) ), DIRECTORY_SEPARATOR ); + } + + return $full_filepath; + } + + /** + * Returns an array of the plugin's shipped view files, where each key is the + * view filename and the value is the version it was last updated. + * + * @return array + */ + public function get_views() { + return $this->originals; + } + + /** + * Returns an array of any or all of the plugin's shipped view files that contain + * a version field in their header blocks. + * + * @see $this->get_views() for format of returned array + * + * @return array + */ + public function get_versioned_views() { + $versioned_views = []; + + foreach ( $this->originals as $key => $version ) { + if ( ! empty( $version ) ) { + $versioned_views[ $key ] = $version; + } + } + + return $versioned_views; + } + + /** + * Returns an array of any shipped plugin views that were updated or introduced + * with the current release (as specified by $this->plugin_version). + * + * @see $this->get_views() for format of returned array + * + * @return array + */ + public function get_views_tagged_this_release() { + $currently_tagged_views = []; + + foreach ( $this->get_versioned_views() as $key => $version ) { + if ( $version === $this->plugin_version ) { + $currently_tagged_views[ $key ] = $version; + } + } + + return $currently_tagged_views; + } + + /** + * Returns an array of theme overrides, where each key is the view filename and the + * value is the version it was last updated (may be empty). + * + * @return array + */ + public function get_overrides() { + return $this->overrides; + } + + /** + * Returns an array of any or all theme overrides that contain a version field in their + * header blocks. + * + * @see $this->get_overrides() for format of returned array + * + * @return array + */ + public function get_versioned_overrides() { + $versioned_views = []; + + foreach ( $this->overrides as $key => $version ) { + if ( ! empty( $version ) ) { + $versioned_views[ $key ] = $version; + } + } + + return $versioned_views; + } + + /** + * Returns an array of any or all theme overrides that seem to be based on an earlier + * version than that which currently ships with the plugin. + * + * If optional param $include_unknown is set to true, the list will include theme + * overrides where the version could not be determined (for instance, this might result + * in theme overrides where the template header - or version tag - was removed being + * included). + * + * @see $this->get_overrides() for format of returned array + * + * @param bool $include_unknown = false + * @return array + */ + public function get_outdated_overrides( $include_unknown = false ) { + $outdated = []; + $originals = $this->get_versioned_views(); + + $overrides = $include_unknown + ? $this->get_overrides() + : $this->get_versioned_overrides(); + + foreach ( $overrides as $view => $override_version ) { + if ( empty( $originals[ $view ] ) ) { + continue; + } + + $shipped_version = $originals[ $view ]; + + if ( version_compare( $shipped_version, $override_version, '>' ) ) { + $outdated[ $view ] = $override_version; + } + } + + return $outdated; + } +} diff --git a/tribe-common/src/Tribe/Support/Template_Checker_Report.php b/tribe-common/src/Tribe/Support/Template_Checker_Report.php new file mode 100644 index 0000000000..87545f41be --- /dev/null +++ b/tribe-common/src/Tribe/Support/Template_Checker_Report.php @@ -0,0 +1,119 @@ + $plugin_template_system ) { + self::generate_for( $plugin_name, $plugin_template_system ); + } + + self::wrap_report(); + return self::$complete_report; + } + + protected static function registered_plugins() { + /** + * Provides a mechanism for plugins to register information about their template/view + * setups. + * + * This should be done by adding an entry to $registere_template_systems where the key + * should be the plugin name and the element an array structured as follows: + * + * [ + * plugin_version, + * path_to_included_views, + * path_to_theme_overrides + * ] + * + * @var array $registered_template_systems + */ + return apply_filters( 'tribe_support_registered_template_systems', [] ); + } + + /** + * Creates a report for the specified plugin. + * + * @param string $plugin_name + * @param array $template_system + */ + protected static function generate_for( $plugin_name, array $template_system ) { + $report = '
          ' . esc_html( $plugin_name ) . '
          '; + + $scanner = new Tribe__Support__Template_Checker( + $template_system[ self::VERSION_INDEX ], + $template_system[ self::INCLUDED_VIEWS_INDEX ], + $template_system[ self::THEME_OVERRIDES_INDEX ] + ); + + $newly_introduced_or_updated = $scanner->get_views_tagged_this_release(); + $outdated_or_unknown = $scanner->get_outdated_overrides( true ); + + if ( empty( $newly_introduced_or_updated ) && empty( $outdated_or_unknown ) ) { + $report .= '
          ' . __( 'No notable changes detected', 'tribe-common' ) . '
          '; + } + + if ( ! empty( $newly_introduced_or_updated ) ) { + $report .= '

          ' . sprintf( __( 'Templates introduced or updated with this release (%s):', 'tribe-common' ), $template_system[ self::VERSION_INDEX ] ) . '

            '; + + foreach ( $newly_introduced_or_updated as $view_name => $version ) { + $report .= '
          • ' . esc_html( $view_name ) . '
          • '; + } + + $report .= '
          '; + } + + if ( ! empty( $outdated_or_unknown ) ) { + $report .= '

          ' . __( 'Existing theme overrides that may need revision:', 'tribe-common' ) . '

            '; + + foreach ( $outdated_or_unknown as $view_name => $version ) { + $version_note = empty( $version ) + ? __( 'version data missing from override', 'tribe-common' ) + : sprintf( __( 'based on %s version', 'tribe-common' ), $version ); + + $report .= '
          • ' . esc_html( $view_name ) . ' (' . $version_note . ')
          • '; + } + + $report .= '
          '; + } + + self::$plugin_reports[ $plugin_name ] = $report; + } + + /** + * Wraps the individual plugin template reports ready for display. + */ + protected static function wrap_report() { + if ( empty( self::$plugin_reports ) ) { + self::$complete_report = '

          ' . __( 'No notable template changes detected.', 'tribe-common' ) . '

          '; + } else { + self::$complete_report = '

          ' . __( 'Information about recent template changes and potentially impacted template overrides is provided below.', 'tribe-common' ) . '

          ' + . '
          ' . join( ' ', self::$plugin_reports ) . '
          '; + } + } +} diff --git a/tribe-common/src/Tribe/Tabbed_View.php b/tribe-common/src/Tribe/Tabbed_View.php new file mode 100644 index 0000000000..38e7aa7fe5 --- /dev/null +++ b/tribe-common/src/Tribe/Tabbed_View.php @@ -0,0 +1,381 @@ + => ] format. + */ + protected $items = []; + + /** + * The slug of the default tab + * + * @var string + */ + protected $default_tab; + + /** + * @var string The absolute path to this tabbed view template file. + */ + protected $template; + + /** + * An array or value object of data that should be used to render the tabbed view. + * + * @var array|object + */ + protected $data = []; + + /** + * @var string + */ + protected $label; + + /** + * @var string + */ + protected $url; + + /** + * @var string + */ + protected $active; + + /** + * Returns the tabbed view URL. + * + * @param array|string $args Query String or Array with the arguments + * @param boolean $relative Return a relative URL or absolute + * + * @return string + */ + public function get_url( $args, $relative ) { + $relative_path = add_query_arg( $args, $this->url ); + + return $relative ? $relative_path : admin_url( $relative_path ); + } + + /** + * The currently set template for this tabbed view. + * + * @return string + */ + public function get_template() { + return ! empty( $this->template ) ? $this->template : $this->get_default_template_path(); + } + + /** + * @param string $template + */ + public function set_template( $template ) { + $this->template = $template; + } + + /** + * @return string + */ + public function get_label() { + return $this->label; + } + + /** + * @param string $label + */ + public function set_label( $label ) { + $this->label = $label; + } + + /** + * Returns only the visible tabs for this tabbed view. + * + * @return Tribe__Tabbed_View__Tab[] An array of all the active and visible tabs. + */ + public function get_visibles() { + return array_filter( $this->get(), [ $this, 'is_tab_visible' ] ); + } + + /** + * @param string $url + */ + public function set_url( $url ) { + $this->url = $url; + } + + /** + * Sets the slug of the currently active tab. + * + * This value, if the tab exists, will override the value specified in the GET request. + * + * @param string $active + */ + public function set_active( $active ) { + $this->active = $active; + } + + /** + * A method to sort tabs by priority in ascending order. + * + * @param object $a First tab to compare + * @param object $b Second tab to compare + * + * @return int + */ + protected function sort_by_priority( $a, $b ) { + $a_priority = $a->get_priority(); + $b_priority = $b->get_priority(); + + if ( $a_priority == $b_priority ) { + return 0; + } + + return ( $a_priority < $b_priority ) ? - 1 : 1; + } + + /** + * Removes a tab from the tabbed view items. + * + * @param string $slug The slug of the tab to remove + * + * @return boolean `true` if the slug was registered and removed, `false` otherwise + */ + public function remove( $slug ) { + if ( ! $this->exists( $slug ) ) { + return false; + } + + unset( $this->items[ $slug ] ); + + return true; + } + + /** + * Checks if a given tab exist + * + * @param string $slug The slug of the tab + * + * @return boolean + */ + public function exists( $slug ) { + return is_object( $this->get( $slug ) ) ? true : false; + } + + /** + * Fetches the Instance of the Tab or all the tabs + * + * @param string $slug (optional) The Slug of the Tab + * + * @return null|array|object If we couldn't find the tab it will be null, if the slug is null will return all tabs + */ + public function get( $slug = null ) { + uasort( $this->items, [ $this, 'sort_by_priority' ] ); + + if ( is_null( $slug ) ) { + return $this->items; + } + + // Prevent weird stuff here + $slug = sanitize_title_with_dashes( $slug ); + + if ( ! empty( $this->items[ $slug ] ) ) { + return $this->items[ $slug ]; + } + + return null; + } + + /** + * Checks if a given Tab (slug) is active + * + * @param string $slug The Slug of the Tab + * + * @return boolean Is this tab active? + */ + public function is_active( $slug = null ) { + $slug = $this->get_requested_slug( $slug ); + $tab = $this->get_active(); + + return $slug === $tab->get_slug(); + } + + /** + * Returns the slug of tab requested in the `_GET` array or the default one. + * + * @param string|null $slug + * @param mixed $default A default value to return if the tab was not requested. + * + * @return string|bool Either the slug of the requested tab or `false` if no slug was requested + * and no default tab is set. + */ + protected function get_requested_slug( $slug = null, $default = null ) { + if ( is_null( $slug ) ) { + $default = null === $default ? $this->get_default_tab() : $default; + // Set the slug + $slug = ! empty( $_GET['tab'] ) && $this->exists( $_GET['tab'] ) ? $_GET['tab'] : $default; + } + + return $slug; + } + + /** + * Fetches the current active tab instance. + * + * @return Tribe__Tabbed_View__Tab|bool The active tab, the default tab if no tab is active, + * `false` if no tabs are registered in the Tabbed View. + */ + public function get_active() { + if ( ! empty( $this->active ) && $this->exists( $this->active ) ) { + return $this->get( $this->active ); + } + + $tab = ! empty( $_GET['tab'] ) && $this->exists( $_GET['tab'] ) ? $_GET['tab'] : $this->get_default_tab(); + + // Return the active tab or the default one + return ! empty( $tab ) ? $this->get( $tab ) : false; + } + + /** + * Returns the slug of the default tab for this tabbed view. + * + * @return string The slug of the default tab, the slug of the first tab if + * a default tab is not set, `false` otherwise. + */ + public function get_default_tab() { + if ( ! empty( $this->default_tab ) && $this->exists( $this->default_tab ) ) { + return $this->default_tab; + } + + $tabs = $this->get_tabs(); + + if ( empty( $tabs ) ) { + return false; + } + + return reset( $tabs )->get_slug(); + } + + /** + * @param Tribe__Tabbed_View__Tab|string $tab + * + * @return Tribe__Tabbed_View__Tab + */ + public function register( $tab ) { + $is_object = $tab instanceof Tribe__Tabbed_View__Tab; + if ( ! ( $is_object || ( is_string( $tab ) && class_exists( $tab ) ) ) ) { + return false; + } + + if ( ! $is_object ) { + $tab = $this->get_new_tab_instance( $tab ); + } + + // Set the Tab Item on the array of Tabs + $tab_slug = $tab->get_slug(); + + if ( empty( $tab_slug ) ) { + return false; + } + + $this->items[ $tab_slug ] = $tab; + + // Return the tab + return $tab; + } + + /** + * Returns all the registered tabs. + * + * @return Tribe__Tabbed_View__Tab[] + */ + public function get_tabs() { + uasort( $this->items, [ $this, 'sort_by_priority' ] ); + + return array_values( $this->items ); + } + + /** + * Builds an instance of the specified tab class. + * + * @param string $tab_class + * + * @return Tribe__Tabbed_View__Tab + */ + protected function get_new_tab_instance( $tab_class ) { + return new $tab_class( $this ); + } + + /** + * Renders the tabbed view and returns the resulting HTML. + * + * @return string + */ + public function render() { + $visibles = $this->get_visibles(); + if ( empty( $visibles ) ) { + return ''; + } + + if ( empty( $this->template ) ) { + $this->template = $this->get_default_template_path(); + } + + $template = $this->template; + + if ( empty( $template ) ) { + return ''; + } + + $default_data = [ + 'view' => $this, + ]; + + $data = array_merge( $default_data, (array) $this->data ); + + extract( $data ); + + ob_start(); + + include $template; + + $html = ob_get_clean(); + + return $html; + } + + /** + * Sets the default tab for the tabbed view. + * + * Please note that no check is made on the tabbed view items to ensure the value + * corresponds to a registered tab. + * + * @param string $default_tab The slug of the default tab. + */ + public function set_default_tab( $default_tab ) { + $this->default_tab = $default_tab; + } + + /** + * @param Tribe__Tabbed_View__Tab $tab + * + * @return bool + */ + protected function is_tab_visible( Tribe__Tabbed_View__Tab $tab ) { + return $tab->is_visible(); + } + + /** + * Returns the absolute path to the default template for the tabbed view. + * + * @return string + */ + public function get_default_template_path() { + return Tribe__Main::instance()->plugin_path . '/src/admin-views/tabbed-view/tabbed-view.php'; + } +} diff --git a/tribe-common/src/Tribe/Tabbed_View/Tab.php b/tribe-common/src/Tribe/Tabbed_View/Tab.php new file mode 100644 index 0000000000..8032ed62b8 --- /dev/null +++ b/tribe-common/src/Tribe/Tabbed_View/Tab.php @@ -0,0 +1,238 @@ +tabbed_view = $tabbed_view; + $this->slug = ! empty( $slug ) ? $slug : $this->slug; + } + + /** + * @return int + */ + public function get_priority() { + return $this->priority; + } + + /** + * @param $priority + */ + public function set_priority( $priority ) { + $this->priority = $priority; + } + + /** + * @return array|object + */ + public function get_data() { + return $this->data; + } + + /** + * @param array $data + */ + public function set_data( $data ) { + $this->data = $data; + } + + /** + * @return string + */ + public function get_template() { + return ! empty( $this->template ) ? $this->template : $this->get_default_template_path(); + } + + /** + * @param string $template + */ + public function set_template( $template ) { + $this->template = $template; + } + + /** + * Returns the absolute path to the default template for the tab. + * + * @return string + */ + public function get_default_template_path() { + return Tribe__Main::instance()->plugin_path . '/src/admin-views/tabbed-view/tab.php'; + } + + /** + * Whether the tab should display or not. + * + * @return boolean + */ + public function is_visible() { + return $this->visible; + } + + /** + * @param boolean $visible + */ + public function set_visible( $visible ) { + $this->visible = $visible; + } + + /** + * @return string + */ + public function get_label() { + return $this->label; + } + + /** + * @param string $label + */ + public function set_label( $label ) { + $this->label = $label; + } + + /** + * Creates a way to include the this tab HTML easily + * + * @return string HTML content of the tab + */ + public function render() { + if ( empty( $this->template ) ) { + $this->template = Tribe__Main::instance()->plugin_path . '/src/admin-views/tabbed-view/tab.php'; + } + + $template = $this->template; + + if ( empty( $template ) ) { + return ''; + } + + $default_data = [ + 'tab' => $this, + ]; + + $data = array_merge( $default_data, (array) $this->data ); + + extract( $data ); + + ob_start(); + + include $template; + + $html = ob_get_clean(); + + return $html; + } + + /** + * Returns the link to this tab + * + * @param array|string $args Query String or Array with the arguments + * @param boolean $relative Return a relative URL or absolute + * + * @return string + */ + public function get_url( $args = [], $relative = false ) { + if ( ! empty( $this->url ) ) { + return $this->url; + } + + $defaults = [ + 'tab' => $this->get_slug(), + ]; + + // Allow the link to be "changed" on the fly + $args = wp_parse_args( $args, $defaults ); + + // Escape after the filter + return $this->tabbed_view->get_url( $args, $relative ); + } + + /** + * Sets this tab URL. + * + * This URL will override the tab natural URL. + * + * @param string $url + */ + public function set_url( $url ) { + $this->url = $url; + } + + /** + * Returns the tab slug + * + * @return string + */ + public function get_slug() { + return $this->slug; + } + + /** + * Determines if this Tab is currently displayed + * + * @return boolean + */ + public function is_active() { + $active = $this->tabbed_view->get_active(); + + return ! empty( $active ) ? $this->get_slug() === $active->get_slug() : false; + } +} diff --git a/tribe-common/src/Tribe/Template.php b/tribe-common/src/Tribe/Template.php new file mode 100644 index 0000000000..e24465da0b --- /dev/null +++ b/tribe-common/src/Tribe/Template.php @@ -0,0 +1,1468 @@ + alias`. + * + * @since 4.12.10 + * + * @var array + */ + protected $aliases = []; + + /** + * Configures the class origin plugin path + * + * @since 4.6.2 + * + * @param object|string $origin The base origin for the templates + * + * @return self + */ + public function set_template_origin( $origin = null ) { + if ( empty( $origin ) ) { + $origin = $this->origin; + } + + if ( is_string( $origin ) ) { + // Origin needs to be a class with a `instance` method + if ( class_exists( $origin ) && method_exists( $origin, 'instance' ) ) { + $origin = call_user_func( [ $origin, 'instance' ] ); + } + } + + if ( + empty( $origin->plugin_path ) + && empty( $origin->pluginPath ) + && ! is_dir( $origin ) + ) { + throw new InvalidArgumentException( 'Invalid Origin Class for Template Instance' ); + } + + if ( is_string( $origin ) ) { + $this->template_base_path = array_filter( + (array) explode( + '/', + untrailingslashit( $origin ) + ) + ); + } else { + $this->origin = $origin; + + $this->template_base_path = untrailingslashit( + ! empty( $this->origin->plugin_path ) + ? $this->origin->plugin_path + : $this->origin->pluginPath + ); + } + + return $this; + } + + /** + * Configures the class with the base folder in relation to the Origin + * + * @since 4.6.2 + * + * @param array|string $folder Which folder we are going to look for templates + * + * @return self + */ + public function set_template_folder( $folder = null ) { + // Allows configuring a already set class + if ( ! isset( $folder ) ) { + $folder = $this->folder; + } + + // If Folder is String make it an Array + if ( is_string( $folder ) ) { + $folder = (array) explode( '/', $folder ); + } + + // Cast as Array and save + $this->folder = (array) $folder; + + return $this; + } + + /** + * Returns the array for which folder this template instance is looking into. + * + * @since 4.11.0 + * + * @return array Current folder we are looking for templates. + */ + public function get_template_folder() { + return $this->folder; + } + + /** + * Configures the class with the base folder in relation to the Origin + * + * @since 4.7.20 + * + * @param mixed $value Should we look for template files in the list of folders. + * + * @return self + */ + public function set_template_folder_lookup( $value = true ) { + $this->template_folder_lookup = tribe_is_truthy( $value ); + + return $this; + } + + /** + * Gets in this instance of the template engine whether we are looking public folders like themes. + * + * @since 4.12.1 + * + * @return bool Whether we are looking into theme folders. + */ + public function get_template_folder_lookup() { + return $this->template_folder_lookup; + } + + /** + * Configures the class global context + * + * @since 4.6.2 + * + * @param array $context Default global Context + * + * @return self + */ + public function add_template_globals( $context = [] ) { + // Cast as Array merge and save + $this->global = wp_parse_args( (array) $context, $this->global ); + + return $this; + } + + /** + * Configures if the class will extract context for template + * + * @since 4.6.2 + * + * @param bool $value Should we extract context for templates + * + * @return self + */ + public function set_template_context_extract( $value = false ) { + // Cast as bool and save + $this->template_context_extract = tribe_is_truthy( $value ); + + return $this; + } + + /** + * Set the current hook name for the template include. + * + * @since 4.12.1 + * + * @param string $value Which value will be saved as the current hook name. + * + * @return self Allow daisy-chaining. + */ + public function set_template_current_hook_name( $value ) { + $this->template_current_hook_name = (string) $value; + + return $this; + } + + /** + * Gets the hook name for the current template setup. + * + * @since 4.12.1 + * + * @return string Hook name currently set on the class. + */ + public function get_template_current_hook_name() { + return $this->template_current_hook_name; + } + + /** + * Sets an Index inside of the global or local context. + * Final to prevent extending the class when the `get` already exists on the child class. + * + * @see Tribe__Utils__Array::set() + * + * @since 4.6.2 + * + * @param array|string $index Specify each nested index in order. + * Example: array( 'lvl1', 'lvl2' ); + * @param mixed $default Default value if the search finds nothing. + * @param boolean $is_local Use the Local or Global context. + * + * @return mixed The value of the specified index or the default if not found. + */ + final public function get( $index, $default = null, $is_local = true ) { + $context = $this->get_global_values(); + + if ( true === $is_local ) { + $context = $this->get_local_values(); + } + + /** + * Allows filtering the the getting of Context variables, also short circuiting + * Following the same structure as WP Core + * + * @since 4.6.2 + * + * @param mixed $value The value that will be filtered. + * @param array|string $index Specify each nested index in order. + * Example: array( 'lvl1', 'lvl2' ); + * @param mixed $default Default value if the search finds nothing. + * @param boolean $is_local Use the Local or Global context. + * @param self $template Current instance of the Tribe__Template. + */ + $value = apply_filters( 'tribe_template_context_get', null, $index, $default, $is_local, $this ); + + if ( null !== $value ) { + return $value; + } + + return Tribe__Utils__Array::get( $context, $index, $default ); + } + + /** + * Sets a Index inside of the global or local context + * Final to prevent extending the class when the `set` already exists on the child class + * + * @since 4.6.2 + * + * @see Tribe__Utils__Array::set + * + * @param string|array $index To set a key nested multiple levels deep pass an array + * specifying each key in order as a value. + * Example: array( 'lvl1', 'lvl2', 'lvl3' ); + * @param mixed $value The value. + * @param boolean $is_local Use the Local or Global context + * + * @return array Full array with the key set to the specified value. + */ + final public function set( $index, $value = null, $is_local = true ) { + if ( true === $is_local ) { + $this->context = Tribe__Utils__Array::set( $this->context, $index, $value ); + + return $this->context; + } + + $this->global = Tribe__Utils__Array::set( $this->global, $index, $value ); + + return $this->global; + } + + /** + * Merges local and global context, and saves it locally + * + * @since 4.6.2 + * + * @param array $context Local Context array of data + * @param string $file Complete path to include the PHP File + * @param array $name Template name + * + * @return array + */ + public function merge_context( $context = [], $file = null, $name = null ) { + // Allow for simple null usage as well as array() for nothing + if ( is_null( $context ) ) { + $context = []; + } + + // Applies new local context on top of Global + Previous local. + $context = wp_parse_args( (array) $context, $this->get_values() ); + + /** + * Allows filtering the Local context + * + * @since 4.6.2 + * + * @param array $context Local Context array of data + * @param string $file Complete path to include the PHP File + * @param array $name Template name + * @param self $template Current instance of the Tribe__Template + */ + $this->context = apply_filters( 'tribe_template_context', $context, $file, $name, $this ); + + return $this->context; + } + + /** + * Fetches the path for locating files in the Plugin Folder + * + * @since 4.7.20 + * + * @return string + */ + protected function get_template_plugin_path() { + // Craft the plugin Path + $path = array_merge( (array) $this->template_base_path, $this->folder ); + + // Implode to avoid Window Problems + $path = implode( DIRECTORY_SEPARATOR, $path ); + + /** + * Allows filtering of the base path for templates + * + * @since 4.7.20 + * + * @param string $path Complete path to include the base plugin folder + * @param self $template Current instance of the Tribe__Template + */ + return apply_filters( 'tribe_template_plugin_path', $path, $this ); + } + + /** + * Fetches the Namespace for the public paths, normally folders to look for + * in the theme's directory. + * + * @since 4.7.20 + * @since 4.11.0 Added param $plugin_namespace. + * + * @param string $plugin_namespace Overwrite the origin namespace with a given one. + * + * @return array Namespace where we to look for templates. + */ + protected function get_template_public_namespace( $plugin_namespace ) { + $namespace = [ + 'tribe', + ]; + + if ( ! empty( $plugin_namespace ) ) { + $namespace[] = $plugin_namespace; + } elseif ( ! empty( $this->origin->template_namespace ) ) { + $namespace[] = $this->origin->template_namespace; + } + + /** + * Allows filtering of the base path for templates + * + * @since 4.7.20 + * + * @param array $namespace Which is the namespace we will look for files in the theme + * @param self $template Current instance of the Tribe__Template + */ + return apply_filters( 'tribe_template_public_namespace', $namespace, $this ); + } + + /** + * Fetches which base folder we look for templates in the origin plugin. + * + * @since 4.10.2 + * + * @return array The base folders we look for templates in the origin plugin. + */ + public function get_template_origin_base_folder() { + /** + * Allows filtering of the base path for templates. + * + * @since 4.10.2 + * + * @param array $namespace Which is the base folder we will look for files in the plugin. + * @param self $template Current instance of the Tribe__Template. + */ + return apply_filters( 'tribe_template_origin_base_folder', $this->template_origin_base_folder, $this ); + } + + /** + * Fetches the path for locating files given a base folder normally theme related. + * + * @since 4.7.20 + * @since 4.11.0 Added the param $namespace. + * + * @param mixed $base Base path to look into. + * @param string $namespace Adds the plugin namespace to the path returned. + * + * @return string The public path for a given base.ห™ห™ + */ + protected function get_template_public_path( $base, $namespace ) { + + // Craft the plugin Path + $path = array_merge( (array) $base, (array) $this->get_template_public_namespace( $namespace ) ); + + // Pick up if the folder needs to be aded to the public template path. + $folder = array_diff( $this->folder, $this->get_template_origin_base_folder() ); + + if ( ! empty( $folder ) ) { + $path = array_merge( $path, $folder ); + } + + // Implode to avoid Window Problems + $path = implode( DIRECTORY_SEPARATOR, $path ); + + /** + * Allows filtering of the base path for templates + * + * @since 4.7.20 + * + * @param string $path Complete path to include the base public folder + * @param self $template Current instance of the Tribe__Template + */ + return apply_filters( 'tribe_template_public_path', $path, $this ); + } + + /** + * Fetches the folders in which we will look for a given file + * + * @since 4.7.20 + * @since 4.12.10 Add support for common lookup. + * + * @return array A list of possible locations for the template file. + */ + protected function get_template_path_list() { + $folders = []; + + $folders['plugin'] = [ + 'id' => 'plugin', + 'priority' => 20, + 'path' => $this->get_template_plugin_path(), + ]; + + if ( $this->common_lookup ) { + // After the plugin (due to priority) look into Common too. + $folders['common'] = [ + 'id' => 'common', + 'priority' => 100, + 'path' => $this->get_template_common_path(), + ]; + } + + $folders = array_merge( $folders, $this->apply_aliases( $folders ) ); + + /** + * Allows filtering of the list of folders in which we will look for the + * template given. + * + * @since 4.7.20 + * + * @param array $folders Complete path to include the base public folder + * @param self $template Current instance of the Tribe__Template + */ + $folders = (array) apply_filters( 'tribe_template_path_list', $folders, $this ); + + uasort( $folders, 'tribe_sort_by_priority' ); + + return $folders; + } + + /** + * Get the list of theme related folders we will look up for the template. + * + * @since 4.11.0 + * + * @param string $namespace Which plugin namespace we are looking for. + * + * @return array + */ + protected function get_template_theme_path_list( $namespace ) { + $folders = []; + + $folders['child-theme'] = [ + 'id' => 'child-theme', + 'priority' => 10, + 'path' => $this->get_template_public_path( STYLESHEETPATH, $namespace ), + ]; + $folders['parent-theme'] = [ + 'id' => 'parent-theme', + 'priority' => 15, + 'path' => $this->get_template_public_path( TEMPLATEPATH, $namespace ), + ]; + + /** + * Allows filtering of the list of theme folders in which we will look for the template. + * + * @since 4.11.0 + * + * @param array $folders Complete path to include the base public folder. + * @param string $namespace Loads the files from a specified folder from the themes. + * @param self $template Current instance of the Tribe__Template. + */ + $folders = (array) apply_filters( 'tribe_template_theme_path_list', $folders, $namespace, $this ); + + uasort( $folders, 'tribe_sort_by_priority' ); + + return $folders; + } + + /** + * Tries to locate the correct file we want to load based on the Template class + * configuration and it's list of folders + * + * @since 4.7.20 + * + * @param mixed $name File name we are looking for + * + * @return string + */ + public function get_template_file( $name ) { + // If name is String make it an Array + if ( is_string( $name ) ) { + $name = (array) explode( '/', $name ); + } + + $folders = $this->get_template_path_list(); + $found_file = false; + $namespace = false; + + foreach ( $folders as $folder ) { + if ( empty( $folder['path'] ) ) { + continue; + } + + // Build the File Path + $file = Paths::merge( $folder['path'], $name ); + + // Append the Extension to the file path + $file .= '.php'; + + // Skip non-existent files + if ( file_exists( $file ) ) { + $found_file = $file; + $namespace = ! empty( $folder['namespace'] ) ? $folder['namespace'] : false; + break; + } + } + + if ( $this->get_template_folder_lookup() ) { + $theme_folders = $this->get_template_theme_path_list( $namespace ); + + foreach ( $theme_folders as $folder ) { + if ( empty( $folder['path'] ) ) { + continue; + } + + // Build the File Path + $file = implode( DIRECTORY_SEPARATOR, array_merge( (array) $folder['path'], $name ) ); + + // Append the Extension to the file path + $file .= '.php'; + + // Skip non-existent files + if ( file_exists( $file ) ) { + $found_file = $file; + break; + } + } + } + + if ( $found_file ) { + /** + * A more Specific Filter that will include the template name + * + * @since 4.6.2 + * @since 4.7.20 The $name param no longer contains the extension + * + * @param string $file Complete path to include the PHP File + * @param array $name Template name + * @param self $template Current instance of the Tribe__Template + */ + return apply_filters( 'tribe_template_file', $found_file, $name, $this ); + } + + // Couldn't find a template on the Stack + return false; + } + + /** + * Runs the entry point hooks and filters. + * + * @param string $entry_point_name The name of the entry point. + * @param boolean $echo If we should also print the entry point content. + * + * @return null|string `null` if an entry point is disabled or the entry point HTML. + */ + public function do_entry_point( $entry_point_name, $echo = true ) { + $hook_name = $this->get_template_current_hook_name(); + + /** + * Filter if the entry points are enabled. + * + * @since 4.12.1 + * + * @param boolean $is_enabled Is entry_point enabled. + * @param string $hook_name For which template include this entry point belongs. + * @param string $entry_point_name Which entry point specifically we are triggering. + * @param self $template Current instance of the template class doing this entry point. + */ + $is_entry_point_enabled = apply_filters( 'tribe_template_entry_point_is_enabled', true, $hook_name, $entry_point_name, $this ); + + if ( ! $is_entry_point_enabled ) { + return null; + } + + ob_start(); + + if ( has_action( "tribe_template_entry_point:{$hook_name}" ) ) { + /** + * Generic entry point action for the current template. + * + * @since 4.12.1 + * + * @param string $hook_name For which template include this entry point belongs. + * @param string $entry_point_name Which entry point specifically we are triggering. + * @param self $template Current instance of the template class doing this entry point. + */ + do_action( "tribe_template_entry_point:{$hook_name}", $hook_name, $entry_point_name, $this ); + } + + if ( has_action( "tribe_template_entry_point:{$hook_name}:{$entry_point_name}" ) ) { + /** + * Specific named entry point action called. + * + * @since 4.12.1 + * + * @param string $hook_name For which template include this entry point belongs. + * @param string $entry_point_name Which entry point specifically we are triggering. + * @param self $template Current instance of the template class doing this entry point. + */ + do_action( "tribe_template_entry_point:{$hook_name}:{$entry_point_name}", $hook_name, $entry_point_name, $this ); + } + + $html = ob_get_clean(); + + if ( has_filter( "tribe_template_entry_point_html:{$hook_name}" ) ) { + /** + * Generic entry point action for the current template. + * + * @since 4.12.1 + * + * @param string $html HTML returned and/or echoed for this for this entry point. + * @param string $hook_name For which template include this entry point belongs. + * @param string $entry_point_name Which entry point specifically we are triggering. + * @param self $template Current instance of the template class doing this entry point. + */ + $html = apply_filters( "tribe_template_entry_point_html:{$hook_name}", $html, $hook_name, $entry_point_name, $this ); + } + + if ( has_filter( "tribe_template_entry_point_html:{$hook_name}:{$entry_point_name}" ) ) { + /** + * Specific named entry point action called. + * + * @since 4.12.1 + * + * @param string $html HTML returned and/or echoed for this for this entry point. + * @param string $hook_name For which template include this entry point belongs. + * @param string $entry_point_name Which entry point specifically we are triggering. + * @param self $template Current instance of the template class doing this entry point. + */ + $html = apply_filters( "tribe_template_entry_point_html:{$hook_name}:{$entry_point_name}", $html, $hook_name, $entry_point_name, $this ); + } + + if ( $echo ) { + echo $html; + } + + return $html; + } + + /** + * A very simple method to include a Template, allowing filtering and additions using hooks. + * + * @since 4.6.2 + * + * @param string|array $name Which file we are talking about including. + * If an array, each item will add a directory separator to get to the single template. + * @param array $context Any context data you need to expose to this file + * @param boolean $echo If we should also print the Template + * + * @return string|false Either the final content HTML or `false` if no template could be found. + */ + public function template( $name, $context = [], $echo = true ) { + static $file_exists = []; + static $files = []; + static $template_names = []; + + /** + * Allow users to disable templates before rendering it by returning empty string. + * + * @since 4.12.0 + * + * @param string null Whether to continue displaying the template or not. + * @param array $name Template name. + * @param array $context Any context data you need to expose to this file. + * @param boolean $echo If we should also print the Template. + */ + $done = apply_filters( 'tribe_template_done', null, $name, $context, $echo ); + + if ( null !== $done ) { + return false; + } + + // Key we'll use for in-memory caching of expensive operations. + $cache_name_key = is_array( $name ) ? implode( '/', $name ) : $name; + + // Cache template name massaging so we don't have to repeat these actions. + if ( ! isset( $template_names[ $cache_name_key ] ) ) { + // If name is String make it an Array + if ( is_string( $name ) ) { + $name = (array) explode( '/', $name ); + } + + // Clean this Variable + $name = array_map( 'sanitize_title_with_dashes', $name ); + + $template_names[ $cache_name_key ] = $name; + } + + // Cache file location and existence. + if ( + ! isset( $file_exists[ $cache_name_key ] ) + || ! isset( $files[ $cache_name_key ] ) + ) { + // Check if the file exists + $files[ $cache_name_key ] = $file = $this->get_template_file( $name ); + + // Check if it's a valid variable + if ( ! $file ) { + return $file_exists[ $cache_name_key ] = false; + } + + // Before we load the file we check if it exists + if ( ! file_exists( $file ) ) { + return $file_exists[ $cache_name_key ] = false; + } + + $file_exists[ $cache_name_key ] = true; + } + + // If the file doesn't exist, bail. + if ( ! $file_exists[ $cache_name_key ] ) { + return false; + } + + // Use filename stored in cache. + $file = $files[ $cache_name_key ]; + $name = $template_names[ $cache_name_key ]; + $origin_folder_appendix = array_diff( $this->folder, $this->template_origin_base_folder ); + + if ( $origin_namespace = $this->template_get_origin_namespace( $file ) ) { + $legacy_namespace = array_merge( (array) $origin_namespace, $name ); + $namespace = array_merge( (array) $origin_namespace, $origin_folder_appendix, $name ); + } else { + $legacy_namespace = $name; + $namespace = array_merge( $origin_folder_appendix, $legacy_namespace ); + } + + // Setup the Hook name. + $legacy_hook_name = implode( '/', $legacy_namespace ); + $hook_name = implode( '/', $namespace ); + $prev_hook_name = $this->get_template_current_hook_name(); + + // Store the current hook name for the purposes of entry-points. + $this->set_template_current_hook_name( $hook_name ); + + /** + * Allow users to filter the HTML before rendering + * + * @since 4.11.0 + * + * @param string $html The initial HTML + * @param string $file Complete path to include the PHP File + * @param array $name Template name + * @param self $template Current instance of the Tribe__Template + */ + $pre_html = apply_filters( 'tribe_template_pre_html', null, $file, $name, $this ); + + /** + * Allow users to filter the HTML by the name before rendering + * + * E.g.: + * `tribe_template_pre_html:events/blocks/parts/details` + * `tribe_template_pre_html:events/embed` + * `tribe_template_pre_html:tickets/login-to-purchase` + * + * @since 4.11.0 + * + * @param string $html The initial HTML + * @param string $file Complete path to include the PHP File + * @param array $name Template name + * @param self $template Current instance of the Tribe__Template + */ + $pre_html = apply_filters( "tribe_template_pre_html:{$hook_name}", $pre_html, $file, $name, $this ); + + if ( null !== $pre_html ) { + return $pre_html; + } + + // Merges the local data passed to template to the global scope + $this->merge_context( $context, $file, $name ); + + $before_include_html = $this->actions_before_template( $file, $name, $hook_name ); + $before_include_html = $this->filter_template_before_include_html( $before_include_html, $file, $name, $hook_name ); + + $include_html = $this->template_safe_include( $file ); + $include_html = $this->filter_template_include_html( $include_html, $file, $name, $hook_name ); + + $after_include_html = $this->actions_after_template( $file, $name, $hook_name ); + $after_include_html = $this->filter_template_after_include_html( $after_include_html, $file, $name, $hook_name ); + + // Only fetch the contents after the action + $html = $before_include_html . $include_html . $after_include_html; + + $html = $this->filter_template_html( $html, $file, $name, $hook_name ); + + // Tries to hook container entry points in the HTML. + $html = $this->template_hook_container_entry_points( $html ); + + if ( $echo ) { + echo $html; + } + + // Revert the current hook name. + $this->set_template_current_hook_name( $prev_hook_name ); + + return $html; + } + + /** + * Run the hooks for the container entry points. + * + * @since 4.12.1 + * + * @param string $html The html of the current template. + * + * @return string|false Either the final entry point content HTML or `false` if no entry point could be found or set to false. + */ + private function template_hook_container_entry_points( $html ) { + + $matches = $this->get_entry_point_matches( $html ); + $html_matches = $matches[0]; + + if ( 0 === count( $html_matches ) ) { + return $html; + } + + $html_tags = $matches['tag']; + $html_tags_ends = $matches['is_end']; + + // Get first and last tags. + $first_tag = reset( $html_tags ); + $last_tag = end( $html_tags ); + + // Determine if first last tags are tag ends. + $first_tag_is_end = '/' === reset( $html_tags_ends ); + $last_tag_is_end = '/' === end( $html_tags_ends ); + + // When first and last tag are not the same, bail. + if ( $first_tag !== $last_tag ) { + return $html; + } + + // If the first tag is a html tag end, bail. + if ( $first_tag_is_end ) { + return $html; + } + + // If the last tag is not and html tag end, bail. + if ( ! $last_tag_is_end ) { + return $html; + } + + $first_tag_html = reset( $html_matches ); + $last_tag_html = end( $html_matches ); + + $open_container_entry_point_html = $this->do_entry_point( 'after_container_open', false ); + $close_container_entry_point_html = $this->do_entry_point( 'before_container_close', false ); + + $html = Strings::replace_first( $first_tag_html, $first_tag_html . $open_container_entry_point_html, $html ); + $html = Strings::replace_last( $last_tag_html, $close_container_entry_point_html . $last_tag_html, $html ); + + return $html; + } + + /** + * Based on a path it determines what is the namespace that should be used. + * + * @since 4.11.0 + * + * @param string $path Which file we are going to load. + * + * @return string|false The found namespace for that path or false. + */ + public function template_get_origin_namespace( $path ) { + $matching_namespace = false; + /** + * Allows more namespaces to be added based on the path of the file we are loading. + * + * @since 4.11.0 + * + * @param array $namespace_map Indexed array containing the namespace as the key and path to `strpos`. + * @param string $path Path we will do the `strpos` to validate a given namespace. + * @param self $template Current instance of the template class. + */ + $namespace_map = (array) apply_filters( 'tribe_template_origin_namespace_map', [], $path, $this ); + + foreach ( $namespace_map as $namespace => $contains_string ) { + // Normalize the trailing slash to the current OS directory separator. + $contains_string = rtrim( $contains_string, '\\/' ) . DIRECTORY_SEPARATOR; + + // Skip when we don't have the namespace path. + if ( false === strpos( $path, $contains_string ) ) { + continue; + } + + $matching_namespace = $namespace; + + // Once the first namespace is found it breaks out. + break; + } + + if ( empty( $matching_namespace ) && ! empty( $this->origin->template_namespace ) ) { + $matching_namespace = $this->origin->template_namespace; + } + + return $matching_namespace; + } + + /** + * Includes a give PHP inside of a safe context. + * + * This method is required to prevent template files messing with local variables used inside of the + * `self::template` method. Also shelters the template loading from any possible variables that could + * be overwritten by the context. + * + * @since 4.11.0 + * + * @param string $file Which file will be included with safe context. + * + * @return string Contents of the included file. + */ + public function template_safe_include( $file ) { + ob_start(); + // We use this instance variable to prevent collisions. + $this->template_current_file_path = $file; + unset( $file ); + + // Only do this if really needed (by default it won't). + if ( true === $this->template_context_extract && ! empty( $this->context ) ) { + // Make any provided variables available in the template variable scope. + extract( $this->context ); // @phpcs:ignore + } + + include $this->template_current_file_path; + + // After the include we reset the variable. + unset( $this->template_current_file_path ); + return ob_get_clean(); + } + + /** + * Sets a number of values at the same time. + * + * @since 4.9.11 + * + * @param array $values An associative key/value array of the values to set. + * @param bool $is_local Whether to set the values as global or local; defaults to local as the `set` method does. + * + * @see Tribe__Template::set() + */ + public function set_values( array $values = [], $is_local = true ) { + foreach ( $values as $key => $value ) { + $this->set( $key, $value, $is_local ); + } + } + + /** + * Returns the Template global context. + * + * @since 4.9.11 + * + * @return array An associative key/value array of the Template global context. + */ + public function get_global_values() { + return $this->global; + } + + /** + * Returns the Template local context. + * + * @since 4.9.11 + * + * @return array An associative key/value array of the Template local context. + */ + public function get_local_values() { + return $this->context; + } + + /** + * Returns the Template global and local context values. + * + * Local values will override the template global context values. + * + * @since 4.9.11 + * + * @return array An associative key/value array of the Template global and local context. + */ + public function get_values() { + return array_merge( $this->get_global_values(), $this->get_local_values() ); + } + + /** + * Get the Entry Point Matches. + * + * @since 4.12.1 + * + * @param string $html The html of the current template. + * + * @return array An array of matches from the regular expression. + */ + private function get_entry_point_matches( $html ) { + $regexp = '/<(?\/)*(?[A-Z0-9]*)(?:\b)*[^>]*>/mi'; + + preg_match_all( $regexp, $html, $matches ); + + return $matches; + } + + /** + * Fetches the path for locating files in the Common folder part of the plugin that is currently providing it. + * + * Note: the Common path will be dependent on the version that is loaded from the plugin that is bundling it. + * E.g. if both TEC and ET are active (both will bundle Common) and the ET version of Common has been loaded as + * most recent and the ET version of Common does not have a template file, then the template file will not be found. + * This will allow versioning the existence and nature of the template files part of common. + * + * @since 4.12.10 + * + * @return string The absolute path, with no guarantee of its existence, to the Common version of the template file. + */ + protected function get_template_common_path() { + // As base path use the current location of Common, remove the trailing slash. + $common_abs_path = untrailingslashit( Tribe__Main::instance()->plugin_path ); + $path = array_merge( (array) $common_abs_path, $this->folder ); + + // Implode to avoid problems on Windows hosts. + $path = implode( DIRECTORY_SEPARATOR, $path ); + + /** + * Allows filtering the path to a template provided by Common. + * + * @since 4.12.10 + * + * @param string $path Complete path to include the base folder of common part of the plugin. + * @param self $template Current instance of the Tribe__Template. + */ + return apply_filters( 'tribe_template_common_path', $path, $this ); + } + + /** + * Sets the aliases the template should use. + * + * @since 4.12.10 + * + * @param array $aliases A map of aliases that should be used to add lookup locations, in the format + * `[ original => alias ]`; + * + * @return static This instance, for method chaining. + */ + public function set_aliases( array $aliases = [] ) { + $this->aliases = $aliases; + + return $this; + } + + /** + * Applies the template path aliases, if any, to a list of folders. + * + * @since 4.12.10 + * + * @param array $folders The list of folder to apply the aliases to, if any. + * + * @return array The list of new folder entries to add to the folders, in the same input format of the + * folders. + */ + protected function apply_aliases( array $folders ) { + $new_folders = []; + if ( ! empty( $this->aliases ) ) { + foreach ( $folders as $folder_name => $folder ) { + $original_path = $folder['path']; + foreach ( $this->aliases as $original => $alias ) { + // Since an alias could be a path, we take care to handle it with the current directory separator. + list( $normalized_original, $normalized_alias ) = str_replace(['\\','/'] , DIRECTORY_SEPARATOR, [ $original, $alias ] ); + if ( false === strpos( $original_path, $normalized_original ) ) { + continue; + } + + $alias_path = str_replace( $normalized_original, $normalized_alias, $original_path ); + + $new = $folder; + $new['path'] = $alias_path; + $new['priority'] = (int) $new['priority'] + 1; + $new_folders[ $folder_name . '_' . $alias ] = $new; + } + } + } + return $new_folders; + } + + + /** + * Filters the full HTML for the template. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param string $hook_name The hook used to create the filter by name. + * + * @return string HTML after filtering. + */ + protected function filter_template_html( $html, $file, $name, $hook_name ) { + /** + * Allow users to filter the final HTML. + * + * @since 4.6.2 + * @since 4.7.20 The $name param no longer contains the extension + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( 'tribe_template_html', $html, $file, $name, $this ); + + /** + * Allow users to filter the final HTML by the name. + * + * E.g.: + * `tribe_template_html:events/blocks/parts/details` + * `tribe_template_html:events/embed` + * `tribe_template_html:tickets/login-to-purchase` + * + * @since 4.7.20 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( "tribe_template_html:{$hook_name}", $html, $file, $name, $this ); + + return $html; + } + + /** + * Filters the HTML for the Before include actions. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param string $hook_name The hook used to create the filter by name. + * + * @return string HTML after filtering. + */ + protected function filter_template_before_include_html( $html, $file, $name, $hook_name ) { + /** + * Allow users to filter the Before include actions. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( 'tribe_template_before_include_html', $html, $file, $name, $this ); + + /** + * Allow users to filter the Before include actions by name. + * + * E.g.: + * `tribe_template_before_include_html:events/blocks/parts/details` + * `tribe_template_before_include_html:events/embed` + * `tribe_template_before_include_html:tickets/login-to-purchase` + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( "tribe_template_before_include_html:{$hook_name}", $html, $file, $name, $this ); + + return $html; + } + + /** + * Filters the HTML for the PHP safe include. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param string $hook_name The hook used to create the filter by name. + * + * @return string HTML after filtering. + */ + protected function filter_template_include_html( $html, $file, $name, $hook_name ) { + /** + * Allow users to filter the PHP template include actions. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( 'tribe_template_include_html', $html, $file, $name, $this ); + + /** + * Allow users to filter the PHP template include actions by name. + * + * E.g.: + * `tribe_template_include_html:events/blocks/parts/details` + * `tribe_template_include_html:events/embed` + * `tribe_template_include_html:tickets/login-to-purchase` + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( "tribe_template_include_html:{$hook_name}", $html, $file, $name, $this ); + + return $html; + } + + /** + * Filters the HTML for the after include actions. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param string $hook_name The hook used to create the filter by name. + * + * @return string HTML after filtering. + */ + protected function filter_template_after_include_html( $html, $file, $name, $hook_name ) { + /** + * Allow users to filter the after include actions. + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( 'tribe_template_after_include_html', $html, $file, $name, $this ); + + /** + * Allow users to filter the after include actions by name. + * + * E.g.: + * `tribe_template_after_include_html:events/blocks/parts/details` + * `tribe_template_after_include_html:events/embed` + * `tribe_template_after_include_html:tickets/login-to-purchase` + * + * @since 4.13.0 + * + * @param string $html The final HTML. + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + $html = apply_filters( "tribe_template_after_include_html:{$hook_name}", $html, $file, $name, $this ); + + return $html; + } + + /** + * Fires of actions before including the template. + * + * @since 4.13.0 + * + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param string $hook_name The hook used to create the filter by name. + * + * @return string HTML printed by the before actions. + */ + protected function actions_before_template( $file, $name, $hook_name ) { + ob_start(); + + /** + * Fires an Action before including the template file + * + * @since 4.13.0 + * + * @param string $file Complete path to include the PHP File + * @param array $name Template name + * @param self $template Current instance of the Tribe__Template + */ + do_action( 'tribe_template_before_include', $file, $name, $this ); + + /** + * Fires an Action for a given template name before including the template file, + * + * E.g.: + * `tribe_template_before_include:events/blocks/parts/details` + * `tribe_template_before_include:events/embed` + * `tribe_template_before_include:tickets/login-to-purchase` + * + * @since 4.13.0 + * + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + do_action( "tribe_template_before_include:{$hook_name}", $file, $name, $this ); + + return ob_get_clean(); + } + + /** + * Fires of actions after including the template. + * + * @since 4.13.0 + * + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param string $hook_name The hook used to create the filter by name. + * + * @return string HTML printed by the after actions. + */ + protected function actions_after_template( $file, $name, $hook_name ) { + ob_start(); + /** + * Fires an Action after including the template file. + * + * @since 4.13.0 + * + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + do_action( 'tribe_template_after_include', $file, $name, $this ); + + /** + * Fires an Action for a given template name after including the template file. + * + * E.g.: + * `tribe_template_after_include:events/blocks/parts/details` + * `tribe_template_after_include:events/embed` + * `tribe_template_after_include:tickets/login-to-purchase` + * + * @since 4.13.0 + * + * @param string $file Complete path to include the PHP File. + * @param array $name Template name. + * @param self $template Current instance of the Tribe__Template. + */ + do_action( "tribe_template_after_include:{$hook_name}", $file, $name, $this ); + return ob_get_clean(); + } +} diff --git a/tribe-common/src/Tribe/Template_Factory.php b/tribe-common/src/Tribe/Template_Factory.php new file mode 100755 index 0000000000..3635e7a113 --- /dev/null +++ b/tribe-common/src/Tribe/Template_Factory.php @@ -0,0 +1,219 @@ +asset_packages(); + } + + /** + * Manage the asset packages defined for this template + * + * @deprecated 4.7.18 + * + * @return void + **/ + protected function asset_packages() { + foreach ( $this->asset_packages as $asset_package ) { + $this->asset_package( $asset_package ); + } + } + + /** + * Handles an asset package request. + * + * @deprecated 4.7.18 + * + * @param string $name The asset name in the `hyphen-separated-format` + * @param array $deps An array of dependency handles + * @param string $vendor_url URL to vendor scripts and styles dir + * @param string $prefix MT script and style prefix + * @param Tribe__Main $tec An instance of the main plugin class + */ + protected static function handle_asset_package_request( $name, $deps, $vendor_url, $prefix, $tec ) { + + $asset = self::get_asset_factory_instance( $name ); + + self::prepare_asset_package_request( $asset, $name, $deps, $vendor_url, $prefix, $tec ); + } + + /** + * initializes asset package request + * + * @deprecated 4.7.18 + * + * @param object $asset The Tribe__*Asset object + * @param string $name The asset name in the `hyphen-separated-format` + * @param array $deps An array of dependency handles + * @param string $vendor_url URL to vendor scripts and styles dir + * @param string $prefix MT script and style prefix + * @param Tribe__Main $common An instance of the main plugin class + */ + protected static function prepare_asset_package_request( $asset, $name, $deps, $vendor_url, $prefix, $common ) { + if ( ! $asset ) { + do_action( $prefix . '-' . $name ); + + return; + } + + $asset->set_name( $name ); + $asset->set_deps( $deps ); + $asset->set_vendor_url( $vendor_url ); + $asset->set_prefix( $prefix ); + $asset->set_tec( $common ); + + $asset->handle(); + } + + /** + * Retrieves the appropriate asset factory instance + * + * @deprecated 4.7.18 + * + */ + protected static function get_asset_factory_instance( $name ) { + $asset = Tribe__Asset__Factory::instance()->make_for_name( $name ); + return $asset; + } + + /** + * + * @deprecated 4.7.18 + * + * @param string $script_handle A registered script handle. + */ + public static function add_vendor_script( $script_handle ) { + if ( in_array( $script_handle, self::$vendor_scripts ) ) { + return; + } + self::$vendor_scripts[] = $script_handle; + } + + /** + * @return string[] An array of registered vendor script handles. + */ + public static function get_vendor_scripts() { + return self::$vendor_scripts; + } + + /** + * Asset calls for vendor packages + * + * @deprecated 4.7.18 + * + * @param string $name + * @param array $deps Dependents + */ + public static function asset_package( $name, $deps = [] ) { + + $common = Tribe__Main::instance(); + $prefix = 'tribe-events'; + + // setup plugin resources & 3rd party vendor urls + $vendor_url = trailingslashit( $common->plugin_url ) . 'vendor/'; + + self::handle_asset_package_request( $name, $deps, $vendor_url, $prefix, $common ); + } + + /** + * Returns the path to a minified version of a js or css file, if it exists. + * If the file does not exist, returns false. + * + * @deprecated 4.7.18 + * + * @param string $url The path or URL to the un-minified file. + * @param bool $default_to_original Whether to just return original path if min version not found. + * + * @return string|false The path/url to minified version or false, if file not found. + */ + public static function getMinFile( $url, $default_to_original = false ) { + if ( ! defined( 'SCRIPT_DEBUG' ) || SCRIPT_DEBUG === false ) { + if ( substr( $url, - 3, 3 ) == '.js' ) { + $url_new = substr_replace( $url, '.min', - 3, 0 ); + } + if ( substr( $url, - 4, 4 ) == '.css' ) { + $url_new = substr_replace( $url, '.min', - 4, 0 ); + } + } + + if ( isset( $url_new ) && file_exists( str_replace( content_url(), WP_CONTENT_DIR, $url_new ) ) ) { + return $url_new; + } elseif ( $default_to_original ) { + return $url; + } else { + return false; + } + } + + /** + * Playing ping-pong with WooCommerce. They keep changing their script. + * + * @deprecated 4.7.18 + * + * @see https://github.com/woothemes/woocommerce/issues/3623 + */ + public static function get_placeholder_handle() { + $placeholder_handle = 'jquery-placeholder'; + + global $woocommerce; + if ( + class_exists( 'Woocommerce' ) && + version_compare( $woocommerce->version, '2.0.11', '>=' ) && + version_compare( $woocommerce->version, '2.0.13', '<=' ) + ) { + $placeholder_handle = 'tribe-placeholder'; + } + + return $placeholder_handle; + } +} diff --git a/tribe-common/src/Tribe/Template_Part_Cache.php b/tribe-common/src/Tribe/Template_Part_Cache.php new file mode 100755 index 0000000000..3a3e99ac64 --- /dev/null +++ b/tribe-common/src/Tribe/Template_Part_Cache.php @@ -0,0 +1,123 @@ +template = $template; + $this->key = $template . '_' . $id; + $this->expiration = $expiration; + $this->expiration_trigger = $expiration_trigger; + $this->cache = new Tribe__Cache(); + + $this->add_hooks(); + } + + /** + * Hook in to show cached content and bypass queries where needed + */ + public function add_hooks() { + + // set the cached html in transients after the template part is included + add_filter( 'tribe_get_template_part_content', [ $this, 'set' ], 10, 2 ); + + // get the cached html right before the setup_view runs so it's available for bypassing any view logic + add_action( 'tribe_events_before_view', [ $this, 'get' ], 9, 1 ); + + // when the specified template part is included, show the cached html instead + add_filter( 'tribe_get_template_part_path_' . $this->template, [ $this, 'display' ] ); + } + + /** + * Checks if there is a cached html fragment in the transients, if it's there, + * don't include the requested file path. If not, just return the file path like normal + * + * @param $path file path to the month view template part + * + * @return bool + * @uses tribe_get_template_part_path_[template] hook + */ + public function display( $path ) { + + if ( $this->html !== false ) { + echo $this->html; + + return false; + } + + return $path; + + } + + /** + * Set cached html in transients + * + * @param $html + * @param $template + * + * @return string + * @uses tribe_get_template_part_content hook + */ + public function set( $html, $template ) { + if ( $template == $this->template ) { + $this->cache->set_transient( $this->key, $html, $this->expiration, $this->expiration_trigger ); + } + + return $html; + } + + /** + * Retrieve the cached html from transients, set class property + * + * @uses tribe_events_before_view hook + */ + public function get() { + + if ( isset( $this->html ) ) { + + return $this->html; + } + + $this->html = $this->cache->get_transient( $this->key, $this->expiration_trigger ); + + return $this->html; + + } +} diff --git a/tribe-common/src/Tribe/Templates.php b/tribe-common/src/Tribe/Templates.php new file mode 100644 index 0000000000..9e0857cbb2 --- /dev/null +++ b/tribe-common/src/Tribe/Templates.php @@ -0,0 +1,79 @@ +is_main_query(); + } + + /** + * Look for the stylesheets. Fall back to $fallback path if the stylesheets can't be located or the array is empty. + * + * @param array|string $stylesheets Path to the stylesheet + * @param bool|string $fallback Path to fallback stylesheet + * + * @return bool|string Path to stylesheet + */ + public static function locate_stylesheet( $stylesheets, $fallback = false ) { + if ( ! is_array( $stylesheets ) ) { + $stylesheets = [ $stylesheets ]; + } + if ( empty( $stylesheets ) ) { + return $fallback; + } + foreach ( $stylesheets as $filename ) { + if ( file_exists( get_stylesheet_directory() . '/' . $filename ) ) { + $located = trailingslashit( get_stylesheet_directory_uri() ) . $filename; + break; + } else { + if ( file_exists( get_template_directory() . '/' . $filename ) ) { + $located = trailingslashit( get_template_directory_uri() ) . $filename; + break; + } + } + } + if ( empty( $located ) ) { + return $fallback; + } + + return $located; + } + + /** + * Add our own method is_embed to check by WordPress Version and function is_embed + * to prevent fatal errors in WordPress 4.3 and earlier + * + * @version 4.2.1 + */ + public static function is_embed() { + global $wp_version; + if ( version_compare( $wp_version, '4.4', '<' ) || ! function_exists( 'is_embed' ) ) { + return false; + } + + return is_embed(); + + } + +}//end class diff --git a/tribe-common/src/Tribe/Terms.php b/tribe-common/src/Tribe/Terms.php new file mode 100644 index 0000000000..7810dd9fb3 --- /dev/null +++ b/tribe-common/src/Tribe/Terms.php @@ -0,0 +1,56 @@ +to_array(); + } elseif ( is_numeric( $term ) ) { + $term = absint( $term ); + $term_info = get_term( $term, $taxonomy, ARRAY_A ); + } else { + $term_info = term_exists( $term, $taxonomy ); + } + + if ( ! $term_info ) { + // Skip if a non-existent term ID is passed. + if ( is_numeric( $term ) ) { + continue; + } + + if ( true == $create_missing ) { + $term_info = wp_insert_term( $term, $taxonomy ); + } else { + continue; + } + } + + if ( is_wp_error( $term_info ) ) { + continue; + } + + $term_ids[] = $term_info['term_id']; + } + + return array_unique( $term_ids ); + } +} diff --git a/tribe-common/src/Tribe/Timezones.php b/tribe-common/src/Tribe/Timezones.php new file mode 100644 index 0000000000..8af5da2531 --- /dev/null +++ b/tribe-common/src/Tribe/Timezones.php @@ -0,0 +1,625 @@ +format( 'T' ); + + // If PHP date "T" format is a -03 or +03, it's a bugged abbreviation, we can find it manually. + if ( 0 === strpos( $abbr, '-' ) || 0 === strpos( $abbr, '+' ) ) { + $abbreviations = timezone_abbreviations_list(); + + foreach ( $abbreviations as $abbreviation => $timezones ) { + foreach ( $timezones as $timezone ) { + if ( $timezone['timezone_id'] === $timezone_string ) { + return strtoupper( $abbreviation ); + } + } + } + } + } catch ( Exception $e ) { + $abbr = ''; + } + + return $abbr; + } + + /** + * Helper function to retrieve the timezone string for a given UTC offset + * + * This is a close copy of WooCommerce's wc_timezone_string() method + * + * @param string $offset UTC offset + * + * @return string + */ + public static function generate_timezone_string_from_utc_offset( $offset ) { + if ( ! self::is_utc_offset( $offset ) ) { + return $offset; + } + + // ensure we have the minutes on the offset + if ( ! strpos( $offset, ':' ) ) { + $offset .= ':00'; + } + + $offset = str_replace( 'UTC', '', $offset ); + + list( $hours, $minutes ) = explode( ':', $offset ); + $seconds = $hours * 60 * 60 + $minutes * 60; + + // attempt to guess the timezone string from the UTC offset + $timezone = timezone_name_from_abbr( '', $seconds, 0 ); + + if ( false === $timezone ) { + $is_dst = (bool) date( 'I' ); + + foreach ( timezone_abbreviations_list() as $abbr ) { + foreach ( $abbr as $city ) { + if ( + (bool) $city['dst'] === $is_dst + && intval( $city['offset'] ) === intval( $seconds ) + && $city['timezone_id'] + ) { + return $city['timezone_id']; + } + } + } + + // fallback to UTC + return 'UTC'; + } + + return $timezone; + } + + /** + * Tests to see if the timezone string is a UTC offset, ie "UTC+2". + * + * @param string $timezone + * + * @return bool + */ + public static function is_utc_offset( $timezone ) { + $timezone = trim( $timezone ); + return ( 0 === strpos( $timezone, 'UTC' ) && strlen( $timezone ) > 3 ); + } + + /** + * Returns a DateTimeZone object matching the representation in $tzstring where + * possible, or else representing UTC (or, in the worst case, false). + * + * If optional parameter $with_fallback is true, which is the default, then in + * the event it cannot find/create the desired timezone it will try to return the + * UTC DateTimeZone before bailing. + * + * @param string $tzstring + * @param bool $with_fallback = true + * + * @return DateTimeZone|false + */ + public static function get_timezone( $tzstring, $with_fallback = true ) { + if ( isset( self::$timezones[ $tzstring ] ) ) { + return self::$timezones[ $tzstring ]; + } + + try { + self::$timezones[ $tzstring ] = new DateTimeZone( $tzstring ); + return self::$timezones[ $tzstring ]; + } + catch ( Exception $e ) { + if ( $with_fallback ) { + return self::get_timezone( 'UTC', true ); + } + } + + return false; + } + + /** + * Confirms if the current timezone mode matches the $possible_mode. + * + * @param string $possible_mode + * + * @return bool + */ + public static function is_mode( $possible_mode ) { + return $possible_mode === self::mode(); + } + + /** + * Returns a string representing the timezone/offset currently desired for + * the display of dates and times. + * + * @return string + */ + public static function mode() { + $mode = self::EVENT_TIMEZONE; + + if ( 'site' === tribe_get_option( 'tribe_events_timezone_mode' ) ) { + $mode = self::SITE_TIMEZONE; + } + + return apply_filters( 'tribe_events_current_display_timezone', $mode ); + } + + /** + * Tries to convert the provided $datetime to UTC from the timezone represented by $tzstring. + * + * Though the usual range of formats are allowed, $datetime ordinarily ought to be something + * like the "Y-m-d H:i:s" format (ie, no timezone information). If it itself contains timezone + * data, the results may be unexpected. + * + * In those cases where the conversion fails to take place, the $datetime string will be + * returned untouched. + * + * @param string $datetime + * @param string $tzstring + * @param string $format The optional format of the resulting date, defaults to + * `Tribe__Date_Utils::DBDATETIMEFORMAT`. + * + * @return string + */ + public static function to_utc( $datetime, $tzstring, $format = null ) { + if ( self::is_utc_offset( $tzstring ) ) { + return self::apply_offset( $datetime, $tzstring, true ); + } + + $local = self::get_timezone( $tzstring ); + $utc = self::get_timezone( 'UTC' ); + + $new_datetime = date_create( $datetime, $local ); + + if ( $new_datetime ) { + $new_datetime->setTimezone( $utc ); + $format = ! empty( $format ) ? $format : Tribe__Date_Utils::DBDATETIMEFORMAT; + + return $new_datetime->format( $format ); + } + + // Fallback to the unmodified datetime if there was a failure during conversion + return $datetime; + } + + /** + * Tries to convert the provided $datetime to the timezone represented by $tzstring. + * + * This is the sister function of self::to_utc() - please review the docs for that method + * for more information. + * + * @param string $datetime + * @param string $tzstring + * + * @return string + */ + public static function to_tz( $datetime, $tzstring ) { + + if ( self::is_utc_offset( $tzstring ) ) { + + return self::apply_offset( $datetime, $tzstring ); + } + + $local = self::get_timezone( $tzstring ); + $utc = self::get_timezone( 'UTC' ); + + $new_datetime = date_create( $datetime, $utc ); + + if ( $new_datetime && $new_datetime->setTimezone( $local ) ) { + return $new_datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT ); + } + + // Fallback to the unmodified datetime if there was a failure during conversion + return $datetime; + } + + /** + * Localizes a date or timestamp using WordPress timezone and returns it in the specified format. + * + * @param string $format The format the date shouuld be formatted to. + * @param string|int $date The date UNIX timestamp or `strtotime` parseable string. + * @param string $timezone An optional timezone string identifying the timezone the date shoudl be localized + * to; defaults to the WordPress installation timezone (if available) or to the system + * timezone. + * + * @return string|bool The parsed date in the specified format and localized to the system or specified + * timezone, or `false` if the specified date is not a valid date string or timestamp + * or the specified timezone is not a valid timezone string. + */ + public static function localize_date( $format = null, $date = null, $timezone = null ) { + if ( empty( $timezone ) ) { + $timezone = self::wp_timezone_string(); + } + + $timezone = self::generate_timezone_string_from_utc_offset( $timezone ); + + try { + $timezone_object = new DateTimeZone( $timezone ); + + if ( Tribe__Date_Utils::is_timestamp( $date ) ) { + $date = new DateTime( "@{$date}" ); + } else { + $date = new DateTime( $date ); + } + } catch ( Exception $e ) { + return false; + } + + $date->setTimezone( $timezone_object ); + + return $date->format( $format ); + } + + /** + * Converts a date string or timestamp to a destination timezone. + * + * @param string|int $date Either a string parseable by the `strtotime` function or a UNIX timestamp. + * @param string $from_timezone The timezone of the source date. + * @param string $to_timezone The timezone the destination date should use. + * @param string $format The format that should be used for the destination date. + * + * @return string The formatted and converted date. + */ + public static function convert_date_from_timezone( $date, $from_timezone, $to_timezone, $format ) { + if ( ! Tribe__Date_Utils::is_timestamp( $date ) ) { + $from_date = new DateTime( $date, new DateTimeZone( $from_timezone ) ); + $timestamp = $from_date->format( 'U' ); + } else { + $timestamp = $date; + } + + $to_date = new DateTime( "@{$timestamp}", new DateTimeZone( $to_timezone ) ); + + return $to_date->format( $format ); + } + + /** + * Whether the candidate timezone is a valid PHP timezone or a supported UTC offset. + * + * @param string $candidate + * + * @return bool + */ + public static function is_valid_timezone( $candidate ) { + if ( self::is_utc_offset( $candidate ) ) { + return true; + } + try { + new DateTimeZone( $candidate ); + } catch ( Exception $e ) { + return false; + } + + return true; + } + + /** + * Given a string in the form "UTC+2.5" returns the corresponding DateTimeZone object. + * + * If this is not possible or if $utc_offset_string does not match the expected pattern, + * boolean false is returned. + * + * @todo revise to eliminate all of these: maybe_get_tz_name, apply_offset, timezone_from_utc_offset, and adjust_timestamp + * + * @since 4.6.3 + * + * @param string $utc_offset_string + * + * @return DateTimeZone | bool + */ + public static function timezone_from_utc_offset( $utc_offset_string ) { + // Test for strings looking like "UTC-2" or "UTC+5.25" etc + if ( ! preg_match( '/^UTC[+-][0-9.]{1,4}$/', $utc_offset_string ) ) { + return false; + } + + // Breakdown into polarity, hours and minutes + $parts = explode( '.', substr( $utc_offset_string, 4 ) ); + $hours = (int) $parts[ 0 ]; + $fraction = isset( $parts[ 1 ] ) ? '0.' . (int) $parts[ 1 ] : 0; + $minutes = $fraction * 60; + $polarity = substr( $utc_offset_string, 3, 1 ); + + // Reassemble in the form +/-hhmm (ie "-0200" or "+0930") + $utc_offset = sprintf( $polarity . "%'.02d%'.02d", $hours, $minutes ); + + if ( '+0000' === $utc_offset || '-0000' === $utc_offset ) { + $utc_offset = 'UTC'; + } + + // Use this to build a new DateTimeZone + try { + return new DateTimeZone( $utc_offset ); + } catch ( Exception $e ) { + return false; + } + } + + /** + * Applies an time offset to the specified date time. + * + * @todo revise to eliminate all of these: maybe_get_tz_name, apply_offset, timezone_from_utc_offset, and adjust_timestamp + * + * @param string $datetime The date and time string in a valid date format. + * @param int|string $offset (string or numeric offset) + * @param bool $invert = false Whether the offset should be added (`true`) or + * subtracted (`false`); signum operations carry over so + * `-(-23) = +23`. + * + * @return string + */ + public static function apply_offset( $datetime, $offset, $invert = false ) { + // Normalize + $offset = strtolower( trim( $offset ) ); + + // Strip any leading "utc" text if set + if ( 0 === strpos( $offset, 'utc' ) ) { + $offset = substr( $offset, 3 ); + } + + // It's possible no adjustment will be needed + if ( 0 === (int) $offset ) { + return $datetime; + } + + // if the offset contains fractions like :15, :30 or :45 convert them + $supported_offsets = [ + '/:15$/' => '.25', + '/:30$/' => '.5', + '/:45$/' => '.75', + ]; + $offset = preg_replace( array_keys( $supported_offsets ), array_values( $supported_offsets ), $offset ); + + // Convert the offset to minutes for easier handling of fractional offsets + $offset = (int) ( $offset * 60 ); + + // Invert the offset? Useful for stripping an offset that has already been applied + if ( $invert ) { + $offset *= - 1; + } + + if ( $offset > 0 ) { + $offset = '+' . $offset; + } + + $offset = $offset . ' minutes'; + + $offset_datetime = date_create( $datetime ); + + if ( $offset_datetime && $offset_datetime->modify( $offset ) ) { + return $offset_datetime->format( Tribe__Date_Utils::DBDATETIMEFORMAT ); + } + + return $datetime; + } + + /** + * Try to figure out the Timezone name base on offset + * + * @since 4.0.7 + * + * @todo revise to eliminate all of these: maybe_get_tz_name, apply_offset, timezone_from_utc_offset, and adjust_timestamp + * + * @param string|int|float $timezone The timezone + * + * @return string The Guessed Timezone String + */ + public static function maybe_get_tz_name( $timezone ) { + if ( ! self::is_utc_offset( $timezone ) && ! is_numeric( $timezone ) ) { + return $timezone; + } + + if ( ! is_numeric( $timezone ) ) { + $offset = str_replace( 'utc', '', trim( strtolower( $timezone ) ) ); + } else { + $offset = $timezone; + } + + + // try to get timezone from gmt_offset, respecting daylight savings + $timezone = timezone_name_from_abbr( null, $offset * 3600, true ); + + // if that didn't work, maybe they don't have daylight savings + if ( false === $timezone ) { + $timezone = timezone_name_from_abbr( null, $offset * 3600, false ); + } + + // and if THAT didn't work, round the gmt_offset down and then try to get the timezone respecting daylight savings + if ( false === $timezone ) { + $timezone = timezone_name_from_abbr( null, (int) $offset * 3600, true ); + } + + // lastly if that didn't work, round the gmt_offset down and maybe that TZ doesn't do daylight savings + if ( false === $timezone ) { + $timezone = timezone_name_from_abbr( null, (int) $offset * 3600, false ); + } + + return $timezone; + } + + /** + * Accepts a unix timestamp and adjusts it so that when it is used to constitute + * a new datetime string, that string reflects the designated timezone. + * + * @todo revise to eliminate all of these: maybe_get_tz_name, apply_offset, timezone_from_utc_offset, and adjust_timestamp + * + * @deprecated 4.7.12 + * + * @param string $unix_timestamp + * @param string $tzstring + * + * @return string + */ + public static function adjust_timestamp( $unix_timestamp, $tzstring ) { + try { + $local = self::get_timezone( $tzstring ); + + $datetime = date_create_from_format( 'U', $unix_timestamp )->format( Tribe__Date_Utils::DBDATETIMEFORMAT ); + + // We prefer format('U') to getTimestamp() here due to our requirement for compatibility with PHP 5.2 + return date_create_from_format( 'Y-m-d H:i:s', $datetime, $local )->format( 'U' ); + } + catch( Exception $e ) { + return $unix_timestamp; + } + } + + /** + * Returns a valid timezone object built from the passed timezone or from the + * site one if a timezone in not passed. + * + * @since 4.9.5 + * + * @param string|null|DateTimeZone $timezone A DateTimeZone object, a timezone string + * or `null` to build an object using the site one. + * + * @return DateTimeZone The built DateTimeZone object. + */ + public static function build_timezone_object( $timezone = null ) { + if ( $timezone instanceof DateTimeZone ) { + return $timezone; + } + + /** @var Tribe__Cache $cache */ + $cache = tribe('cache'); + + if ( is_string( $timezone ) && $cached = $cache[ __METHOD__ . $timezone ] ) { + return clone $cached; + } + + $timezone = null === $timezone ? self::wp_timezone_string() : $timezone; + + try { + $object = new DateTimeZone( self::get_valid_timezone( $timezone ) ); + } catch ( Exception $e ) { + return new DateTimeZone( 'UTC' ); + } + + if ( is_string( $timezone ) ) { + $cache[ __METHOD__ . $timezone ] = $object; + } + + return $object; + } + + /** + * Parses the timezone string to validate or convert it into a valid one. + * + * @since 4.9.5 + * + * @param string|\DateTimeZone $timezone_candidate The timezone string candidate. + * + * @return string The validated timezone string or a valid timezone string alternative. + */ + public static function get_valid_timezone( $timezone_candidate ) { + if ( $timezone_candidate instanceof DateTimeZone ) { + return $timezone_candidate->getName(); + } + + $timezone_string = preg_replace( '/[+-]0$/', '', $timezone_candidate ); + $timezone_string = self::is_utc_offset( $timezone_string ) + ? self::generate_timezone_string_from_utc_offset( $timezone_string ) + : $timezone_string; + + return $timezone_string; + } +} diff --git a/tribe-common/src/Tribe/Tooltip/View.php b/tribe-common/src/Tribe/Tooltip/View.php new file mode 100644 index 0000000000..f1cab9b35a --- /dev/null +++ b/tribe-common/src/Tribe/Tooltip/View.php @@ -0,0 +1,138 @@ +set_template_origin( \Tribe__Main::instance() ); + $this->set_template_folder( 'src/views/tooltip' ); + + // Configures this templating class to extract variables + $this->set_template_context_extract( true ); + + // Uses the public folders + $this->set_template_folder_lookup( true ); + } + + /** + * Public wrapper for build method + * + * @since 4.9.8 + * + * @param array|string $message Array of messages or single message as string. + * @param array $args { + * List of arguments to override tooltip template. + * + * @var array $context Any additional context data you need to expose to this file (optional). + * @var string $classes Additional classes for the icon span (optional). + * @var string $direction Direction the tooltip should be from the trigger (down). + * @var string $icon dashicon classname to use, without the `dashicon-` (info). + * @var string $wrap_classes Classes for the tooltip wrapper (optional). + * } + * @return string A string of html for the tooltip. + */ + public function render_tooltip( $message, $args = [] ) { + if ( empty( $message ) ) { + return; + } + + /** @var \Tribe__Assets $assets */ + $assets = tribe( 'assets' ); + $assets->enqueue_group( 'tribe-tooltip' ); + + $html = $this->build_tooltip( $message, $args ); + + return $html; + } + + /** + * Factory method for tooltip HTML + * + * @since 4.9.8 + * + * @param array|string $message array of messages or single message as string. + * @param array $args { + * List of arguments to override tooltip template. + * + * @var array $context Any additional context data you need to expose to this file (optional). + * @var string $classes Additional classes for the icon span (optional). + * @var string $direction Direction the tooltip should be from the trigger (down). + * @var string $icon dashicon classname to use, without the `dashicon-` (info). + * @var string $wrap_classes Classes for the tooltip wrapper (optional). + * } + * @return string A string of html for the tooltip. + */ + private function build_tooltip( $message, $original_args ) { + $default_args = [ + 'classes' => '', + 'context' => '', + 'direction' => 'down', + 'icon' => 'info', + 'wrap_classes' => '', + ]; + + $args = wp_parse_args( $original_args, $default_args ); + + // Check for message to be passed. + if ( empty( $message ) ) { + return ''; + } + + // Setup message as an array of messages + $messages = (array) $message; + + $args['messages'] = $messages; + + ob_start(); + + /** + * Allow us to filter the tooltip template + * + * @since 4.9.8 + * + * @param string $template The tooltip template name. + * @param array $args Extra arguments, defaults include icon, classes, direction, and context. + */ + $template_name = apply_filters( 'tribe_tooltip_template', 'tooltip', $args ); + + $template = $this->template( $template_name, $args, false ); + + if ( ! empty( $template ) ) { + echo $template; + } + + $html = ob_get_clean(); + + /** + * Allow us to filter the tooltip output + * + * @since 4.9.8 + * + * @param string $html The tooltip HTML. + * @param array $messages An array of message strings. + * @param array $args Extra arguments, defaults include icon, classes, direction, and context. + */ + return apply_filters( 'tribe_tooltip_html', $html, $messages, $args ); + } + +} diff --git a/tribe-common/src/Tribe/Tracker.php b/tribe-common/src/Tribe/Tracker.php new file mode 100644 index 0000000000..2d43c1f0e2 --- /dev/null +++ b/tribe-common/src/Tribe/Tracker.php @@ -0,0 +1,467 @@ +$field ) ) { + return false; + } + + if ( isset( $new->$field ) && ! isset( $old->$field ) ) { + return true; + } + + if ( $new->$field !== $old->$field ) { + return true; + } + + return false; + } + + /** + * Get the date(timestamp) of last modification for a tracked field. + * + * @since 4.12.3 + * + * @param string $meta_key The key for the meta field we're interested in. + * @param int $post_id The ID of the post to check. + * + * @return boolean|string The change timestamp or false if the field is not found/empty. + */ + public function get_modified_date( $meta_key, $post_id ) { + $modified = get_post_meta( $post_id, self::$field_key, true ); + + // If the key is missing or empty/null return false - no recorded change. + return Tribe__Utils__Array::get( $modified, $meta_key, false ); + } + + /** + * Easy way to see currently which post types are being tracked by our code. + * + * @return array + */ + public function get_post_types() { + // By default we are not tracking anything + $tracked_post_types = []; + + /** + * Adds a way for Developers to add and remove which post types will be tracked + * + * Note: Removing any of the default methods will affect how we deal with fields + * affected by the authority settings defined on this installation + * + * @var array + */ + $tracked_post_types = (array) apply_filters( 'tribe_tracker_post_types', $this->tracked_post_types ); + + return $tracked_post_types; + } + + /** + * Easy way to see currenlty which meta values are been tracked by our code + * + * @return array + */ + public function get_excluded_meta_keys() { + // By default we are not tracking anything + $excluded_keys = [ + '_edit_lock', + self::$field_key, + ]; + + /** + * Adds a way for Developers remove Meta Keys that shouldn't be tracked + * + * Note: Removing any of the default methods will affect how we deal with fields + * affected by the authority settings defined on this installation + * + * @var array + */ + $excluded_keys = (array) apply_filters( 'tribe_tracker_excluded_meta_keys', $excluded_keys ); + + return $excluded_keys; + } + + /** + * Make sure we are tracking all meta fields related on the correct Post Types + * + * @since 4.5 + * + * @param int $meta_id Meta ID + * @param int $post_id Post ID. + * @param string $meta_key Meta key. + */ + public function register_added_deleted_meta( $meta_id, $post_id, $meta_key ) { + /** + * Allows toggling the Modified fields tracking + * @var bool + */ + $is_tracking_modified_fields = (bool) apply_filters( 'tribe_tracker_enabled', true ); + + // Bail if we shouldn't be tracking modifications + if ( false === $is_tracking_modified_fields ) { + return; + } + + // Try to fetch the post object + $post = get_post( $post_id ); + + // We only go forward if we have the Post Object + if ( ! $post instanceof WP_Post ) { + return; + } + + // Fetch from a unified method which meta keys are been excluded + $excluded_keys = $this->get_excluded_meta_keys(); + + // Bail when this meta is set to be excluded + if ( in_array( $meta_key, $excluded_keys ) ) { + return; + } + + // Fetch from a unified method which post types are been tracked + $tracked_post_types = $this->get_post_types(); + + // Only track if the meta is from a post that is been tracked + if ( ! in_array( $post->post_type, $tracked_post_types ) ) { + return; + } + + // Gets the Current Timestamp + $now = current_time( 'timestamp' ); + + // Fetch the current data from the modified fields + $modified = get_post_meta( $post->ID, self::$field_key, true ); + if ( ! is_array( $modified ) ) { + $modified = []; + } + + // If we got here we will update the Modified Meta + $modified[ $meta_key ] = $now; + + // Actually do the Update + update_post_meta( $post->ID, self::$field_key, $modified ); + } + + /** + * Make sure we are tracking all meta fields related to the correct Post Types + * + * @since 4.5 + * + * @param null|bool $check Whether to allow updating metadata for the given type. + * @param int $post_id Post ID. + * @param string $meta_key Meta key. + * @param mixed $meta_value Meta value. Must be serializable if non-scalar. + * @param mixed $prev_value Previous Value of the Meta, allowing to check the data + * + * @return null|bool This should be ignored, only used to not break the WordPress filters + */ + public function filter_watch_updated_meta( $check, $post_id, $meta_key, $meta_value, $prev_value = null ) { + /** + * Allows toggling the Modified fields tracking + * @var bool + */ + $is_tracking_modified_fields = (bool) apply_filters( 'tribe_tracker_enabled', true ); + + // Bail if we shouldn't be tracking modifications + if ( false === $is_tracking_modified_fields ) { + return $check; + } + + // Matching the WordPress filter, we actually don't care about Check at all! + if ( null !== $check ) { + return (bool) $check; + } + + // Try to fetch the post object + $post = get_post( $post_id ); + + // We only go forward if we have the Post Object + if ( ! $post instanceof WP_Post ) { + return $check; + } + + // Fetch from a unified method which meta keys are been excluded + $excluded_keys = $this->get_excluded_meta_keys(); + + // Bail when this meta is set to be excluded + if ( in_array( $meta_key, $excluded_keys ) ) { + return $check; + } + + // Fetch from a unified method which post types are been tracked + $tracked_post_types = $this->get_post_types(); + + // Only track if the meta is from a post that is been tracked + if ( ! in_array( $post->post_type, $tracked_post_types ) ) { + return $check; + } + + if ( empty( $prev_value ) ) { + $prev_value = get_post_meta( $post->ID, $meta_key, true ); + } + + // We don't care if the value didn't actually change + if ( $prev_value == $meta_value ) { + return $check; + } + + // Gets the Current Timestamp + $now = current_time( 'timestamp' ); + + // Fetch the current data from the modified fields + $modified = get_post_meta( $post->ID, self::$field_key, true ); + if ( ! is_array( $modified ) ) { + $modified = []; + } + + // If we got here we will update the Modified Meta + $modified[ $meta_key ] = $now; + + // Actually do the Update + update_post_meta( $post->ID, self::$field_key, $modified ); + + // We need to return this, because we are still on a filter + return $check; + } + + /** + * Tracks fields that are changed when an event is updated + * + * @param int $post_id Post ID + * @param WP_Post $post_after New post object + * @param WP_Post $post_before Old post object + */ + public function filter_watch_post_fields( $post_id, $post_after, $post_before ) { + /** + * Allows toggling the Modified fields tracking + * @var bool + */ + $is_tracking_modified_fields = (bool) apply_filters( 'tribe_tracker_enabled', true ); + + // Bail if we shouldn't be tracking modifications + if ( false === $is_tracking_modified_fields ) { + return; + } + + // Fetch from a unified method which post types are been tracked + $tracked_post_types = $this->get_post_types(); + + // Only track if the meta is from a post that is been tracked + if ( ! in_array( $post_before->post_type, $tracked_post_types ) ) { + return; + } + + // Fetch the current Time + $now = current_time( 'timestamp' ); + + if ( ! $modified = get_post_meta( $post_id, self::$field_key, true ) ) { + $modified = []; + } + + $fields_to_check_for_changes = [ + 'post_title', + 'post_content', + 'post_excerpt', + 'post_status', + 'post_type', + 'post_parent', + ]; + + foreach ( $fields_to_check_for_changes as $field ) { + if ( ! $this->has_field_changed( $field, $post_after, $post_before ) ) { + continue; + } + + $modified[ $field ] = $now; + } + + if ( $modified ) { + update_post_meta( $post_id, self::$field_key, $modified ); + } + } + + /** + * Track term changes for the tracked post types and terms. + * + * Meant to run on the `set_object_terms` action. + * + * @see wp_set_object_terms() + * + * @param $object_id + * @param $terms + * @param $tt_ids + * @param $taxonomy + * @param $append + * @param $old_tt_ids + * + * @return bool `true` if the post type and taxonomy are tracked, `false` otherwise. + */ + public function track_taxonomy_term_changes( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) { + /** + * Allows toggling the post taxonomy terms tracking + * + * @var bool $track_terms Whether the class is currently tracking terms or not. + */ + $is_tracking_taxonomy_terms = (bool) apply_filters( 'tribe_tracker_enabled_for_terms', $this->track_terms ); + + if ( false === $is_tracking_taxonomy_terms ) { + return false; + } + + $tracked_post_types = $this->get_post_types(); + + $post_id = tribe_post_exists( $object_id ); + + if ( + empty( $post_id ) + || ! ( $post = get_post( $post_id ) ) + || ! in_array( $post->post_type, $tracked_post_types ) + ) { + return false; + } + + $tracked_taxonomies = $this->get_taxonomies(); + + if ( ! in_array( $taxonomy, $tracked_taxonomies ) ) { + return false; + } + + if ( ! $modified = get_post_meta( $post->ID, self::$field_key, true ) ) { + $modified = []; + } + + if ( $tt_ids == $old_tt_ids ) { + // nothing to update, still we did the job + return true; + } + + $modified[ $taxonomy ] = time(); + update_post_meta( $post->ID, self::$field_key, $modified ); + + return true; + } + + /** + * Easy way to see currently which taxonomies are been tracked by our code. + * + * @return array + */ + public function get_taxonomies() { + /** + * Adds a way for Developers to add and remove which taxonomies will be tracked + * + * Note: Removing any of the default methods will affect how we deal with fields + * affected by the authority settings defined on this installation + * + * @var array $tracked_taxonomies An array of the tracker taxonomies names. + */ + $tracked_taxonomies = (array) apply_filters( 'tribe_tracker_taxonomies', $this->tracked_taxonomies ); + + return $tracked_taxonomies; + } + + /** + * Whether taxonomy term changes should be tracked or not by the class. + * + * @param bool $track_terms + */ + public function should_track_terms( $track_terms ) { + $this->track_terms = $track_terms; + } + + /** + * Sets the taxonomies the tracker should track. + * + * @param array $tracked_taxonomies + */ + public function set_tracked_taxonomies( array $tracked_taxonomies ) { + $this->tracked_taxonomies = $tracked_taxonomies; + } + + /** + * Sets the post types the tracker should track. + * + * @param array $tracked_post_types + */ + public function set_tracked_post_types( array $tracked_post_types ) { + $this->tracked_post_types = $tracked_post_types; + } + + /** + * Make sure to remove the changed field if the event is deleted to ensure there are no left meta fields when + * the event is deleted. + * + * @since 4.7.6 + * + * @param int Post ID + * @return bool + */ + public function cleanup_meta_fields( $post_id ) { + return delete_post_meta( (int) $post_id, self::$field_key ); + } +} diff --git a/tribe-common/src/Tribe/Traits/Cache_User.php b/tribe-common/src/Tribe/Traits/Cache_User.php new file mode 100644 index 0000000000..9d73bbc01c --- /dev/null +++ b/tribe-common/src/Tribe/Traits/Cache_User.php @@ -0,0 +1,145 @@ +warmup_cache( 'computation', WEEK_IN_SECONDS, 'save_post' ); + * if( isset( $this->computation_cache[$key] ) ){ + * return $this->computation_cache[$key]; + * } + * + * $computated = 23; + * + * $this->computation_cache[$key] = $computated; + * + * return $computated; + * } + * } + * ``` + * + * @package Tribe + */ + +namespace Tribe\Traits; + +/** + * Class Cache_User + * + * @since 4.9.11 + * + * @package Tribe + */ +trait Cache_User { + + + /** + * An array of caches and data for each key. + * + * @var array + */ + protected $caches = []; + + /** + * Dumps the temporary cache to the persistent one. + */ + public function dump_cache() { + foreach ( $this->caches as $key => $cache ) { + + list( $cache, $prefix, $expiration, $expiration_trigger ) = array_values( $this->caches[ $key ] ); + + if ( isset( $this->{$key . '_cache'} ) ) { + /** @var \Tribe__Cache $cache */ + $cache->set( $prefix . $key, + $this->{$key . '_cache'}, + $expiration, + $expiration_trigger + ); + } + } + } + + /** + * Warms up one of the caches used by the class, if not warmed up already. + * + * @since 4.9.11 + * + * @param string $key The key of the cache to warm up. + * @param int $expiration The expiration, in seconds, to set on the cache. + * @param string $expiration_trigger The expiration trigger to set on the cache; this should be one of those + * supported by the `Tribe__Cache_Listener` class. + * + * @see \Tribe__Cache_Listener::add_hooks() + */ + protected function warmup_cache( $key, $expiration = 0, $expiration_trigger = '' ) { + if ( ! isset( $this->caches[ $key ] ) ) { + $this_class = get_class( $this ); + + if ( ! property_exists( $this, $key . '_cache' ) ) { + throw new \BadMethodCallException( + sprintf( + 'The %s class should explicitly define a "%s" property to use the %s trait.', + $this_class, + $key . '_cache', + __TRAIT__ + ) + ); + } + + $this->caches[ $key ] = [ + 'cache_object' => tribe( 'cache' ), + 'prefix' => $this_class, + 'expiration' => $expiration, + 'expiration_trigger' => $expiration_trigger, + ]; + } + + list( $cache, $prefix, $expiration, $expiration_trigger ) = array_values( $this->caches[ $key ] ); + + if ( null === $this->{$key . '_cache'} ) { + /** @var \Tribe__Cache $cache */ + $this->{$key . '_cache'} = $cache->get( + $prefix . $key, + $expiration_trigger, + [], + $expiration + ); + if ( false === $this->{$key . '_cache'} ) { + $this->{$key . '_cache'} = []; + } + } + } + + /** + * Resets the instance caches for the this instance. + * + * @since 4.11.0 + * + * @return string[] A list of the emptied cache properties. + */ + public function reset_caches() { + $emptied = []; + foreach ( array_keys( $this->caches ) as $key ) { + $emptied[] = $key; + $this->{"{$key}_cache"} = []; + } + + return $emptied; + } +} diff --git a/tribe-common/src/Tribe/Traits/With_DB_Lock.php b/tribe-common/src/Tribe/Traits/With_DB_Lock.php new file mode 100644 index 0000000000..5eb8f28cca --- /dev/null +++ b/tribe-common/src/Tribe/Traits/With_DB_Lock.php @@ -0,0 +1,50 @@ +acquire_db_lock( $lock_key ); + } + + /** + * Releases the database lock of the record. + * + * Release a not held db lock will return `null`, not `false`. + * + * @since 4.12.6 + * + * @param string $lock_key The name of the lock to release. + * + * @return bool Whether the lock was correctly released or not. + */ + private function release_db_lock( $lock_key ) { + return tribe( 'db-lock' )->release_db_lock( $lock_key ); + } +} diff --git a/tribe-common/src/Tribe/Traits/With_Meta_Updates_Handling.php b/tribe-common/src/Tribe/Traits/With_Meta_Updates_Handling.php new file mode 100644 index 0000000000..f11e4a6570 --- /dev/null +++ b/tribe-common/src/Tribe/Traits/With_Meta_Updates_Handling.php @@ -0,0 +1,66 @@ +taxonomies ) ) { + // If we're here, then the developer made an error: throw an exception to bring this up as early as possible. + throw new \RuntimeException( + 'The ' . __TRAIT__ . ' trait requires the user class to define a $taxonomies array parameter.' + ); + } + + return in_array( $key, $this->taxonomies, true ); + } +} diff --git a/tribe-common/src/Tribe/Updater.php b/tribe-common/src/Tribe/Updater.php new file mode 100644 index 0000000000..d5b6119f20 --- /dev/null +++ b/tribe-common/src/Tribe/Updater.php @@ -0,0 +1,180 @@ +current_version = $current_version; + } + + /** + * We've had problems with the notoptions and + * alloptions caches getting out of sync with the DB, + * forcing an eternal update cycle + * + * @since 4.9.4 + * + */ + protected function clear_option_caches() { + wp_cache_delete( 'notoptions', 'options' ); + wp_cache_delete( 'alloptions', 'options' ); + } + + /** + * Run Updates for a Plugin + * + * @since 4.9.4 + * + */ + public function do_updates() { + $this->clear_option_caches(); + $updates = $this->get_update_callbacks(); + uksort( $updates, 'version_compare' ); + + try { + foreach ( $updates as $version => $callback ) { + + if ( ! $this->is_new_install() && version_compare( $version, $this->current_version, '<=' ) && $this->is_version_in_db_less_than( $version ) ) { + call_user_func( $callback ); + } + } + + foreach ( $this->get_constant_update_callbacks() as $callback ) { + call_user_func( $callback ); + } + + $this->update_version_option( $this->current_version ); + } catch ( Exception $e ) { + // fail silently, but it should try again next time + } + } + + /** + * Update Version Number for a Plugin + * + * @since 4.9.4 + * + * @param int $new_version the current version number of a plugin + */ + public function update_version_option( $new_version ) { + Tribe__Settings_Manager::set_option( $this->version_option, $new_version ); + } + + /** + * Returns an array of callbacks with version strings as keys. + * Any key higher than the version recorded in the DB + * and lower than $this->current_version will have its + * callback called. + * + * @since 4.9.4 + * + * @return array + */ + public function get_update_callbacks() { + return []; + } + + /** + * Returns an array of callbacks that should be called + * every time the version is updated + * + * @since 4.9.4 + * + * @return array + */ + public function get_constant_update_callbacks() { + return [ + [ $this, 'flush_rewrites' ], + ]; + } + + /** + * Get version from Tribe Settings for the Plugin + * + * @since 4.9.4 + * + * @return mixed the version number of the plugin saved in the options + */ + public function get_version_from_db() { + return Tribe__Settings_Manager::get_option( $this->version_option ); + } + + /** + * Returns true if the version in the DB is less than the provided version + * + * @since 4.9.4 + * + * @return boolean + */ + public function is_version_in_db_less_than( $version ) { + $version_in_db = $this->get_version_from_db(); + + return ( version_compare( $version, $version_in_db ) > 0 ); + } + + /** + * Returns true if this is a new install + * + * @since 4.9.4 + * + * @return boolean + */ + public function is_new_install() { + $version_in_db = $this->get_version_from_db(); + + return empty( $version_in_db ); + } + + /** + * Returns true if an update is required + * + * @since 4.9.4 + * + * @return boolean + */ + public function update_required() { + return $this->is_version_in_db_less_than( $this->current_version ); + } + + /** + * Flush Rewrite rules + * + * @since 4.9.4 + * + */ + public function flush_rewrites() { + // run after 'init' to ensure that all CPTs are registered + add_action( 'wp_loaded', 'flush_rewrite_rules' ); + } + + /** + * Reset update flags. All updates past $this->reset_version will + * run again on the next page load + * + * @since 4.9.4 + * + */ + public function reset() { + $this->update_version_option( $this->reset_version ); + } + +} diff --git a/tribe-common/src/Tribe/Utils/Array.php b/tribe-common/src/Tribe/Utils/Array.php new file mode 100644 index 0000000000..c9ede39602 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Array.php @@ -0,0 +1,671 @@ + $value ) { + if ( ! is_array( $value ) && ! is_object( $value ) ) { + $data[ $key ] = esc_attr( trim( $value ) ); + } + if ( is_array( $value ) ) { + $data[ $key ] = self::escape_multidimensional_array( $value ); + } + } + + return $data; + } + + /** + * Returns an array of values obtained by using the keys on the map; keys + * that do not have a match in map are discarded. + * + * To discriminate from not found results and legitimately `false` + * values from the map the `$found` parameter will be set by reference. + * + * @since 4.7.19 + * + * @param string|array $keys One or more keys that should be used to get + * the new values + * @param array $map An associative array relating the keys to the new + * values. + * @param bool $found When using a single key this argument will be + * set to indicate whether the mapping was successful + * or not. + * + * @return array|mixed|false An array of mapped values, a single mapped value when passing + * one key only or `false` if one key was passed but the key could + * not be mapped. + */ + public static function map_or_discard( $keys, array $map, &$found = true ) { + $hash = md5( time() ); + $mapped = []; + + foreach ( (array) $keys as $key ) { + $meta_key = Tribe__Utils__Array::get( $map, $key, $hash ); + if ( $hash === $meta_key ) { + continue; + } + $mapped[] = $meta_key; + } + + $found = (bool) count( $mapped ); + + if ( is_array( $keys ) ) { + return $mapped; + } + + return $found ? $mapped[0] : false; + } + + /** + * Duplicates any key prefixed with '_' creating an un-prefixed duplicate one. + * + * The un-prefixing and duplication is recursive. + * + * @since 4.9.5 + * + * @param mixed $array The array whose keys should be duplicated. + * @param bool $recursive Whether the un-prefixing and duplication should be + * recursive or shallow. + * + * @return array The array with the duplicate, unprefixed, keys or the + * original input if not an array. + */ + public static function add_unprefixed_keys_to( $array, $recursive = false ) { + if ( ! is_array( $array ) ) { + return $array; + } + + $unprefixed = []; + foreach ( $array as $key => $value ) { + if ( $recursive && is_array( $value ) ) { + $value = self::add_unprefixed_keys_to( $value, true ); + // And also add it to the original array. + $array[ $key ] = array_merge( $array[ $key ], $value ); + } + + if ( 0 !== strpos( $key, '_' ) ) { + continue; + } + $unprefixed[ substr( $key, 1 ) ] = $value; + } + + return array_merge( $array, $unprefixed ); + } + + /** + * Filters an associative array non-recursively, keeping only the values attached + * to keys starting with the specified prefix. + * + * @since 4.9.5 + * + * @param array $array The array to filter. + * @param string $prefix The prefix, or prefixes, of the keys to keep. + * + * @return array The filtered array. + */ + public static function filter_prefixed( array $array, $prefix ) { + $prefixes = implode( '|', array_map( 'preg_quote', (array) $prefix ) ); + $pattern = '/^(' . $prefixes . ')/'; + $filtered = []; + foreach ( $array as $key => $value ) { + if ( ! preg_match( $pattern, $key ) ) { + continue; + } + $filtered[ $key ] = $value; + } + + return $filtered; + } + + /** + * Flattens an array transforming each value that is an array and only contains one + * element into that one element. + * + * Typical use case is to flatten arrays like those returned by `get_post_meta( $id )`. + * Empty arrays are replaced with an empty string. + * + * @since 4.9.5 + * + * @param array $array The array to flatten. + * + * @return array The flattened array. + */ + public static function flatten( array $array ) { + foreach ( $array as $key => &$value ) { + if ( ! is_array( $value ) ) { + continue; + } + + $count = count( $value ); + + switch ( $count ) { + case 0: + $value = ''; + break; + case 1: + $value = reset( $value ); + break; + default: + break; + } + } + + return $array; + } + + /** + * Duplicates any key not prefixed with '_' creating a prefixed duplicate one. + * + * The prefixing and duplication is recursive. + * + * @since 4.9.5 + * + * @param mixed $array The array whose keys should be duplicated. + * @param bool $recursive Whether the prefixing and duplication should be + * recursive or shallow. + * + * @return array The array with the duplicate, prefixed, keys or the + * original input if not an array. + */ + public static function add_prefixed_keys_to( $array, $recursive = false ) { + if ( ! is_array( $array ) ) { + return $array; + } + + $prefixed = []; + foreach ( $array as $key => $value ) { + if ( $recursive && is_array( $value ) ) { + $value = self::add_prefixed_keys_to( $value, true ); + // And also add it to the original array. + $array[ $key ] = array_merge( $array[ $key ], $value ); + } + + if ( 0 === strpos( $key, '_' ) ) { + continue; + } + + $prefixed[ '_' . $key ] = $value; + } + + return array_merge( $array, $prefixed ); + } + + /** + * Recursively key-sort an array. + * + * @since 4.9.5 + * + * @param array $array The array to sort, modified by reference. + * + * @return bool The sorting result. + */ + public static function recursive_ksort( array &$array ) { + foreach ( $array as &$value ) { + if ( is_array( $value ) ) { + static::recursive_ksort( $value ); + } + } + + return ksort( $array ); + } + + /** + * Returns the value associated with the first index, among the indexes, that is set in the array.. + * + * @since 4.9.11 + * + * @param array $array The array to search. + * @param array $indexes The indexes to search; in order the function will look from the first to the last. + * @param null $default The value that will be returned if the array does not have any of the indexes set. + * + * @return mixed|null The set value or the default value. + */ + public static function get_first_set( array $array, array $indexes, $default = null ) { + foreach ( $indexes as $index ) { + if ( ! isset( $array[ $index ] ) ) { + continue; + } + + return $array[ $index ]; + } + + return $default; + } + + /** + * Discards everything other than array values having string keys and scalar values, ensuring a + * one-dimensional, associative array result. + * + * @link https://www.php.net/manual/language.types.array.php Keys cast to non-strings will be discarded. + * + * @since 4.12.2 + * + * @param array $array + * + * @return array Associative or empty array. + */ + public static function filter_to_flat_scalar_associative_array( array $array ) { + $result = []; + + if ( ! is_array( $array ) ) { + return $result; + } + + foreach ( $array as $k => $v ) { + if ( ! is_string( $k ) ) { + continue; + } + + if ( ! is_scalar( $v ) ) { + continue; + } + + $result[ $k ] = $v; + } + + return $result; + } + + /** + * Build an array from migrating aliased key values to their canonical key values, removing all alias keys. + * + * If the original array has values for both the alias and its canonical, keep the canonical's value and + * discard the alias' value. + * + * @since 4.12.2 + * + * @param array $original An associative array of values, such as passed shortcode arguments. + * @param array $alias_map An associative array of aliases: key as alias, value as mapped canonical. + * Example: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ] + * + * @return array + */ + public static function parse_associative_array_alias( array $original, array $alias_map ) { + // Ensure array values. + $original = (array) $original; + $alias_map = static::filter_to_flat_scalar_associative_array( (array) $alias_map ); + + // Fail gracefully if alias array wasn't setup as [ 'from' => 'to' ]. + if ( empty( $alias_map ) ) { + return $original; + } + + $result = $original; + + // Parse aliases. + foreach ( $alias_map as $from => $to ) { + // If this alias isn't in use, go onto the next. + if ( ! isset( $result[ $from ] ) ) { + continue; + } + + // Only allow setting alias value if canonical value is not already present. + if ( ! isset( $result[ $to ] ) ) { + $result[ $to ] = $result[ $from ]; + } + + // Always remove the alias key. + unset( $result[ $from ] ); + } + + return $result; + } + + /** + * Stringifies the numeric keys of an array. + * + * @since 4.12.14 + * + * @param array $input The input array whose keys should be stringified. + * @param string|null $prefix The prefix that should be use to stringify the keys, if not provided + * then it will be generated. + * + * @return array The input array with each numeric key stringified. + */ + public static function stringify_keys( array $input, $prefix = null ) { + $prefix = null === $prefix ? uniqid( 'sk_', true ) : $prefix; + $visitor = static function ( $key, $value ) use ( $prefix ) { + $string_key = is_numeric( $key ) ? $prefix . $key : $key; + + return [ $string_key, $value ]; + }; + + return static::array_visit_recursive( $input, $visitor ); + } + + /** + * The inverse of the `stringify_keys` method, it will restore numeric keys for previously + * stringified keys. + * + * @since 4.12.14 + * + * @param array $input The input array whose stringified keys should be + * destringified. + * @param string $prefix The prefix that should be used to target only specific string keys. + * + * @return array The input array, its stringified keys destringified. + */ + public static function destringify_keys( array $input, $prefix = 'sk_' ) { + $visitor = static function ( $key, $value ) use ( $prefix ) { + $destringified_key = 0 === self::strpos( $key, $prefix ) ? null : $key; + + return [ $destringified_key, $value ]; + }; + + return static::array_visit_recursive( $input, $visitor ); + } + + /** + * Recursively visits all elements of an array applying the specified callback to each element + * key and value. + * + * @since 4.12.14 + * + * @param array $input The input array whose nodes should be visited. + * @param callable $visitor A callback function that will be called on each array item; the callback will + * receive the item key and value as input and should return an array that contains + * the update key and value in the shape `[ , ]`. Returning a `null` + * key will cause the element to be removed from the array. + */ + public static function array_visit_recursive( $input, callable $visitor ) { + if ( ! is_array( $input ) ) { + return $input; + } + + $return = []; + + foreach ( $input as $key => &$value ) { + if ( is_array( $value ) ) { + $value = static::array_visit_recursive( $value, $visitor ); + } + // Ensure visitors can quickly return `null` to remove an element. + list( $updated_key, $update_value ) = array_replace( [ $key, $value ], (array) $visitor( $key, $value ) ); + if ( false === $updated_key ) { + // Visitor will be able to remove an element by returning a `false` key for it. + continue; + } + if ( null === $updated_key ) { + // Automatically assign the first available numeric index to the element. + $return[] = $update_value; + } else { + $return[ $updated_key ] = $update_value; + } + } + + return $return; + } + + /** + * Recursively remove associative, non numeric, keys from an array. + * + * @since 4.12.14 + * + * @param array $input The input array. + * + * @return array An array that only contains integer keys at any of its levels. + */ + public static function remove_numeric_keys_recursive( array $input ) { + return self::array_visit_recursive( + $input, + static function ( $key ) { + return is_numeric( $key ) ? false : $key; + } + ); + } + + /** + * Recursively remove numeric keys from an array. + * + * @since 4.12.14 + * + * @param array $input The input array. + * + * @return array An array that only contains non numeric keys at any of its levels. + */ + public static function remove_string_keys_recursive( array $input ) { + return self::array_visit_recursive( + $input, + static function ( $key ) { + return !is_numeric( $key ) ? false : $key; + } + ); + } + + /** + * Merges two or more arrays in the nested format used by WP_Query arguments preserving and merging them correctly. + * + * The method will recursively replace named keys and merge numeric keys. The method takes its name from its intended + * primary use, but it's not limited to query arguments only. + * + * @since 4.12.14 + * + * @param array ...$arrays A set of arrays to merge. + * + * @return array The recursively merged array. + */ + public static function merge_recursive_query_vars( array ...$arrays ) { + if ( ! count( $arrays ) ) { + return []; + } + + // Temporarily transform numeric keys to string keys generated with time-related randomness. + $stringified = array_map( [ static::class, 'stringify_keys' ], $arrays ); + // Replace recursive will recursively replace any entry that has the same string key, stringified keys will never match due to randomness. + $merged = array_replace_recursive( ...$stringified ); + + // Finally destringify the keys to return something that will resemble, in shape, the original arrays. + return static::destringify_keys( $merged ); + } + } +} diff --git a/tribe-common/src/Tribe/Utils/Body_Classes.php b/tribe-common/src/Tribe/Utils/Body_Classes.php new file mode 100644 index 0000000000..6e8b702811 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Body_Classes.php @@ -0,0 +1,350 @@ + true, 'class => false ] + * + * @var array + */ + protected $classes = []; + + /** + * Stores all the admin classes. + * In the format: ['class' => true, 'class => false ] + * + * @var array + */ + protected $admin_classes = []; + + /** + * Queue-aware method to get the classes array. + * Returns the array of classes to add. + * + * @since 4.12.6 + * + * @param string $queue The queue we want to get 'admin', 'display', 'all'. + * @return array A map of the classes for the queue. + */ + public function get_classes( $queue = 'display' ) { + switch( $queue ) { + case 'admin': + return $this->admin_classes; + break; + case 'all': + return array_merge( $this->classes, $this->admin_classes ); + break; + default: + return $this->classes; + break; + } + } + + /** + * Returns the array of classnames to add + * + * @since 4.12.6 + * + * @param string $queue The queue we want to get 'admin', 'display', 'all'. + * @return array The list of class names. + */ + public function get_class_names( $queue = 'display' ) { + $classes = $this->get_classes( $queue ); + + return array_keys( + array_filter( + $classes, + static function( $v ) { + return $v; + }, + ARRAY_FILTER_USE_KEY + ) + ); + } + + /** + * Checks if a class is in the queue, + * wether it's going to be added or not. + * + * @since 4.12.6 + * + * @param string $class The class we are checking for. + * @param string $queue The queue we want to check 'admin', 'display', 'all' + * @return boolean Whether a class exists or not in the queue. + */ + public function class_exists( $class, $queue = 'display' ) { + $classes = $this->get_classes( $queue ); + + return array_key_exists( $class, $classes ); + } + + /** + * Checks if a class is in the queue and going to be added. + * + * @since 4.12.6 + * + * @param string $class The class we are checking for. + * @param string $queue The queue we want to check 'admin', 'display', 'all' + * @return boolean Whether a class is currently queued or not. + */ + public function class_is_enqueued( $class, $queue = 'display' ) { + $classes = $this->get_classes( $queue ); + if ( ! $this->class_exists( $class, $queue ) ) { + return false; + } + + return $classes[ $class ]; + } + + /** + * Dequeues a class. + * + * @since 4.12.6 + * + * @param string $class + * @param string $queue The queue we want to alter 'admin', 'display', 'all' + * @return boolean + */ + public function dequeue_class( $class, $queue = 'display' ) { + if ( ! $this->class_exists( $class, $queue ) ) { + return false; + } + + if ( 'admin' !== $queue ) { + $this->classes[ $class ] = false; + } + + if ( 'display' !== $queue ) { + $this->admin_classes[ $class ] = false; + } + + return true; + + } + + /** + * Enqueues a class. + * + * @since 4.12.6 + * + * @param string $class + * @param string $queue The queue we want to alter 'admin', 'display', 'all' + * @return false + */ + public function enqueue_class( $class, $queue = 'display' ) { + if ( ! $this->class_exists( $class, $queue ) ) { + return false; + } + + if ( 'admin' !== $queue ) { + $this->classes[ $class ] = true; + } + + if ( 'display' !== $queue ) { + $this->admin_classes[ $class ] = true; + } + + return true; + } + + /** + * Add a single class to the queue. + * + * @since 4.12.6 + * + * @param string $class The class to add. + * @param string $queue The queue we want to alter 'admin', 'display', 'all' + * @return void + */ + public function add_class( $class, $queue = 'display' ) { + if ( empty( $class ) ) { + return; + } + + if ( is_array( $class ) ) { + $this->add_classes( $class, $queue ); + } elseif ( $this->should_add_body_class_to_queue( $class, $queue ) ) { + + $class = sanitize_html_class( $class ); + + if ( 'admin' !== $queue ) { + $this->classes[ $class ] = true ; + } + + if ( 'display' !== $queue ) { + $this->admin_classes[ $class ] = true ; + } + + } + } + + /** + * Add an array of classes to the queue. + * + * @since 4.12.6 + * + * @param array $class The classes to add. + * @return void + */ + public function add_classes( array $classes, $queue = 'display' ) { + foreach ( $classes as $key => $value ) { + // If the classes are passed as class => bool, only add ones set to true. + if ( is_bool( $value ) && false !== $value ) { + $this->add_class( $key, $queue ); + } else { + $this->add_class( $value, $queue ); + } + } + } + + /** + * Remove a single class from the queue. + * + * @since 4.12.6 + * + * @param string $class The class to remove. + * @return void + */ + public function remove_class( $class, $queue = 'display' ) { + if ( 'admin' !== $queue ) { + $this->classes = array_filter( + $this->classes, + static function( $k ) use ( $class ) { + return $k !== $class; + }, + ARRAY_FILTER_USE_KEY + ); + } + + if ( 'display' !== $queue ) { + $this->admin_classes = array_filter( + $this->admin_classes, + static function( $k ) use ( $class ) { + return $k !== $class; + }, + ARRAY_FILTER_USE_KEY + ); + } + } + + /** + * Remove an array of classes from the queue. + * + * @since 4.12.6 + * + * @param array $classes The classes to remove. + * @return void + */ + public function remove_classes( array $classes, $queue = 'display' ) { + if ( empty( $classes ) || ! is_array( $classes) ) { + return; + } + + foreach ( $classes as $class ) { + $this->remove_class( $class, $queue ); + } + } + + /** + * Adds the enqueued classes to the body class array. + * + * @since 4.12.6 + * + * @param array $classes An array of body class names. + * @return array Array of body classes. + */ + public function add_body_classes( $classes = [] ) { + // Make sure they should be added. + if( ! $this->should_add_body_classes( $this->get_class_names(), (array) $classes, 'display' ) ) { + return $classes; + } + + $element_classes = new Element_Classes( $this->get_class_names() ); + + return array_merge( $classes, $element_classes->get_classes() ); + } + + /** + * Adds the enqueued classes to the body class array. + * + * @since 4.12.6 + * + * @param string $classes The existing body class names. + * + * @return string String of admin body classes. + */ + public function add_admin_body_classes( $classes ) { + $existing_classes = explode( ' ', $classes ); + // Make sure they should be added. + if ( ! $this->should_add_body_classes( $this->get_class_names( 'admin' ), (array) $existing_classes, 'admin' ) ) { + // Ensure we return the current string on false! + return $classes; + } + + $element_classes = new Element_Classes( $this->get_class_names( 'admin' ) ); + + return implode( ' ', array_merge( $existing_classes, $element_classes->get_classes() ) ); + + } + + /** + * Should a individual class be added to the queue. + * + * @since 4.12.6 + * + * @param string $class The body class we wish to add. + * + * @return boolean Whether to add tribe body classes to the queue. + */ + private function should_add_body_class_to_queue( $class, $queue = 'display' ) { + /** + * Filter whether to add the body class to the queue or not. + * + * @since 4.12.6 + * + * @param boolean $add Whether to add the class to the queue or not. + * @param array $class The array of body class names to add. + * @param string $queue The queue we want to get 'admin', 'display', 'all'. + */ + return (bool) apply_filters( 'tribe_body_class_should_add_to_queue', false, $class, $queue ); + } + + /** + * Logic for whether the body classes, as a whole, should be added. + * + * @since 4.12.6 + * + * @param array $add_classes An array of body class names to add. + * @param array $existing_classes An array of existing body class names from WP. + * @param string $queue The queue we want to get 'admin', 'display', 'all'. + * + * @return boolean Whether to add tribe body classes. + */ + private function should_add_body_classes( array $add_classes, array $existing_classes, $queue ) { + /** + * Filter whether to add tribe body classes or not. + * + * @since 4.12.6 + * + * @param boolean $add Whether to add classes or not. + * @param array $add_classes The array of body class names to add. + * @param array $existing_classes An array of existing body class names from WP. + * @param string $queue The queue we want to get 'admin', 'display', 'all'. + * + */ + return (bool)apply_filters( 'tribe_body_classes_should_add', false, $queue, $add_classes, $existing_classes ); + } +} diff --git a/tribe-common/src/Tribe/Utils/Callback.php b/tribe-common/src/Tribe/Utils/Callback.php new file mode 100644 index 0000000000..e1efa13034 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Callback.php @@ -0,0 +1,177 @@ + $slug, + 'method' => $method, + 'arguments' => $arguments, + 'is_empty' => $is_empty, + ]; + + $key = md5( json_encode( $item ) ); + + // Prevent this from been reset + if ( isset( $this->items[ $key ] ) ) { + return $this->items[ $key ]; + } + + $item->callback = $container->callback( $item->slug, $item->method ); + + $this->items[ $key ] = $item; + + return [ $this, $this->prefix . $key ]; + } + + /** + * Returns the Value passed as a simple Routing method for tribe_callback_return + * + * @since 4.6.2 + * + * @param mixed $value Value to be Routed + * + * @return mixed + */ + public function return_value( $value ) { + return $value; + } + + /** + * Calls the Lambda function provided by Di52 to allow passing of Params without having to create more + * methods into classes for simple callbacks that will only have a pre-determined value. + * + * @since 4.6.2 + * + * @param string $slug A class or interface fully qualified name or a string slug. + * @param string $method The method that should be called on the resolved implementation with the + * specified array arguments. + * + * @return mixed The Return value used + */ + public function __call( $method, $args ) { + $key = str_replace( $this->prefix, '', $method ); + + if ( ! isset( $this->items[ $key ] ) ) { + return false; + } + + $item = $this->items[ $key ]; + + // Allow for previous compatibility with tribe_callback + if ( ! $item->is_empty ) { + $args = $item->arguments; + } + + return call_user_func_array( $item->callback, $args ); + } + + /** + * Tribe__Utils__Callback constructor. + * + * This is used to wrap a Tribe callable couple, a bound slug and method, to be used as a serializable callback. + * + * @since 4.9.5 + * + * @param string $slug The slug or class to call. + * @param string $method The method to call on the slug or class. + */ + public function __construct( $slug = null, $method = null ) { + $this->slug = $slug; + $this->method = $method; + } + + /** + * Returns the list of properties that should be serialized for the object. + + * + * @since 4.9.5 + * + * @return array An array of properties that should be serialized. + */ + public function __sleep() { + return [ 'slug', 'method' ]; + } + + /** + * Returns this callback slug or class. + * + * This only makes sense if this class is being used to wrap a Tribe callback couple (slug and method). + * + * @since 4.9.5 + * + * @return string|null This Tribe callback wrapper slug or class. + */ + public function get_slug() { + return $this->slug; + } + + /** + * Returns this callback method. + * + * This only makes sense if this class is being used to wrap a Tribe callback couple (slug and method). + * + * @since 4.9.5 + * + * @return string|null This Tribe callback method. + */ + public function get_method() { + + return $this->method; + } +} diff --git a/tribe-common/src/Tribe/Utils/Collection.php b/tribe-common/src/Tribe/Utils/Collection.php new file mode 100644 index 0000000000..aec8cb446f --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Collection.php @@ -0,0 +1,56 @@ +items = $items; + foreach ( $items as $item ) { + $this->push( $item ); + } + } + + /** + * Runs a callback function on all the collection items and returns the results. + * + * This is just a wrapper around the `array_map` method. + * + * @since 4.9.5 + * + * @param callable $callback The callback to run on each collection item. + * + * @return array An array of results returned by running the callback on all + * collection items. + */ + public function map( $callback ) { + return array_map( $callback, $this->items ); + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Utils/Collection_Interface.php b/tribe-common/src/Tribe/Utils/Collection_Interface.php new file mode 100644 index 0000000000..3dbcd6aec9 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Collection_Interface.php @@ -0,0 +1,57 @@ +all(); + + return reset( $items ); + } + + /** + * Returns the last item in the collection. + * + * @since 4.9.14 + * + * @return mixed The last item in the collection. + */ + public function last() { + $items = $this->all(); + + return end( $items ); + } + + /** + * Returns the nth item in the collection. + * + * @since 4.9.14 + * + * @param int $n The 1-based index of the item to return. It's not 0-based, `1` will return the first item. + * + * @return mixed|null The nth item in the collection or `null` if not set. + */ + public function nth( $n ) { + $items = array_values( $this->all() ); + + return isset( $items[ $n - 1 ] ) ? $items[ $n - 1 ] : null; + } + + /** + * {@inheritDoc} + */ + public function offsetExists( $offset ) { + $items = $this->all(); + + return isset( $items[ $offset ] ); + } + + /** + * {@inheritDoc} + */ + public function offsetGet( $offset ) { + $items = $this->all(); + + return isset( $items[ $offset ] ) + ? $items[ $offset ] + : null; + } + + /** + * {@inheritDoc} + */ + public function offsetSet( $offset, $value ) { + $this->items = $this->all(); + + $this->items[ $offset ] = $value; + } + + /** + * {@inheritDoc} + */ + public function offsetUnset( $offset ) { + $this->items = $this->all(); + + unset( $this->items[ $offset ] ); + } + + /** + * {@inheritDoc} + */ + public function next() { + $this->items_index ++; + } + + /** + * {@inheritDoc} + */ + public function valid() { + $items = $this->all(); + + return ( isset( $items[ $this->items_index ] ) ); + } + + /** + * {@inheritDoc} + */ + public function key() { + return $this->items_index; + } + + /** + * {@inheritDoc} + */ + public function current() { + $items = array_values( $this->all() ); + + return isset( $items[ $this->items_index ] ) ? $items[ $this->items_index ] : null; + } + + /** + * {@inheritDoc} + */ + public function rewind() { + $this->items_index = 0; + } + + /** + * {@inheritDoc} + */ + public function count() { + return count( $this->all() ); + } + + /** + * {@inheritDoc} + */ + public function serialize() { + $to_serialize = $this->all(); + + if ( method_exists( $this, 'before_serialize' ) ) { + $to_serialize = $this->before_serialize( $this->all() ); + } + + return serialize( $to_serialize ); + } + + /** + * {@inheritDoc} + */ + public function unserialize( $serialized ) { + $to_unserialize = $serialized; + + if ( method_exists( $this, 'custom_unserialize' ) ) { + $this->items = $this->custom_unserialize( $to_unserialize ); + return; + } + + $this->items = unserialize( $to_unserialize ); + } + + /** + * {@inheritDoc} + */ + public function seek( $position ) { + $this->items_index = $position; + } + + /** + * Applies a filter callback to each element of this collection changing the collection elements to only those + * passing the filter. + * + * @since 4.10.2 + * + * @param callable $filter_callback The filter callback that will be applied to each element of the collection; the + * callback will receive the element as parameter. + * + * @return Collection_Trait A new collection instance, that contains only the elements that passed the filter. + */ + public function filter( $filter_callback ) { + if ( $this->count() === 0 ) { + // If there is nothing to filter to begin with, just return this. + return $this; + } + + $filtered = new static(); + $filtered->items = array_filter( $this->all(), $filter_callback ); + + return $filtered; + } +} diff --git a/tribe-common/src/Tribe/Utils/Color.php b/tribe-common/src/Tribe/Utils/Color.php new file mode 100644 index 0000000000..de5213278c --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Color.php @@ -0,0 +1,507 @@ + + * Info: http://mexitek.github.io/phpColors/ + */ + +/** + * PHP 5.2 Compatibility + * Author: Gustavo Bordoni + */ + +class Tribe__Utils__Color { + + private $_hex; + private $_hsl; + private $_rgb; + + /** + * Auto darkens/lightens by 10% for sexily-subtle gradients. + * Set this to FALSE to adjust automatic shade to be between given color + * and black (for darken) or white (for lighten) + */ + const DEFAULT_ADJUST = 10; + + /** + * Instantiates the class with a HEX value + * @param string $hex + * @throws Exception "Bad color format" + */ + public function __construct( $hex ) { + // Strip # sign is present + $color = str_replace( '#', '', $hex ); + + // Make sure it's 6 digits + if ( strlen( $color ) === 3 ) { + $color = preg_replace( '/(.)(.)(.)/', '$1$1$2$2$3$3', $color ); + } elseif ( strlen( $color ) != 6 ) { + throw new Exception( 'HEX color needs to be 6 or 3 digits long' ); + } + + $this->_hsl = self::hexToHsl( $color ); + $this->_hex = $color; + $this->_rgb = self::hexToRgb( $color ); + } + + // ==================== + // = Public Interface = + // ==================== + + /** + * Given a HEX string returns a HSL array equivalent. + * @param string $color + * @return array HSL associative array + */ + public static function hexToHsl( $color ) { + + // Sanity check + $color = self::_checkHex( $color ); + + // Convert HEX to DEC + $R = hexdec( $color[0] . $color[1] ); + $G = hexdec( $color[2] . $color[3] ); + $B = hexdec( $color[4] . $color[5] ); + + $HSL = []; + + $var_R = ( $R / 255 ); + $var_G = ( $G / 255 ); + $var_B = ( $B / 255 ); + + $var_Min = min( $var_R, $var_G, $var_B ); + $var_Max = max( $var_R, $var_G, $var_B ); + $del_Max = $var_Max - $var_Min; + + $L = ( $var_Max + $var_Min ) / 2; + + if ( 0 == $del_Max ) { + $H = 0; + $S = 0; + } else { + if ( $L < 0.5 ) { + $S = $del_Max / ( $var_Max + $var_Min ); + } else { + $S = $del_Max / ( 2 - $var_Max - $var_Min ); + } + + $del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; + $del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; + $del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; + + if ( $var_R == $var_Max ) { + $H = $del_B - $del_G; + } elseif ( $var_G == $var_Max ) { + $H = ( 1 / 3 ) + $del_R - $del_B; + } elseif ( $var_B == $var_Max ) { + $H = ( 2 / 3 ) + $del_G - $del_R; + } + + if ( $H < 0 ) { + $H++; + } + if ( $H > 1 ) { + $H--; + } + } + + $HSL['H'] = ( $H * 360 ); + $HSL['S'] = $S; + $HSL['L'] = $L; + + return $HSL; + } + + /** + * Given a HSL associative array returns the equivalent HEX string + * @param array $hsl + * @return string HEX string + * @throws Exception "Bad HSL Array" + */ + public static function hslToHex( $hsl = [] ) { + // Make sure it's HSL + if ( empty( $hsl ) || ! isset( $hsl['H'] ) || ! isset( $hsl['S'] ) || ! isset( $hsl['L'] ) ) { + throw new Exception( 'Param was not an HSL array' ); + } + + list( $H, $S, $L ) = [ $hsl['H'] / 360, $hsl['S'], $hsl['L'] ]; + + if ( 0 == $S ) { + $r = $L * 255; + $g = $L * 255; + $b = $L * 255; + } else { + if ( $L < 0.5 ) { + $var_2 = $L * ( 1 + $S ); + } else { + $var_2 = ( $L + $S ) - ( $S * $L ); + } + + $var_1 = 2 * $L - $var_2; + + $r = round( 255 * self::_huetorgb( $var_1, $var_2, $H + ( 1 / 3 ) ) ); + $g = round( 255 * self::_huetorgb( $var_1, $var_2, $H ) ); + $b = round( 255 * self::_huetorgb( $var_1, $var_2, $H - ( 1 / 3 ) ) ); + + } + + // Convert to hex + $r = dechex( $r ); + $g = dechex( $g ); + $b = dechex( $b ); + + // Make sure we get 2 digits for decimals + $r = ( strlen( '' . $r ) === 1 ) ? '0' . $r : $r; + $g = ( strlen( '' . $g ) === 1 ) ? '0' . $g : $g; + $b = ( strlen( '' . $b ) === 1 ) ? '0' . $b : $b; + + return $r.$g.$b; + } + + + /** + * Given a HEX string returns a RGB array equivalent. + * @param string $color + * @return array RGB associative array + */ + public static function hexToRgb( $color ) { + + // Sanity check + $color = self::_checkHex( $color ); + + // Convert HEX to DEC + $R = hexdec( $color[0] . $color[1] ); + $G = hexdec( $color[2] . $color[3] ); + $B = hexdec( $color[4] . $color[5] ); + + $RGB['R'] = $R; + $RGB['G'] = $G; + $RGB['B'] = $B; + + return $RGB; + } + + + /** + * Given an RGB associative array returns the equivalent HEX string + * @param array $rgb + * @return string RGB string + * @throws Exception "Bad RGB Array" + */ + public static function rgbToHex( $rgb = [] ) { + // Make sure it's RGB + if ( empty( $rgb ) || ! isset( $rgb['R'] ) || ! isset( $rgb['G'] ) || ! isset( $rgb['B'] ) ) { + throw new Exception( 'Param was not an RGB array' ); + } + + // Convert RGB to HEX + $hex[0] = dechex( $rgb['R'] ); + $hex[1] = dechex( $rgb['G'] ); + $hex[2] = dechex( $rgb['B'] ); + + return implode( '', $hex ); + + } + + + /** + * Given a HEX value, returns a darker color. If no desired amount provided, then the color halfway between + * given HEX and black will be returned. + * @param int $amount + * @return string Darker HEX value + */ + public function darken( $amount = self::DEFAULT_ADJUST ) { + // Darken + $darkerHSL = $this->_darken( $this->_hsl, $amount ); + // Return as HEX + return self::hslToHex( $darkerHSL ); + } + + /** + * Given a HEX value, returns a lighter color. If no desired amount provided, then the color halfway between + * given HEX and white will be returned. + * @param int $amount + * @return string Lighter HEX value + */ + public function lighten( $amount = self::DEFAULT_ADJUST ) { + // Lighten + $lighterHSL = $this->_lighten( $this->_hsl, $amount ); + // Return as HEX + return self::hslToHex( $lighterHSL ); + } + + /** + * Given a HEX value, returns a mixed color. If no desired amount provided, then the color mixed by this ratio + * @param string $hex2 Secondary HEX value to mix with + * @param int $amount = -100..0..+100 + * @return string mixed HEX value + */ + public function mix( $hex2, $amount = 0 ) { + $rgb2 = self::hexToRgb( $hex2 ); + $mixed = $this->_mix( $this->_rgb, $rgb2, $amount ); + + // Return as HEX + return self::rgbToHex( $mixed ); + } + + /** + * Creates an array with two shades that can be used to make a gradient + * @param int $amount Optional percentage amount you want your contrast color + * @return array An array with a 'light' and 'dark' index + */ + public function makeGradient( $amount = self::DEFAULT_ADJUST ) { + // Decide which color needs to be made + if ( $this->isLight() ) { + $lightColor = $this->_hex; + $darkColor = $this->darken( $amount ); + } else { + $lightColor = $this->lighten( $amount ); + $darkColor = $this->_hex; + } + + // Return our gradient array + return [ 'light' => $lightColor, 'dark' => $darkColor ]; + } + + + /** + * Returns whether or not given color is considered "light" + * @param string|Boolean $color + * @return boolean + */ + public function isLight( $color = false ) { + // Get our color + $color = ( $color ) ? $color : $this->_hex; + + // Calculate straight from rbg + $r = hexdec( $color[0] . $color[1] ); + $g = hexdec( $color[2] . $color[3] ); + $b = hexdec( $color[4] . $color[5] ); + + return ( ( $r * 299 + $g * 587 + $b * 114 ) / 1000 > 130 ); + } + + /** + * Returns whether or not a given color is considered "dark" + * @param string|Boolean $color + * @return boolean + */ + public function isDark( $color = false ) { + // Get our color + $color = ( $color ) ? $color:$this->_hex; + + // Calculate straight from rbg + $r = hexdec( $color[0] . $color[1] ); + $g = hexdec( $color[2] . $color[3] ); + $b = hexdec( $color[4] . $color[5] ); + + return ( ( $r * 299 + $g * 587 + $b * 114 ) / 1000 <= 130 ); + } + + /** + * Returns the complimentary color + * @return string Complementary hex color + * + */ + public function complementary() { + // Get our HSL + $hsl = $this->_hsl; + + // Adjust Hue 180 degrees + $hsl['H'] += ( $hsl['H'] > 180 ) ? -180 : 180; + + // Return the new value in HEX + return self::hslToHex( $hsl ); + } + + /** + * Returns your color's HSL array + */ + public function getHsl() { + return $this->_hsl; + } + /** + * Returns your original color + */ + public function getHex() { + return $this->_hex; + } + /** + * Returns your color's RGB array + */ + public function getRgb() { + return $this->_rgb; + } + + /** + * Returns the cross browser CSS3 gradient + * @param int $amount Optional: percentage amount to light/darken the gradient + * @param boolean $vintageBrowsers Optional: include vendor prefixes for browsers that almost died out already + * @param string $prefix Optional: prefix for every lines + * @param string $suffix Optional: suffix for every lines + * @link http://caniuse.com/css-gradients Resource for the browser support + * @return string CSS3 gradient for chrome, safari, firefox, opera and IE10 + */ + public function getCssGradient( $amount = self::DEFAULT_ADJUST, $vintageBrowsers = false, $suffix = '', $prefix = '' ) { + + // Get the recommended gradient + $g = $this->makeGradient( $amount ); + + $css = ''; + /* fallback/image non-cover color */ + $css .= "{$prefix}background-color: #".$this->_hex.";{$suffix}"; + + /* IE Browsers */ + $css .= "{$prefix}filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#".$g['light']."', endColorstr='#".$g['dark']."');{$suffix}"; + + /* Safari 4+, Chrome 1-9 */ + if ( $vintageBrowsers ) { + $css .= "{$prefix}background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#{$g['light']}), to(#{$g['dark']}));{$suffix}"; + } + + /* Safari 5.1+, Mobile Safari, Chrome 10+ */ + $css .= "{$prefix}background-image: -webkit-linear-gradient(top, #{$g['light']}, #{$g['dark']});{$suffix}"; + + /* Firefox 3.6+ */ + if ( $vintageBrowsers ) { + $css .= "{$prefix}background-image: -moz-linear-gradient(top, #{$g['light']}, #{$g['dark']});{$suffix}"; + } + + /* Opera 11.10+ */ + if ( $vintageBrowsers ) { + $css .= "{$prefix}background-image: -o-linear-gradient(top, #{$g['light']}, #{$g['dark']});{$suffix}"; + } + + /* Unprefixed version (standards): FF 16+, IE10+, Chrome 26+, Safari 7+, Opera 12.1+ */ + $css .= "{$prefix}background-image: linear-gradient(to bottom, #{$g['light']}, #{$g['dark']});{$suffix}"; + + // Return our CSS + return $css; + } + + // =========================== + // = Private Functions Below = + // =========================== + + + /** + * Darkens a given HSL array + * @param array $hsl + * @param int $amount + * @return array $hsl + */ + private function _darken( $hsl, $amount = self::DEFAULT_ADJUST ) { + // Check if we were provided a number + if ( $amount ) { + $hsl['L'] = ( $hsl['L'] * 100 ) - $amount; + $hsl['L'] = ( $hsl['L'] < 0 ) ? 0 : $hsl['L'] / 100; + } else { + // We need to find out how much to darken + $hsl['L'] = $hsl['L'] / 2 ; + } + + return $hsl; + } + + /** + * Lightens a given HSL array + * @param array $hsl + * @param int $amount + * @return array $hsl + */ + private function _lighten( $hsl, $amount = self::DEFAULT_ADJUST ) { + // Check if we were provided a number + if ( $amount ) { + $hsl['L'] = ( $hsl['L'] * 100 ) + $amount; + $hsl['L'] = ( $hsl['L'] > 100 ) ? 1 : $hsl['L'] / 100; + } else { + // We need to find out how much to lighten + $hsl['L'] += ( 1 - $hsl['L'] ) / 2; + } + + return $hsl; + } + + /** + * Mix 2 rgb colors and return an rgb color + * @param array $rgb1 + * @param array $rgb2 + * @param int $amount ranged -100..0..+100 + * @return array $rgb + * + * ported from http://phpxref.pagelines.com/nav.html?includes/class.colors.php.source.html + */ + private function _mix( $rgb1, $rgb2, $amount = 0 ) { + + $r1 = ( $amount + 100 ) / 100; + $r2 = 2 - $r1; + + $rmix = ( ( $rgb1['R'] * $r1 ) + ( $rgb2['R'] * $r2 ) ) / 2; + $gmix = ( ( $rgb1['G'] * $r1 ) + ( $rgb2['G'] * $r2 ) ) / 2; + $bmix = ( ( $rgb1['B'] * $r1 ) + ( $rgb2['B'] * $r2 ) ) / 2; + + return [ 'R' => $rmix, 'G' => $gmix, 'B' => $bmix ]; + } + + /** + * Given a Hue, returns corresponding RGB value + * @param int $v1 + * @param int $v2 + * @param int $vH + * @return int + */ + private static function _huetorgb( $v1, $v2, $vH ) { + if ( $vH < 0 ) { + $vH += 1; + } + + if ( $vH > 1 ) { + $vH -= 1; + } + + if ( ( 6 * $vH ) < 1 ) { + return ( $v1 + ( $v2 - $v1 ) * 6 * $vH ); + } + + if ( ( 2 * $vH ) < 1 ) { + return $v2; + } + + if ( ( 3 * $vH ) < 2 ) { + return ( $v1 + ( $v2 - $v1 ) * ( ( 2 / 3 ) - $vH ) * 6 ); + } + + return $v1; + + } + + /** + * You need to check if you were given a good hex string + * @param string $hex + * @return string Color + * @throws Exception "Bad color format" + */ + private static function _checkHex( $hex ) { + // Strip # sign is present + $color = str_replace( '#', '', $hex ); + + // Make sure it's 6 digits + if ( strlen( $color ) == 3 ) { + $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2]; + } elseif ( strlen( $color ) != 6 ) { + throw new Exception( 'HEX color needs to be 6 or 3 digits long' ); + } + + return $color; + } + +} diff --git a/tribe-common/src/Tribe/Utils/Coordinates_Provider.php b/tribe-common/src/Tribe/Utils/Coordinates_Provider.php new file mode 100644 index 0000000000..2928a27315 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Coordinates_Provider.php @@ -0,0 +1,134 @@ +http = ! empty( $https ) ? $https : _wp_http_get_object(); + } + + /** + * @param string|array $address + */ + public function provide_coordinates_for_address( $address ) { + + if ( is_array( $address ) ) { + $address = implode( ', ', array_filter( array_map( 'trim', $address ) ) ); + } + + $address = trim( $address ); + + if ( $location = $this->get_resolved( $address ) ) { + return $location; + } + + $base_request_url = trailingslashit( $this->get_google_api_base() ) . $this->get_google_api_json_format(); + $url = esc_url( add_query_arg( [ 'address' => $address ], $base_request_url ) ); + $response = $this->http->get( $url ); + + if ( is_wp_error( $response ) ) { + return false; + } + + $decoded = json_decode( $response['body'], true ); + + if ( empty( $decoded['status'] ) || 'OK' !== $decoded['status'] ) { + return false; + } + + if ( empty( $decoded['results'][0]['place_id'] ) || empty( $decoded['results'][0]['geometry']['location']['lat'] ) || empty( $decoded['results'][0]['geometry']['location']['lng'] ) ) { + return false; + } + + $location = $decoded['results'][0]['geometry']['location']; + + $updated_transient = array_merge( $this->get_transient(), [ $address => $location ] ); + set_transient( self::$transient_name, $updated_transient ); + $this->transient = $updated_transient; + + return $location; + } + + /** + * @return null|WP_Http + */ + public function get_http() { + return $this->http; + } + + protected function get_google_api_base() { + return self::$google_api_base; + } + + protected function get_google_api_json_format() { + return self::$google_api_json_format; + } + + protected function get_transient() { + if ( ! is_array( $this->transient ) ) { + $transient = get_transient( self::$transient_name ); + $this->transient = is_array( $transient ) ? $transient : []; + } + + return $this->transient; + } + + protected function get_resolved( $address ) { + $transient = $this->get_transient(); + + return isset( $transient[ $address ] ) ? $transient[ $address ] : false; + } +} diff --git a/tribe-common/src/Tribe/Utils/Date_I18n.php b/tribe-common/src/Tribe/Utils/Date_I18n.php new file mode 100644 index 0000000000..f61244626f --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Date_I18n.php @@ -0,0 +1,48 @@ +setTimestamp( $datetime->getTimestamp() ); + $date_object->setTimezone( $datetime->getTimezone() ); + return $date_object; + } + + /** + * Returns a translated string using the params from this DateTime instance. + * + * @since 4.11.0 + * + * @param string $date_format Format to be used in the translation. + * + * @return string Translated date. + */ + public function format_i18n( $date_format ) { + $unix_with_tz = $this->getTimestamp() + $this->getOffset(); + $translated = date_i18n( $date_format, $unix_with_tz ); + + return $translated; + } +} diff --git a/tribe-common/src/Tribe/Utils/Date_I18n_Immutable.php b/tribe-common/src/Tribe/Utils/Date_I18n_Immutable.php new file mode 100644 index 0000000000..3a1965552b --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Date_I18n_Immutable.php @@ -0,0 +1,48 @@ +setTimestamp( $datetime->getTimestamp() ); + $date_object = $date_object->setTimezone( $datetime->getTimezone() ); + + return $date_object; + } + + /** + * Returns a translated string using the params from this Immutable DateTime instance. + * + * @since 4.11.0 + * + * @param string $date_format Format to be used in the translation. + * + * @return string Translated date. + */ + public function format_i18n( $date_format ) { + $unix_with_tz = $this->getTimestamp() + $this->getOffset(); + $translated = date_i18n( $date_format, $unix_with_tz ); + + return $translated; + } +} diff --git a/tribe-common/src/Tribe/Utils/Element_Attributes.php b/tribe-common/src/Tribe/Utils/Element_Attributes.php new file mode 100644 index 0000000000..4906f3e62e --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Element_Attributes.php @@ -0,0 +1,241 @@ + + */ + protected $results = []; + + /** + * Stores the arguments passed. + * + * @since 4.12.3 + * + * @var array + */ + protected $arguments = []; + + /** + * Setups an instance of Element Attributes. + * + * @since 4.12.3 + * + * @return void + */ + public function __construct() { + $this->arguments = func_get_args(); + } + + /** + * When invoked this class will return the full HTML attributes. + * + * @since 4.12.3 + * + * @return string In the format ` attribute1="value1" attribute2="value2" ` + */ + public function __invoke() { + $this->arguments = func_get_args(); + return $this->get_attributes(); + } + + + /** + * When cast to string an instance will return the full HTML attributes. + * + * @since 4.12.3 + * + * @return string In the format ` attribute1="value1" attribute2="value2" ` + */ + public function __toString() { + return $this->get_attributes(); + } + + /** + * Gets the full HTML attributes for this instance of Element Attributes. + * It will contain a space on each end of the attribute. + * + * @since 4.12.3 + * + * @return string In the format ` attribute1="value1" attribute2="value2" ` + */ + public function get_attributes() { + $attributes = $this->get_attributes_as_string(); + + // Bail with empty string when no attributes are present + if ( ! $attributes ) { + return ''; + } + + return " {$attributes} "; + } + + /** + * Gets a space separated string of all attributes to be printed. + * + * @since 4.12.3 + * + * @return string + */ + public function get_attributes_as_string() { + return implode( ' ', $this->get_attributes_array() ); + } + + /** + * Get the array of attributes to be printed. + * + * @since 4.12.3 + * + * @return array + */ + public function get_attributes_array() { + $this->results = []; + $attributes = []; + + $this->parse_array( $this->arguments ); + + foreach ( $this->results as $key => $val ) { + if ( ! $val && '0' !== $val ) { + continue; + } + + if ( is_bool( $val ) ) { + $attributes[] = esc_attr( $key ); + } else { + // Remove double quotes that might be surrounding the value. + trim( $val, '"' ); + $attributes[] = esc_attr( $key ) . '="' . esc_attr( $val ) . '"'; + } + } + + return $attributes; + } + + /** + * Parse arguments or argument for this instance, and store values on results. + * + * @since 4.12.3 + * + * @param mixed $arguments Any possible set of arguments that this class supports. + * + * @return void + */ + protected function parse( $arguments ) { + if ( ! $arguments ) { + return; + } + + if ( is_numeric( $arguments ) ) { // phpcs:ignore + // Bail on any numeric values. + } elseif ( is_array( $arguments ) ) { + // ['foo', 'bar', ...] || ['foo' => TRUE, 'bar' => FALSE, 'baz' => 'foo', ...] + $this->parse_array( $arguments ); + } elseif ( is_string( $arguments ) ) { + // 'foo bar' + $this->parse_string( $arguments ); + } elseif ( $arguments instanceof \Closure || is_callable( $arguments ) ) { + // function() {} + $this->parse_callable( $arguments ); + } elseif ( is_object( $arguments ) ) { + // stdClass + $this->parse_object( $arguments ); + } + } + + /** + * Parse an array into an array of acceptable values for the instance. + * + * @since 4.12.3 + * + * @param array $values Array of values to be parsed. + * + * @return void + */ + protected function parse_array( array $values ) { + foreach ( $values as $key => $value ) { + if ( is_int( $key ) ) { + $this->parse( $value ); + } elseif ( is_string( $key ) ) { + if ( ! is_bool( $value ) && ! is_string( $value ) ) { + throw new \UnexpectedValueException( 'Value for key ' . $key . ' must be of type boolean or string' ); + } + + $this->results[ $key ] = $value; + } + } + } + + /** + * Parse a string into an array of acceptable values for the instance. + * + * @since 4.12.3 + * + * @param string $arguments Space separated string of attributes to be parsed. + * + * @return void + */ + protected function parse_string( $arguments ) { + $values = preg_split( '/\s+/', $arguments, -1, PREG_SPLIT_NO_EMPTY ); + + // When it doesn't match, bail early. + if ( ! $values ) { + return; + } + + $attrs = []; + + foreach ( $values as $key => $value ) { + if ( preg_match( '/^(?[^=]+)="*(?.*?)"*$/', $value, $m ) ) { + // Something like `f="boo"` or `foo=bar`. + $attrs[ $m['key'] ] = $m['value']; + + continue; + } + + $attrs[ $value ] = true; + } + + $this->parse_array( $attrs ); + } + + /** + * Parses an object into the array of considered attributes. + * + * @since 4.12.3 + * + * @param mixed $object Object to be converted into array and parsed. + * + * @return void + */ + protected function parse_object( $object ) { + $this->parse_array( (array) $object ); + } + + /** + * Parses a callable method or function into the array of considered attributes. + * + * The result of the callable will REPLACE the current attributes, callables will work like filters. + * + * @since 4.12.3 + * + * @param callable $method_or_function Method or Function to be called. + * + * @return void + */ + protected function parse_callable( callable $method_or_function ) { + $filtered = $method_or_function( $this->results ); + $this->results = []; + $this->parse( $filtered ); + } +} diff --git a/tribe-common/src/Tribe/Utils/Element_Classes.php b/tribe-common/src/Tribe/Utils/Element_Classes.php new file mode 100644 index 0000000000..0f5af1b39b --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Element_Classes.php @@ -0,0 +1,246 @@ +arguments = func_get_args(); + } + + /** + * When invoked this class will return the full HTML class attribute. + * + * @since 4.9.13 + * + * @return string In the format ` class="class1 class2" ` + */ + public function __invoke() { + $this->arguments = func_get_args(); + return $this->get_attribute(); + } + + + /** + * When cast to string an instance will return the full HTML class attribute. + * + * @since 4.9.13 + * + * @return string In the format ` class="class1 class2" ` + */ + public function __toString() { + return $this->get_attribute(); + } + + /** + * Gets the full HTML class attribute for this instance of Element Classes. + * It will contain a space on each end of the attribute. + * + * @since 4.9.13 + * + * @return string In the format ` class="class1 class2" ` + */ + public function get_attribute() { + $classes = $this->get_classes_as_string(); + + // Bail with empty string when no classes are present + if ( ! $classes ) { + return ''; + } + + return " class=\"{$classes}\" "; + } + + /** + * Gets a space separated string of all classes to be printed. + * + * @since 4.9.13 + * + * @return string + */ + public function get_classes_as_string() { + return implode( ' ', $this->get_classes() ); + } + + /** + * Get the array of classes to be printed. + * + * @since 4.9.13 + * + * @return array + */ + public function get_classes() { + $this->results = []; + $classes = []; + + $this->parse_array( $this->arguments ); + + foreach ( $this->results as $key => $val ) { + if ( ! $val ) { + continue; + } + + $classes[] = $key; + } + + $classes = array_map( 'sanitize_html_class', $classes ); + $classes = array_filter( array_unique( $classes ) ); + + return $classes; + } + + + /** + * Get the array of the classes, using [ class_name => bool ] as the format. + * + * @since 4.9.13 + * + * @return array [ class_name => bool ] + */ + public function get_conditions() { + $this->results = []; + $this->parse_array( $this->arguments ); + + return $this->results; + } + + /** + * Parse arguments or argument for this instance, and store values on results. + * + * @since 4.9.13 + * + * @param mixed $arguments Any possible set of arguments that this class supports. + * @param boolean $default_value What is the default value for a given class. + * + * @return void + */ + protected function parse( $arguments, $default_value = true ) { + if ( ! $arguments ) { + return; + } + + if ( is_numeric( $arguments ) ) { // phpcs:ignore + // Bail on any numeric values + } elseif ( is_string( $arguments ) ) { + // 'foo bar' + $this->parse_string( $arguments ); + } elseif ( $arguments instanceof \Closure || is_callable( $arguments ) ) { + // function() {} + $this->parse_callable( $arguments ); + } elseif ( is_array( $arguments ) ) { + // ['foo', 'bar', ...] || ['foo' => TRUE, 'bar' => FALSE, ...] + $this->parse_array( $arguments ); + } elseif ( is_object( $arguments ) ) { + // stdClass + $this->parse_object( $arguments ); + } + } + + /** + * Parse a string into an array of acceptable values for the instance. + * + * @since 4.9.13 + * + * @param string $arguments Space separated string of classes to be parsed. + * @param boolean $default_value What is the default value for a given class. + * + * @return void + */ + protected function parse_string( $arguments, $default_value = true ) { + $values = preg_split( '/\s+/', $arguments, -1, PREG_SPLIT_NO_EMPTY ); + + // When it doesn't match, bail early. + if ( ! $values ) { + return; + } + + foreach ( $values as $class_name ) { + $this->results[ $class_name ] = $default_value; + } + } + + /** + * Parse an array into an array of acceptable values for the instance. + * + * @since 4.9.13 + * + * @param array $values Array of values to be parsed. + * + * @return void + */ + protected function parse_array( array $values ) { + foreach ( $values as $key => $value ) { + if ( is_int( $key ) ) { + if ( is_bool( $value ) ) { + $this->parse( $key, $value ); + } else { + $this->parse( $value ); + } + } elseif ( is_string( $key ) ) { + if ( ! is_bool( $value ) ) { + throw new \UnexpectedValueException( 'Value for key ' . $key . ' must be of type boolean' ); + } + + $this->parse_string( $key, $value ); + } + } + } + + /** + * Parses an object, only if it contains __toString it will be considered. + * + * @since 4.9.13 + * + * @param mixed $object Object to be checked for the __toString method + * + * @return void + */ + protected function parse_object( $object ) { + if ( method_exists( $object, '__toString' ) ) { + $this->parse( (string) $object ); + } + } + + /** + * Parses a callable method or function into the array of considered classes.s + * + * @since 4.9.13 + * + * @param callable $method_or_function Method or Function to be called. + * + * @return void + */ + protected function parse_callable( callable $method_or_function ) { + $this->parse( $method_or_function( $this->results ) ); + } +} diff --git a/tribe-common/src/Tribe/Utils/Global_ID.php b/tribe-common/src/Tribe/Utils/Global_ID.php new file mode 100644 index 0000000000..8ff4e91d4c --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Global_ID.php @@ -0,0 +1,165 @@ + 'meetup.com', + 'facebook' => 'facebook.com', + 'eventbrite' => 'eventbrite.com', + ]; + + /** + * Tribe__Utils__Global_ID constructor. + */ + public function __construct() { + + /** + * Filters the registered origin types for Global IDs. + * + * @since 4.7.21 + * + * @param array $type_origins List of origin types. + */ + $this->valid_types = apply_filters( 'tribe_global_id_valid_types', $this->valid_types ); + + /** + * Filters the registered origin URLs for Global IDs. + * + * @since 4.7.21 + * + * @param array $type_origins List of origin URLs. + */ + $this->type_origins = apply_filters( 'tribe_global_id_type_origins', $this->type_origins ); + + } + + /** + * A setter and getter for the Type of ID + * + * @param string|null $name When null is passed it will return the current Type + * @return mixed Will return False on invalid type or the Type in String + */ + public function type( $name = null ) { + if ( is_null( $name ) ) { + return $this->type; + } + + $name = strtolower( $name ); + + if ( ! in_array( $name, $this->valid_types ) ) { + return false; + } + + $this->type = $name; + + return $this->type; + } + + /** + * A setter and getter for the origin on this ID + * + * @param string|null $name When null is passed it will return the current Origin + * @return mixed Will return False on invalid origin or the Origin in String + */ + public function origin( $url = null ) { + if ( ! empty( $this->type_origins[ $this->type ] ) ) { + $this->origin = $this->type_origins[ $this->type ]; + } + + if ( is_null( $url ) ) { + return $this->origin; + } + + $parts = wp_parse_url( $url ); + + if ( ! $parts ) { + return false; + } + + $this->origin = $parts['host']; + + if ( ! empty( $parts['path'] ) ) { + $this->origin .= $parts['path']; + } + + if ( ! empty( $parts['query'] ) ) { + $this->origin .= '?' . $parts['query']; + } + + return $this->origin; + } + + /** + * A very simple Generation of IDs + * + * @param array $args Which query arguments will be added to the Origin + * + * @return string + */ + public function generate( array $args = [] ) { + // We can't do this without type or origin + if ( ! $this->type() || ! $this->origin() ) { + return false; + } + + return add_query_arg( $args, $this->origin() ); + } + + /** + * Parse the Global ID string. + * + * @param string $global_id The previously generated global ID string. + * + * @return array The parsed $args information built by self::generate() + * + * @since 4.7.15 + */ + public function parse( $global_id ) { + $parsed_global_id = null; + + if ( $global_id ) { + $global_id = html_entity_decode( $global_id ); // & characters replaced as expected + + $parsed = wp_parse_url( 'http://' . $global_id ); + + if ( ! empty( $parsed['query'] ) ) { + $parsed_query = []; + + wp_parse_str( $parsed['query'], $parsed_query ); + + if ( ! empty( $parsed_query ) ) { + $parsed_global_id = $parsed_query; + } + } + } + + return $parsed_global_id; + } +} diff --git a/tribe-common/src/Tribe/Utils/JSON.php b/tribe-common/src/Tribe/Utils/JSON.php new file mode 100644 index 0000000000..6268aa77ab --- /dev/null +++ b/tribe-common/src/Tribe/Utils/JSON.php @@ -0,0 +1,38 @@ + $subvalue ) { + $escaped[ $key ] = self::escape_string( $subvalue ); + } + + return $escaped; + } + + $escapers = [ "\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c" ]; + $replacements = [ "\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b" ]; + + return str_replace( $escapers, $replacements, $value ); + } +} diff --git a/tribe-common/src/Tribe/Utils/Lazy_Collection.php b/tribe-common/src/Tribe/Utils/Lazy_Collection.php new file mode 100644 index 0000000000..2c91de9466 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Lazy_Collection.php @@ -0,0 +1,117 @@ +all; + * } + * ```` + * + * @since 4.9.14 + * @package Tribe\Utils + */ + +namespace Tribe\Utils; + +/** + * Class Lazy_Collection + * + * @since 4.9.14 + * @package Tribe\Utils + */ +class Lazy_Collection implements Collection_Interface { + use Collection_Trait; + use Lazy_Events; + + /** + * The callback in charge of providing the elements. + * + * @var callable + */ + protected $callback; + + /** + * The elements of the array. + * + * @var array + */ + protected $items; + + /** + * Array_Promise constructor. + * + * @since 4.9.14 + * + * @param callable $callback The callback that will be used to populate the elements. + */ + public function __construct( callable $callback ) { + $this->callback = $callback; + } + + /** + * Fetches the array items and returns them. + * + * @since 4.9.14 + * + * @return array The array items. + */ + public function all() { + $this->resolve(); + + return $this->items; + } + + /** + * Fills the array elements from the callback if required. + * + * @since 4.9.14 + */ + protected function resolve() { + if ( null !== $this->items ) { + return; + } + + $items = call_user_func( $this->callback ); + $this->items = (array) $items; + $this->resolved(); + } + + /** + * Allows accessing the collection methods using properties. + * + * E.g. `$collection->first` is equivalent to `$collection->first()`. + * + * @since 4.9.14 + * + * @param string $property The name of the property to access. + * + * @return mixed|null The return value of the collection corresponding method or `null` if the collection does not + * have that method. + */ + public function __get( $property ) { + if ( method_exists( $this, $property ) ) { + return call_user_func( [ $this, $property ] ); + } + + return null; + } + + /** + * {@inheritDoc} + */ + public function jsonSerialize() { + return $this->all(); + } +} diff --git a/tribe-common/src/Tribe/Utils/Lazy_Events.php b/tribe-common/src/Tribe/Utils/Lazy_Events.php new file mode 100644 index 0000000000..10f9cc41a2 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Lazy_Events.php @@ -0,0 +1,172 @@ +list ){ + * $this->list = really_expensive_calculation(); + * } + * + * $this->resolved(); + * } + * + * return $this->list; + * } + * } + * + * class Lazy_Value { + * use Tribe\Utils\Lazy_Events; + * + * protected $value; + * + * public function calculate_value(){ + * $cached = wp_cache_get( 'expensive_value' ); + * + * if( false !== $cached ){ + * return $cached; + * + * if( null === $this->value ){ + * $this->value = really_expensive_calculation(); + * } + * + * $this->resolved(); + * } + * + * return $this->value; + * } + * } + * + * class List_And_Value { + * protected $list; + * protected $value; + * + * public function __construct( Lazy_List_Of_Stuff $list, Lazy_Value $value ){ + * $this->list = $list; + * $this->value = $value; + * $this->list->on_resolve( [ $this, 'cache' ] ); + * $this->value->on_resolve( [ $this, 'cache' ] ); + * } + * + * public function cache(){ + * wp_cache_set( 'list_and_value', [ + * 'list' => $this->list->fetch_list(), + * 'value' => $this->value->calculate_value(), + * ]); + * } + * + * public function get_list(){ + * $cached = wp_cache_get( 'list_and_value' ); + * + * return $cached ? $cached['list'] : $this->list->fetch_list(); + * } + * + * public function get_value(){ + * $cached = wp_cache_get( 'list_and_value' ); + * + * return $cached ? $cached['value'] : $this->value->fetch_value(); + * } + * } + * + * + * $list = new Lazy_List_Of_Stuff(); + * $value = new Lazy_Value(); + * $list_and_value = new List_And_Value( $list, $value ); + * + * // Accessing `value` will make it so that `list` too will be cached. + * $list_and_value->get_value(); + * ```` + * + * @package Tribe\Utils + */ + +namespace Tribe\Utils; + +/** + * Trait Lazy_Events + * + * @since 4.9.16 + * + * @package Tribe\Utils + * + * @property string $lazy_resolve_action The action to which the trait will hook to run the callback if the object + * resolved. Using classes should define the property if the default `shutdown` + * one is not correct. + * @property int $lazy_resolve_priority The priority at which the resolution callback will be hooked on the + * `$lazy_resolve_action`; defaults to `10`. + */ +trait Lazy_Events { + + /** + * The callback that will be called when, and if, the lazy object resolved at least once. + * + * @since 4.9.16 + * + * @var + */ + protected $lazy_resolve_callback; + + /** + * Sets the callback that will be hooked to the resolve action when, and if, the `resolved` method is called. + * + * @since 4.9.16 + * + * @param callable $callback The callback that will be hooked on the `$lazy_resolve_action` (defaults to `shutdown`) + * if the `resolved` method is called. + * + * @return static The object instance. + * + * @see Lazy_Events::resolved() + */ + public function on_resolve( callable $callback = null ) { + if ( null === $callback ) { + return $this; + } + + $this->lazy_resolve_callback = $callback; + + return $this; + } + + /** + * Hooks the `$lazy_resolve_callback` to the `$lazy_resolve_action` with the `$lazy_resolve_priority` if set. + * + * @since 4.9.16 + */ + protected function resolved() { + if ( empty( $this->lazy_resolve_callback ) ) { + return; + } + + $action = property_exists( $this, 'lazy_resolve_action' ) ? + $this->lazy_resolve_action + : 'shutdown'; + $priority = property_exists( $this, 'lazy_resolve_priority' ) ? + $this->lazy_resolve_priority + : 10; + + $hooked = has_action( $action, $this->lazy_resolve_callback ); + + // Let's play it safe and move the resoloution as late as possible. + $new_priority = false !== $hooked ? max( $hooked, $priority ) : $priority; + + if ( is_numeric( $hooked ) && $hooked !== $new_priority ) { + remove_action( $action, $this->lazy_resolve_callback, $hooked ); + } + + add_action( $action, $this->lazy_resolve_callback, $new_priority ); + } +} diff --git a/tribe-common/src/Tribe/Utils/Lazy_String.php b/tribe-common/src/Tribe/Utils/Lazy_String.php new file mode 100644 index 0000000000..8597763769 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Lazy_String.php @@ -0,0 +1,141 @@ +value_callback = $callback; + $this->escape_callback = $escape_callback; + } + + /** + * Inits, and returns, the string value of the string. + * + * @since 4.9.16 + * + * @return string The unescaped string value. + */ + public function __toString() { + if ( null === $this->string ) { + $this->string = call_user_func( $this->value_callback ); + $this->resolved(); + } + + return $this->string; + } + + /** + * Returns the HTML ready, escaped version of the string. + * + * @since 4.9.16 + * + * @return string The escaped version of the string. + */ + public function escaped() { + if ( null !== $this->escaped ) { + return $this->escaped; + } + + $this->escaped = empty( $this->escape_callback ) + ? $this->__toString() + : call_user_func( $this->escape_callback, $this->__toString() ); + + return $this->escaped; + } + + /** + * Returns the string value, just a proxy of the `__toString` method. + * + * @since 4.9.16 + * + * @return string The string value. + */ + public function value() { + return $this->__toString(); + } + + /** + * {@inheritDoc} + * + * @since 4.9.16 + */ + public function serialize() { + $serialized = serialize( [ $this->__toString(), $this->escaped() ] ); + + unset( $this->value_callback, $this->escape_callback ); + + return $serialized; + } + + /** + * {@inheritDoc} + * + * @since 4.9.16 + */ + public function unserialize( $serialized ) { + list( $string, $escaped ) = unserialize( $serialized ); + $this->string = $string; + $this->escaped = $escaped; + } + + /** + * {@inheritDoc} + */ + public function jsonSerialize() { + return $this->value(); + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Utils/Paths.php b/tribe-common/src/Tribe/Utils/Paths.php new file mode 100644 index 0000000000..1f8bb8029f --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Paths.php @@ -0,0 +1,75 @@ +> ...$paths A set of paths to merge, each one either a string or an array + * of path fragments. + * + * @return string The merged path, the path intersecting fragments removed. + */ + public static function merge( ...$paths ) { + $merged_paths = ''; + + if ( count( $paths ) > 2 ) { + $slice = array_splice( $paths, 0, 1 ); + $paths = array_merge( $slice, [ static::merge( ...$paths ) ] ); + } + + $path_1 = isset( $paths[0] ) ? $paths[0] : ''; + $lead_slash = is_string( $path_1 ) && $path_1 !== ltrim( $path_1, '\\/' ) ? DIRECTORY_SEPARATOR : ''; + $path_2 = isset( $paths[1] ) ? $paths[1] : ''; + $trail_slash = is_string( $path_2 ) && $path_2 !== rtrim( $path_2, '\\/' ) ? DIRECTORY_SEPARATOR : ''; + // Handle *nix spacing escape sequence (`\ `) correctly. The Windows one (`^ `) is already handled. + $break_pattern = '/[\\\\\\/](?!\\s)/'; + $drop_empty_strings = static function ( $frag ) { + return $frag !== ''; + }; + $path_1_frags = is_array( $path_1 ) + ? $path_1 + : array_filter( (array) preg_split( $break_pattern, $path_1 ), $drop_empty_strings ); + $path_2_frags = is_array( $path_2 ) + ? $path_2 + : array_filter( (array) preg_split( $break_pattern, $path_2 ), $drop_empty_strings ); + $non_consecutive_common = array_intersect( $path_1_frags, $path_2_frags ); + + $trimmed_path_2 = trim( + preg_replace( + '#^' . preg_quote( implode( DIRECTORY_SEPARATOR, $non_consecutive_common ), '#' ) . '#', '', + implode( DIRECTORY_SEPARATOR, $path_2_frags ) + ), + '\\/' + ); + + $merged_paths .= $lead_slash . implode( DIRECTORY_SEPARATOR, $path_1_frags ); + + if ( $trimmed_path_2 ) { + $merged_paths .= DIRECTORY_SEPARATOR . $trimmed_path_2 . $trail_slash; + } + + return $merged_paths; + } +} diff --git a/tribe-common/src/Tribe/Utils/Plugins.php b/tribe-common/src/Tribe/Utils/Plugins.php new file mode 100644 index 0000000000..ee96a0d8c8 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Plugins.php @@ -0,0 +1,80 @@ + 'Plugin Name', + 'PluginURI' => 'Plugin URI', + 'Version' => 'Version', + 'ExtensionClass' => 'Extension Class', + 'ExtensionFile' => 'Extension File', + 'Description' => 'Description', + 'Author' => 'Author', + 'AuthorURI' => 'Author URI', + 'TextDomain' => 'Text Domain', + 'DomainPath' => 'Domain Path', + 'Network' => 'Network', + ]; + + /** + * Filter which header keys passed to get_file_data(). + * + * @see get_file_data() + * + * @param array $headers The headers. + * @param string $plugin_file The plugin file path. + */ + $headers = apply_filters( 'tribe_get_plugin_data_headers', $headers, $plugin_file ); + $file_data = get_file_data( $plugin_file, $headers, 'plugin' ); + + /** + * Filter the parsed plugin header data. + * + * @param array $file_data Output from get_file_data(). + * @param string $plugin_file The plugin file path. + * @param array $headers The headers. + */ + return apply_filters( 'tribe_get_plugin_data', $file_data, $plugin_file, $headers ); + } + + /** + * Get list of active plugins with a given prefix in the plugin folder path. + * + * @param string|array $prefix Prefixes you want to retrieve. + * + * @return array List of plugins with prefix in path. + */ + public static function get_plugins_with_prefix( $prefix ) { + $full_list = wp_get_active_and_valid_plugins(); + + if ( is_multisite() ) { + $full_list = array_merge( $full_list, wp_get_active_network_plugins() ); + } + + $filtered_list = []; + + foreach ( $full_list as $plugin ) { + $base = plugin_basename( $plugin ); + + if ( 0 === Tribe__Utils__Array::strpos( $base, $prefix ) ) { + $filtered_list[] = $plugin; + } + } + + return $filtered_list; + } +} diff --git a/tribe-common/src/Tribe/Utils/Post_Collection.php b/tribe-common/src/Tribe/Utils/Post_Collection.php new file mode 100644 index 0000000000..7240fcfd7f --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Post_Collection.php @@ -0,0 +1,292 @@ + + */ + protected $taxonomies; + + /** + * Tribe__Utils__Post_Collection constructor. + * + * Overrides the base constructor to ensure all elements in the collection are, in fact, posts. + * Elements that do not resolve to a post are discarded. + * + * @param array $items + */ + public function __construct( array $items ) { + parent::__construct( array_filter( array_map( 'get_post', $items ) ) ); + } + + /** + * Plucks fields from the posts in the collection creating a map using a field value as key and one + * or more fields as values. + * + * Note: the method does not make any check on the uniqueness of the fields used as keys, e.g. this will + * probably not return what intended: `$collection->pluck_combine( 'post_status', 'post_title' );`. + * If there's a chance of the key fields not being unique, then use `#` as key field to simply return an + * array of plucked values. + * + * @since 4.12.6 + * + * @param string $key_field The field to key the return map by, or `#` to use + * progressive integers to key the return value. Use fields + * as keys only when their uniqueness is sure. + * @param string|array|array $value_fields Either a single field name to populate the values with; + * a list of fields, each plucked with default settings; + * a map of fields to fetch, each defining a `single` and + * `args` key to define the pluck `$single` and `$args` + * parameters where applicable. + * Additionally an `as` parameter can be specified to alias + * the field in the results. + * If the only requirement is to alias fields, just use a + * flat map like `[ => , ... ]`. + * + * @return array A list of plucked fields or a map of plucked fields keyed by the + * specified field. + */ + public function pluck_combine( $key_field = '#', $value_fields = 'post_title' ) { + $value_req_is_array = is_array( $value_fields ); + $value_fields = (array) $value_fields; + $rows = []; + $field_names = []; + $field_index = 0; + foreach ( $value_fields as $k => $field ) { + if ( is_string( $k ) && is_string( $field ) ) { + $single = true; + $args = []; + $field_name = $field; + $pluck = $k; + } else { + list( $as, $single, $args ) = $this->parse_field_args( $field ); + $field = is_array( $field ) ? $k : $field; + $field_name = null === $as ? $field : $as; + $pluck = $field; + } + $field_names[ $field_index ] = $field_name; + $rows[ $field_name ] = $this->pluck( $pluck, $single, $args ); + $field_index ++; + } + $values = []; + + // Build a list with only numeric keys and string values. + $fields_list = array_replace( + array_filter( + array_filter( $value_fields, 'is_string' ), + 'is_numeric', + ARRAY_FILTER_USE_KEY + ), + $field_names + ); + + for ( $i = 0, $count = count( $this->items ); $i < $count; $i ++ ) { + $values[ $i ] = array_combine( $fields_list, array_column( $rows, $i ) ); + } + + if ( ! $value_req_is_array ) { + $values = array_column( $values, reset( $fields_list ) ); + } + + // If the key field is `#` then use a progressive number as key, else use the specified field. + $keys = '#' === $key_field + ? range( 0, count( $this->items ) - 1 ) + : $this->pluck( $key_field, true ); + + return array_combine( $keys, $values ); + } + + /** + * Parses a single field request to extract the `$single` and `$args` parameters from it. + * + * @since 4.12.6 + * + * @param string|array $field The field name or the field arguments map. + * + * @return array The `$as`, `$single` and `$args` parameters extracted from the field. + */ + protected function parse_field_args( $field ) { + $field = (array) $field; + + $as = isset( $field['as'] ) + ? (string) $field['as'] + : null; + $single = isset( $field['single'] ) + ? (bool) $field['single'] + : true; + $args = isset( $field['args'] ) + ? (array) $field['args'] + : null; + + return [ $as, $single, $args ]; + } + + /** + * Plucks a post field, a taxonomy or a custom field from the collection. + * + * @since 4.12.6 + * + * @param string $key The name of the field to pluck; the method will try to detect the type of field + * from its name. If any issues might arise due to fields of different types with the + * same name, then use the `pluck_` methods directly. + * @param bool $single Whether to pluck a single taxonomy term or custom fields or an array of all the taxonomy + * terms or custom fields for each post. + * @param array $args A list of n optional arguments that will be passed down to the `pluck_` methods. + * Currently only the the `pluck_taxonomy` will support one more argument to define the + * query arguments for the term query. + * + * @return array|array Either an array of plucked fields when plucking post fields or single + * custom fields or taxonomy terms, or an array of arrays, each one a list + * of all the taxonomy terms or custom fields entries for each post. + */ + public function pluck( $key, $single = true, array $args = null ) { + $type = $this->detect_field_type( $key ); + + switch ( $type ) { + case 'post_field': + return $this->pluck_field( $key ); + break; + case 'taxonomy': + return $this->pluck_taxonomy( $key, $single, $args ); + break; + default: + return $this->pluck_meta( $key, $single ); + break; + } + } + + /** + * Detects the type of a post field from its name. + * + * @since 4.12.6 + * + * @param string $key The name of the field to check. + * + * @return string The type of field detected for the key, either `post_field`, `taxonomy` or `custom_field`. + */ + protected function detect_field_type( $key ) { + if ( $this->is_a_post_field( $key ) ) { + return 'post_field'; + } + + // Init taxonomies as late as possible and only once. + $this->init_taxonomies(); + + if ( $this->is_a_taxonomy( $key ) ) { + return 'taxonomy'; + } + + return 'custom_field'; + } + + /** + * Initialize the post collection taxonomies by filling up the `$taxonomies` property. + * + * Note the collection will use the first post in the collection to fill the taxonomies array, + * this assumes the collection is homogeneous in its post types. + * + * @since 4.12.6 + */ + protected function init_taxonomies() { + if ( ! empty( $this->taxonomies ) ) { + // Already set up, return. + return; + } + + if ( empty( $this->items ) ) { + // We cannot detect taxonomies from an empty list of items. + $this->taxonomies = []; + + return; + } + + // Use the first post to detect the taxonomies. + $this->taxonomies = get_object_taxonomies( reset( $this->items ), 'names' ); + } + + /** + * Plucks a post field from all posts in the collection. + * + * Note: there is no check on the name of the plucked post field: if a non-existing post field is requested, then + * the method will return an empty array. + * + * @since 4.12.6 + * + * @param string $field The name of the post field to pluck. + * + * @return array A list of the plucked post fields from each item in the collection. + */ + public function pluck_field( $field ) { + return wp_list_pluck( $this->items, $field ); + } + + /** + * Plucks taxonomy terms assigned to the posts in the collection. + * + * Note: there is no check on the taxonomy being an existing one or not; that responsibility + * is on the user code. + * + * @since 4.12.6 + * + * @param string $taxonomy The name of the post taxonomy to pluck terms for. + * @param bool $single Whether to return only the first results or all of them. + * @param array $args A set of arguments as supported by the `WP_Term_Query::__construct` + * method. + * + * @return array|array Either an array of the requested results if `$single` is `true` + * or an array of arrays if `$single` is `false`. + */ + public function pluck_taxonomy( $taxonomy, $single = true, array $args = null ) { + $plucked = []; + $args = null === $args ? [ 'fields' => 'names' ] : $args; + + foreach ( $this as $item ) { + $terms = wp_get_object_terms( $item->ID, $taxonomy, $args ); + $plucked[] = $single ? reset( $terms ) : $terms; + } + + return $plucked; + } + + /** + * Plucks a meta key for all elements in the collection. + * + * Elements that are not posts or do not have the meta set will have an + * empty string value. + * + * @since 4.9.5 + * + * @param string $meta_key The meta key to pluck. + * @param bool $single Whether to fetch the meta key as single or not. + * + * @return array An array of meta values for each item in the collection; items that + * do not have the meta set or that are not posts, will have an empty + * string value. + */ + public function pluck_meta( $meta_key, $single = true ) { + $plucked = []; + + foreach ( $this as $item ) { + $plucked[] = get_post_meta( $item->ID, $meta_key, $single ); + } + + return $plucked; + } +} diff --git a/tribe-common/src/Tribe/Utils/Post_Root_Pool.php b/tribe-common/src/Tribe/Utils/Post_Root_Pool.php new file mode 100644 index 0000000000..de1b920ab4 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Post_Root_Pool.php @@ -0,0 +1,203 @@ +post_name; + + // A lot fo these get urlencoded, so let's try to fix that first + $post_name = tribe_maybe_urldecode( $post_name ); + + $this->current_post = $post; + $flipped_pool = array_flip( $this->fetch_pool() ); + + if ( isset( $flipped_pool[ $this->current_post->ID ] ) ) { + return $flipped_pool[ $this->current_post->ID ] . $this->root_separator; + } + + $root = $this->build_root_from( $post_name ); + + return $root . $this->root_separator; + } + + /** + * @param string $post_name + * + * @param string $postfix + * + * @return string + */ + protected function build_root_from( $post_name, $postfix = '' ) { + $candidate = $this->build_root_candidate( $post_name, $postfix ); + + $initial_candidate = $candidate; + + while ( $this->is_in_pool( $candidate ) ) { + $postfix = $this->postfix; + $candidate = $initial_candidate . '-' . $postfix; + $this->postfix ++; + } + + $this->postfix = 1; + + $this->insert_root_in_pool( $candidate ); + + return $candidate; + } + + /** + * @return string + */ + public function get_pool_transient_name() { + return $this->pool_transient_name; + } + + /** + * @param $string + * + * @return string + * @deprecated 4.7.18 + */ + protected function uc_first_letter( $string ) { + _deprecated_function( __METHOD__, '4.7.18', 'tribe_uc_first_letter' ); + + return is_numeric( $string ) ? $string : tribe_uc_first_letter( $string ); + } + + /** + * @param $string + * + * @return string + * @deprecated 4.7.18 + */ + protected function safe_strtoupper( $string ) { + _deprecated_function( __METHOD__, '4.7.18', 'tribe_strtoupper' ); + + return is_numeric( $string ) ? $string : tribe_strtoupper( $string ); + } + + /** + * @param string $candidate + */ + protected function is_in_pool( $candidate ) { + $pool = $this->fetch_pool(); + + return isset( $pool[ $candidate ] ); + } + + /** + * @return array + */ + protected function fetch_pool() { + if ( false === self::$prefix_pool ) { + $this->maybe_init_pool(); + } + + return self::$prefix_pool; + } + + protected function maybe_init_pool() { + self::$prefix_pool = get_transient( $this->pool_transient_name ); + if ( self::$prefix_pool === false ) { + self::$prefix_pool = []; + set_transient( $this->pool_transient_name, [] ); + } + } + + /** + * @param string $unique_root + */ + protected function insert_root_in_pool( $unique_root ) { + $prefix_pool = $this->fetch_pool(); + $prefix_pool[ $unique_root ] = $this->current_post->ID; + self::$prefix_pool = $prefix_pool; + set_transient( $this->pool_transient_name, $prefix_pool ); + } + + public static function reset_pool() { + self::$prefix_pool = false; + } + + /** + * @param $post_name + * @param $postfix + * + * @return string + */ + protected function build_root_candidate( $post_name, $postfix ) { + $frags = explode( '-', $post_name ); + + $candidate = implode( '', array_map( 'strtoupper', $frags ) ); + + if ( strlen( $candidate ) > 9 ) { + $frags = array_filter( $frags ); + $candidate = implode( '', array_map( 'tribe_uc_first_letter', $frags ) ); + } + + $candidate = $candidate . $postfix; + + return $candidate; + } + + /** + * Primes the post pool. + * + * @param array $pool + * @param bool $override_transient If `true` the transient too will be overwritten. + */ + public function set_pool( array $pool, $override_transient = false ) { + self::$prefix_pool = $pool; + if ( $override_transient ) { + set_transient( $this->pool_transient_name, $pool ); + } + } + + /** + * Whether the pool transient has been primed or not. + * + * @return bool + */ + public function is_primed() { + return get_transient( $this->pool_transient_name ) !== false; + } + + /** + * @return array + */ + public function get_pool() { + return $this->fetch_pool(); + } +} diff --git a/tribe-common/src/Tribe/Utils/Post_Thumbnail.php b/tribe-common/src/Tribe/Utils/Post_Thumbnail.php new file mode 100644 index 0000000000..fb4a3b8aa2 --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Post_Thumbnail.php @@ -0,0 +1,330 @@ +large->url; + * ``` + * + * @since 4.9.14 + * @package Tribe\Utils + */ + + +namespace Tribe\Utils; + +use Tribe__Utils__Array as Arr; + +/** + * Class Post_Thumbnail + * + * @since 4.9.14 + * @package Tribe\Utils + */ +class Post_Thumbnail implements \ArrayAccess, \Serializable { + use Lazy_Events; + + /** + * An array of the site image sizes, including the `full` one. + * + * @since 4.9.14 + * + * @var array + */ + protected $image_sizes; + + /** + * The post ID this images collection is for. + * + * @since 4.9.14 + * + * @var int + */ + protected $post_id; + + /** + * The post thumbnail data. + * + * @since 4.9.14 + * + * @var array + */ + protected $data; + + /** + * A flag property indicating whether the post thumbnail for the post exists or not. + * + * @since 4.9.16 + * + * @var bool + */ + protected $exists; + + /** + * The post ID, if any, of the post thumbnail. + * + * @since 4.9.16 + * + * @var int + */ + protected $thumbnail_id; + + /** + * Post_Images constructor. + * + * @param int $post_id The post ID. + */ + public function __construct( $post_id ) { + $this->post_id = $post_id; + } + + /** + * {@inheritDoc} + */ + public function __get( $property ) { + if ( 'exists' === $property ) { + return $this->exists(); + } + + return $this->offsetGet( $property ); + } + + /** + * {@inheritDoc} + */ + public function __set( $property, $value ) { + if ( 'exists' === $property ) { + throw new \InvalidArgumentException( 'The `Post_Thumbnail::exists` property cannot be set.' ); + } + + $this->offsetSet( $property, $value ); + } + + /** + * {@inheritDoc} + */ + public function __isset( $property ) { + return $this->offsetExists( $property ); + } + + /** + * Fetches and returns the image sizes registered on the site, if any. + * + * @since 4.9.14 + * + * @return array An array of the registered image sizes. + */ + public function get_image_sizes() { + if ( null !== $this->image_sizes ) { + return $this->image_sizes; + } + + $image_sizes = array_merge( [ 'full' ], get_intermediate_image_sizes() ); + + /** + * Filters the image sizes the `Tribe\Utils\Post_Thumbnail` class will manage and fetch data for. + * + * @since 4.9.14 + * + * @param array $image_sizes All the available image sizes; this includes the default and the intermediate ones. + */ + $this->image_sizes = apply_filters( 'tribe_post_thumbnail_image_sizes', $image_sizes ); + + return $this->image_sizes; + } + + /** + * Returns the data about the post thumbnail, if any. + * + * @since 4.9.14 + * + * @return array An array of objects containing the post thumbnail data. + */ + public function fetch_data() { + static $cache_thumbnail = []; + + if ( ! $this->exists() ) { + return []; + } + + if ( null !== $this->data ) { + return $this->data; + } + + $image_sizes = $this->get_image_sizes(); + $thumbnail_id = $this->thumbnail_id; + + $cache_key = empty( $thumbnail_id ) ? -1 : $thumbnail_id; + + if ( empty( $cache_thumbnail[ $cache_key ] ) ) { + $thumbnail_data = array_combine( + $image_sizes, + array_map( + static function( $size ) use ( $thumbnail_id ) { + static $cache_size_data = []; + + $size_data_cache_key = empty( $thumbnail_id ) ? -1 : $thumbnail_id; + $size_data_cache_key = "{$size_data_cache_key}:{$size}"; + + if ( ! isset( $cache_size_data[ $size_data_cache_key ] ) ) { + $cache_size_data[ $size_data_cache_key ] = wp_get_attachment_image_src( $thumbnail_id, $size ); + } + + $size_data = $cache_size_data[ $size_data_cache_key ]; + + if ( false === $size_data ) { + return (object) [ + 'url' => '', + 'width' => '', + 'height' => '', + 'is_intermediate' => false, + ]; + } + + return (object) [ + 'url' => Arr::get( $size_data, 0, '' ), + 'width' => Arr::get( $size_data, 1, '' ), + 'height' => Arr::get( $size_data, 2, '' ), + 'is_intermediate' => (bool) Arr::get( $size_data, 3, false ), + ]; + }, + $image_sizes + ) + ); + + $srcset = wp_get_attachment_image_srcset( $thumbnail_id ); + $thumbnail_data['srcset'] = ! empty( $srcset ) ? $srcset : false; + + $title = get_the_title( $thumbnail_id ); + $thumbnail_data['title'] = ! empty( $title ) ? $title : false; + + $alt = trim( strip_tags( get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true ) ) ); + $thumbnail_data['alt'] = ! empty( $alt ) ? $alt : false; + + $cache_thumbnail[ $cache_key ] = $thumbnail_data; + } + + /** + * Filters the post thumbnail data and information that will be returned for a specific post. + * + * Note that the thumbnail data will be cast to an object after this filtering. + * + * @since 4.9.14 + * + * @param array $thumbnail_data The thumbnail data for the post. + * @param int $post_id The ID of the post the data is for. + */ + $thumbnail_data = apply_filters( 'tribe_post_thumbnail_data', $cache_thumbnail[ $cache_key ], $this->post_id ); + + $this->resolved(); + + return $thumbnail_data; + } + + /** + * {@inheritDoc} + */ + public function offsetExists( $offset ) { + $this->data = $this->fetch_data(); + + return isset( $this->data[ $offset ] ); + } + + /** + * {@inheritDoc} + */ + public function offsetGet( $offset ) { + $this->data = $this->fetch_data(); + + return isset( $this->data[ $offset ] ) + ? $this->data[ $offset ] + : null; + } + + /** + * {@inheritDoc} + */ + public function offsetSet( $offset, $value ) { + $this->data = $this->fetch_data(); + + $this->data[ $offset ] = $value; + } + + /** + * {@inheritDoc} + */ + public function offsetUnset( $offset ) { + $this->data = $this->fetch_data(); + + unset( $this->data[ $offset ] ); + } + + /** + * Returns an array representation of the post thumbnail data. + * + * @since 4.9.14 + * + * + * @return array An array representation of the post thumbnail data. + */ + public function to_array() { + $this->data = $this->fetch_data(); + + return json_decode( json_encode( $this->data ), true ); + } + + /** + * {@inheritDoc} + */ + public function serialize() { + $data = $this->fetch_data(); + $data['post_id'] = $this->post_id; + + return wp_json_encode( $data ); + } + + /** + * {@inheritDoc} + */ + public function unserialize( $serialized ) { + $data = json_decode( $serialized, true ); + array_walk( $data, static function ( &$data_entry ) { + if ( is_array( $data_entry ) ) { + $data_entry = (object) $data_entry; + } + } ); + $this->post_id = $data['post_id']; + unset( $data['post_id'] ); + $this->data = ! empty( $data ) ? $data : null; + } + + /** + * Returns whether a post thumbnail is set for the post or not. + * + * @since 4.9.16 + * + * @return bool Whether a post thumbnail is set for the post or not. + */ + public function exists() { + if ( null !== $this->exists ) { + return $this->exists; + } + + $thumbnail_id = get_post_thumbnail_id( $this->post_id ); + + if ( empty( $thumbnail_id ) ) { + $this->exists = false; + } else { + $this->thumbnail_id = $thumbnail_id; + $this->exists = true; + } + + return $this->exists; + } +} diff --git a/tribe-common/src/Tribe/Utils/Query.php b/tribe-common/src/Tribe/Utils/Query.php new file mode 100644 index 0000000000..dc8b64bf5e --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Query.php @@ -0,0 +1,72 @@ +posts = $posts; + $query->found_posts = count( $posts ); + $query->post = reset( $posts ); + $query->query = [ 'p' => 0 ]; + $query->tribe_mock_query = true; + global $wpdb; + // Use a query that will never yield results. + $query->request = "SELECT ID FROM {$wpdb->posts} WHERE 1=0"; + + // Return the same set of posts on each method requiring posts. + $filter_posts_pre_query = static function ( $the_posts, $the_query ) use ( $posts, $query ) { + if ( $the_query !== $query ) { + return $the_posts; + } + + $fields = $query->get( 'fields', false ); + // We assume some uniformity here. + $posts_are_objects = ! is_numeric( reset( $posts ) ); + + switch ( $fields ) { + case 'ids': + return $posts_are_objects ? wp_list_pluck( $posts, 'ID' ) : $posts; + case 'id=>parent': + default: + return $posts_are_objects ? $posts : array_map( 'get_post', $posts ); + } + }; + + add_filter( 'posts_pre_query', $filter_posts_pre_query, 10, 2 ); + + return $query; + } +} diff --git a/tribe-common/src/Tribe/Utils/Strings.php b/tribe-common/src/Tribe/Utils/Strings.php new file mode 100644 index 0000000000..33b3f11dda --- /dev/null +++ b/tribe-common/src/Tribe/Utils/Strings.php @@ -0,0 +1,65 @@ +by( $operation, $taxonomy, $terms ); + + // This will only build the query not execute it. + $built_query = $repo->build_query(); + + if ( ! empty( $built_query->query_vars['tax_query'] ) ) { + $tax_query = $built_query->query_vars['tax_query']; + } + + return $tax_query; + } + + /** + * Transform all Term IDs and Slugs into IDs of existing terms in a given taxonomy. + * + * @since 4.13.0 + * + * @param string|int|array $terms Terms to be cleaned up. + * @param string $taxonomy Which taxonomy we are querying for. + * + * @return array List of IDs of terms. + */ + public static function normalize_to_term_ids( $terms, $taxonomy ) { + if ( empty( $terms ) ) { + return $terms; + } + + /** + * Allow filtering of the needle for splitting terms, by default it will be a comma. + * + * @since 4.13.0 + * + * @param string $needle Defaults to a comma. Which character that we will split terms by. + * @param string|array $terms Terms string that we will split by the needle filtered. + * @param string $taxonomy Which taxonomy this will be for. + */ + $needle = apply_filters( 'tribe_normalize_to_term_ids_needle', ',', $terms, $taxonomy ); + if ( is_string( $terms ) && false !== strpos( $terms, $needle ) ) { + $terms = array_map( 'trim', explode( $needle, $terms ) ); + } + + $terms = array_map( static function ( $param ) use ( $taxonomy ) { + $param = preg_replace( '/^#/', '', $param ); + $term_by = is_numeric( $param ) ? 'ID' : 'slug'; + $term = get_term_by( $term_by, $param, $taxonomy ); + + if ( ! $term instanceof \WP_Term ) { + return false; + } + + return $term->term_id; + }, (array) $terms ); + + $terms = array_filter( $terms ); + $terms = array_unique( $terms ); + + return $terms; + } +} \ No newline at end of file diff --git a/tribe-common/src/Tribe/Validate.php b/tribe-common/src/Tribe/Validate.php new file mode 100755 index 0000000000..63a65042d2 --- /dev/null +++ b/tribe-common/src/Tribe/Validate.php @@ -0,0 +1,503 @@ +result = new stdClass; + $this->field = $field; + $this->field['id'] = $field_id; + $this->value = $value; + $this->additional_args = $additional_args; + + // if the field is invalid or incomplete, fail validation + if ( ! is_array( $this->field ) || ! ( isset( $this->field['validation_type'] ) || isset( $this->field['validation_callback'] ) ) ) { + $this->result->valid = false; + $this->result->error = esc_html__( 'Invalid or incomplete field passed', 'tribe-common' ); + $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' )' : ''; + } + + // call validation callback if a validation callback function is set + if ( isset( $this->field['validation_callback'] ) ) { + if ( is_callable( $this->field['validation_callback'] ) || function_exists( $this->field['validation_callback'] ) ) { + if ( ( ! isset( $_POST[ $field_id ] ) || ! $_POST[ $field_id ] || $_POST[ $field_id ] == '' ) && isset( $this->field['can_be_empty'] ) && $this->field['can_be_empty'] ) { + $this->result->valid = true; + } else { + $this->result->valid = call_user_func( $this->field['validation_callback'], $value ); + if ( ! $this->result->valid ) { + $this->result->error = esc_html__( 'Invalid or incomplete field passed', 'tribe-common' ); + $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' )' : ''; + } + } + } + } + + if ( isset( $this->field['validation_type'] ) ) { + if ( method_exists( $this, $this->field['validation_type'] ) ) { + // make sure there's a field validation type set for this validation and that such method exists + $this->type = $this->field['validation_type']; + $this->label = isset( $this->field['label'] ) ? $this->field['label'] : $this->field['id']; + if ( ( ! isset( $_POST[ $field_id ] ) || ! $_POST[ $field_id ] || $_POST[ $field_id ] == '' ) && isset( $this->field['can_be_empty'] ) && $this->field['can_be_empty'] ) { + $this->result->valid = true; + } else { + call_user_func( [ $this, $this->type ] ); // run the validation + } + } else { + // invalid validation type set, validation fails + $this->result->valid = false; + $this->result->error = esc_html__( 'Non-existant field validation function passed', 'tribe-common' ); + $this->result->error .= ( isset( $this->field['id'] ) ) ? ' (' . esc_html__( 'Field ID:', 'tribe-common' ) . ' ' . $this->field['id'] . ' ' . _x( 'with function name:', 'non-existant function name passed for field validation', 'tribe-common' ) . ' ' . $this->field['validation_type'] . ' )' : ''; + } + } + } + + /** + * validates a field as a string containing only letters and numbers + */ + public function alpha_numeric() { + if ( preg_match( '/^[a-zA-Z0-9]+$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must contain numbers and letters only', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as a string containing only letters, + * numbers and carriage returns + */ + public function alpha_numeric_multi_line() { + if ( preg_match( '/^[a-zA-Z0-9\s]+$/', $this->value ) ) { + $this->result->valid = true; + $this->value = tribe_multi_line_remove_empty_lines( $this->value ); + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must contain numbers and letters only', 'tribe-common' ), $this->label ); + } + } + + /** + * Validates a field as a string containing only letters, + * numbers, dots and carriage returns + */ + public function alpha_numeric_multi_line_with_dots_and_dashes() { + if ( preg_match( '/^[a-zA-Z0-9\s.-]+$/', $this->value ) ) { + $this->result->valid = true; + $this->value = tribe_multi_line_remove_empty_lines( $this->value ); + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must contain numbers, letters and dots only', 'tribe-common' ), $this->label ); + } + } + + /** + * Validates a field as a string containing only letters, + * numbers, dashes and underscores + */ + public function alpha_numeric_with_dashes_and_underscores() { + $this->value = trim( $this->value ); + if ( preg_match( '/^[a-zA-Z0-9_-]+$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must contain numbers, letters, dashes and undescores only', 'tribe-common' ), $this->label ); + } + } + + /** + * Validates a field as just "not empty". + * + * @since 4.7.6 + */ + public function not_empty() { + $this->value = trim( $this->value ); + + if ( empty( $this->value ) ) { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must not be empty', 'tribe-common' ), $this->label ); + } else { + $this->result->valid = true; + } + } + + /** + * validates a field as being positive decimal + */ + public function positive_decimal() { + if ( preg_match( '/^[0-9]+(\.[0-9]+)?$/', $this->value ) && $this->value > 0 ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a positive number.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being positive decimal or percent + */ + public function positive_decimal_or_percent() { + if ( preg_match( '/^[0-9]+(\.[0-9]+)?%?$/', $this->value ) && $this->value > 0 ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a positive number or percent.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being positive integers + */ + public function positive_int() { + if ( preg_match( '/^[0-9]+$/', $this->value ) && $this->value > 0 ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a positive number.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being an integer + * + * The expected value is a whole number (positive or negative). This method is named "int" to + * match the mathematical definition of the word AND to closely match the pre-exiting method + * with a similar name: positive_int(). This method WILL validate whole numbers that go beyond + * values that PHP's int type supports, however, if someone enters something like that, that's + * on them. Smart people do smart things. + */ + public function int() { + if ( preg_match( '/^-?[0-9]+$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a whole number.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates & sanitizes fields as URL slugs + */ + public function slug() { + $maybe_valid_value = esc_url_raw( $this->value ); + + // esc_url_raw does the work of validating chars, but returns the checked string with a + // prepended URL protocol; so let's use strpos to match the values. + if ( + ! empty( $maybe_valid_value ) + && false !== strpos( $maybe_valid_value, $this->value ) + ) { + $this->result->valid = true; + $this->value = sanitize_title( $this->value ); + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a valid slug (numbers, letters, dashes, and underscores).', 'tribe-common' ), $this->label ); + } + } + + /** + * validates & sanitizes fields as URLs + */ + public function url() { + + if ( esc_url_raw( $this->value ) == $this->value ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a valid URL.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates fields that have options (radios, dropdowns, etc.) + * by making sure the value is part of the options array + */ + public function options() { + if ( array_key_exists( $this->value, $this->field['options'] ) ) { + $this->value = ( $this->value === 0 ) ? false : $this->value; + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label ); + } + } + + /** + * Validates fields that have multiple options (checkbox list, etc.) + * by making sure the value is part of the options array. + */ + public function options_multi() { + // if we are here it cannot be empty + if ( empty( $this->value ) ) { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label ); + + return; + } + + $this->value = is_array( $this->value ) ? $this->value : [ $this->value ]; + + foreach ( $this->value as $val ) { + if ( array_key_exists( $val, $this->field['options'] ) ) { + $this->value = ( $this->value === 0 ) ? false : $this->value; + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label ); + } + } + } + + /** + * validates fields that have options (radios, dropdowns, etc.) + * by making sure the value is part of the options array + * then combines the value into an array containing the value + * and name from the option + */ + public function options_with_label() { + if ( array_key_exists( $this->value, $this->field['options'] ) ) { + $this->value = ( $this->value === 0 ) ? false : [ + $this->value, + $this->field['options'][ $this->value ], + ]; + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( "%s must have a value that's part of its options.", 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as not being able to be the same + * as the specified value as specified in + * $this->additional_args['compare_name'] + */ + public function cannot_be_the_same_as() { + if ( ! isset( $this->additional_args['compare'] ) ) { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( 'Comparison validation failed because no comparison value was provided, for field %s', 'tribe-common' ), $this->field['id'] ); + } else { + if ( $this->value != $this->additional_args['compare'] ) { + $this->result = true; + } else { + $this->result->valid = false; + if ( isset( $this->additional_args['compare_name'] ) ) { + $this->result->error = sprintf( esc_html__( '%s cannot be the same as %s.', 'tribe-common' ), $this->label, $this->additional_args['compare_name'] ); + } else { + $this->result->error = sprintf( esc_html__( '%s cannot be a duplicate', 'tribe-common' ), $this->label ); + } + } + } + } + + /** + * validates a field as being a number or a percentage + */ + public function number_or_percent() { + if ( preg_match( '/^[0-9]+%{0,1}$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a number or percentage.', 'tribe-common' ), $this->label ); + } + } + + /** + * sanitizes an html field + */ + public function html() { + $this->value = balanceTags( $this->value ); + $this->result->valid = true; + } + + /** + * sanitizes a license key + */ + public function license_key() { + $this->value = trim( $this->value ); + $this->result->valid = true; + } + + /** + * sanitizes a textarea field + */ + public function textarea() { + $this->value = wp_kses( $this->value, [] ); + $this->result->valid = true; + } + + /** + * sanitizes a field as being a boolean + */ + public function boolean() { + $this->value = (bool) $this->value; + $this->result->valid = true; + } + + /** + * validates a Google Maps Zoom field + */ + public function google_maps_zoom() { + if ( preg_match( '/^([0-9]|[0-1][0-9]|2[0-1])$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a number between 0 and 21.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being part of an address + * allows for letters, numbers, dashes and spaces only + */ + public function address() { + $this->value = stripslashes( $this->value ); + if ( preg_match( "/^[0-9\S '-]+$/", $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must consist of letters, numbers, dashes, apostrophes, and spaces only.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being a city or province + * allows for letters, dashes and spaces only + */ + public function city_or_province() { + $this->value = stripslashes( $this->value ); + if ( preg_match( "/^[\D '\-]+$/", $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must consist of letters, spaces, apostrophes, and dashes.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being a zip code + */ + public function zip() { + if ( preg_match( '/^[0-9]{5}$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must consist of 5 numbers.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates a field as being a phone number + */ + public function phone() { + if ( preg_match( '/^[0-9\(\)\+ -]+$/', $this->value ) ) { + $this->result->valid = true; + } else { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( '%s must be a phone number.', 'tribe-common' ), $this->label ); + } + } + + /** + * validates & sanitizes a field as being a country list + */ + public function country_list() { + $country_rows = explode( "\n", $this->value ); + if ( is_array( $country_rows ) ) { + foreach ( $country_rows as $crow ) { + $country = explode( ',', $crow ); + if ( ! isset( $country[0] ) || ! isset( $country[1] ) ) { + $this->result->valid = false; + $this->result->error = sprintf( esc_html__( 'Country List must be formatted as one country per line in the following format:
          US, United States
          UK, United Kingdom.', 'tribe-common' ), $this->label ); + $this->value = wp_kses( $this->value, [] ); + + return; + } + } + } + $this->result->valid = true; + } + + /** + * automatically validate a field regardless of the value + * Don't use this unless you know what you are doing + */ + public function none() { + $this->result->valid = true; + } + + /** + * Validates and sanitizes an email address. + * + * @since 4.7.4 + */ + public function email( ) { + $candidate = trim( $this->value ); + + $this->result->valid = filter_var( $candidate, FILTER_VALIDATE_EMAIL ); + + if ( ! $this->result->valid ) { + $this->result->error = sprintf( esc_html__( '%s must be an email address.', 'tribe-common' ), $this->label ); + } else { + $this->value = filter_var( trim( $candidate ), FILTER_SANITIZE_EMAIL ); + } + } + + } // end class +} // endif class_exists diff --git a/tribe-common/src/Tribe/Validator/Base.php b/tribe-common/src/Tribe/Validator/Base.php new file mode 100644 index 0000000000..1868922dae --- /dev/null +++ b/tribe-common/src/Tribe/Validator/Base.php @@ -0,0 +1,266 @@ +is_string( $value ); + } + + /** + * Whether the value is a timestamp or a string parseable by the strtotime function or not. + * + * @param mixed $value + * + * @return bool + */ + public function is_time( $value ) { + return is_numeric( $value ) || ( is_string( $value ) && strtotime( $value ) ); + } + + /** + * Whether the value corresponds to an existing user ID or not. + * + * @param mixed $value + * + * @return bool + */ + public function is_user_id( $value ) { + return is_numeric( $value ) && (bool) get_user_by( 'ID', $value ); + } + + /** + * Whether the value is a positive integer or not. + * + * @param mixed $value + * + * @return bool + */ + public function is_positive_int( $value ) { + return is_numeric( $value ) && (int) $value == $value && (int) $value > 0; + } + + /** + * Whether the value is a list of positive integers only or not. + * + * @since 4.7.19 + * + * @param array|string|int $list + * @param string $sep + * + * @return bool + */ + public function is_positive_int_list( $list, $sep = ',' ) { + $sep = is_string( $sep ) ? $sep : ','; + $list = Tribe__Utils__Array::list_to_array( $list, $sep ); + + $valid = array_filter( $list, [ $this, 'is_positive_int' ] ); + + return ! empty( $valid ) && count( $valid ) === count( $list ); + } + + /** + * Trims a string. + * + * Differently from the trim method it will not use the second argument. + * + * @param string $value + * + * @return string + */ + public function trim( $value ) { + return is_string( $value ) ? trim( $value ) : $value; + } + + /** + * Whether the value(s) all map to existing post tags. + * + * @param mixed $tag + * + * @return bool + */ + public function is_post_tag( $tag ) { + return $this->is_term_of_taxonomy( $tag, 'post_tag' ); + } + + /** + * Whether the term exists and is a term of the specified taxonomy. + * + * @param mixed $term Either a single term `term_id` or `slug` or an array of + * `term_id`s and `slug`s + * @param string $taxonomy + * + * @return bool + */ + public function is_term_of_taxonomy( $term, $taxonomy ) { + $terms = Tribe__Utils__Array::list_to_array( $term, ',' ); + + if ( empty( $terms ) ) { + return false; + } + + foreach ( $terms as $t ) { + if ( ! term_exists( $t, $taxonomy ) ) { + return false; + } + } + + return true; + } + + /** + * Whether the provided value points to an existing attachment ID or an existing image URL. + * + * @param int|string $image + * + * @return mixed + */ + public function is_image( $image ) { + if ( $this->is_numeric( $image ) ) { + return wp_attachment_is_image( $image ); + } + + if ( is_string( $image ) ) { + $response = wp_remote_head( $image ); + + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + return false; + } + + $content_type = wp_remote_retrieve_header( $response, 'content-type' ); + + if ( empty( $content_type ) || 0 !== strpos( $content_type, 'image' ) ) { + return false; + } + + $allowed_mime_types = get_allowed_mime_types(); + + return ( in_array( $content_type, $allowed_mime_types ) ); + } + + return false; + } + + /** + * Whether the provided value points to an existing attachment ID, an existing image URL, or is empty. + * + * @param int|string $image + * + * @return mixed + */ + public function is_image_or_empty( $image ) { + if ( empty( $image ) ) { + return true; + } + + return $this->is_image( $image ); + } + + /** + * @param mixed $value + * + * @return bool + */ + public function is_numeric( $value ) { + return is_numeric( $value ); + } + + /** + * Whether a string represents a valid array or not. + * + * Valid means that the string looks like a URL, not that the URL is online and reachable. + * + * @param string $input + * + * @return bool + */ + public function is_url( $input ) { + return (bool) filter_var( $input, FILTER_VALIDATE_URL ); + } + + /** + * Whether a string represents a valid array or not. + * + * Valid means that the string looks like a URL, not that the URL is online and reachable. + * + * @param string $input + * + * @return bool + */ + public function is_url_or_empty( $input ) { + if ( empty( $input ) ) { + return true; + } + + return $this->is_url( $input ); + } + + /** + * Whether a string represents a valid and registered post status or not. + * + * @param string $post_status + * + * @return bool + */ + public function is_post_status( $post_status ) { + $post_stati = get_post_stati(); + if ( empty( $post_stati ) ) { + return false; + } + + return in_array( $post_status, $post_stati ); + } + + /** + * Converts a string, a CSV list to an array. + * + * @since 4.7.19 + * + * @param string|array $list + * + * @return array + */ + public function list_to_array( $list ) { + return Tribe__Utils__Array::list_to_array( $list ); + } +} diff --git a/tribe-common/src/Tribe/Validator/Interface.php b/tribe-common/src/Tribe/Validator/Interface.php new file mode 100644 index 0000000000..820677db16 --- /dev/null +++ b/tribe-common/src/Tribe/Validator/Interface.php @@ -0,0 +1,102 @@ +get_countries(); + } + + // Perform a natural sort: this maintains the key -> index associations but ensures the countries + // are in the expected order, even once translated + natsort( $countries ); + + // Placeholder option ('Select a Country') first by default + $select_country = [ '' => esc_html__( 'Select a Country:', 'tribe-common' ) ]; + $countries = $select_country + $countries; + + if ( ( $postId || $useDefault ) ) { + $countryValue = get_post_meta( $postId, '_EventCountry', true ); + if ( $countryValue ) { + $defaultCountry = [ array_search( $countryValue, $countries ), $countryValue ]; + } else { + $defaultCountry = tribe_get_default_value( 'country' ); + } + if ( $defaultCountry && $defaultCountry[0] != '' ) { + $selectCountry = array_shift( $countries ); + asort( $countries ); + $countries = [ $defaultCountry[0] => $defaultCountry[1] ] + $countries; + $countries = [ '' => $selectCountry ] + $countries; + array_unique( $countries ); + } + } + + tribe_set_var( $cache_var_name, $countries ); + + return $countries; + } + + /** + * Get the i18ned states available to the plugin. + * + * @return array The states array. + */ + public static function loadStates() { + $states = tribe( 'languages.locations' )->get_us_states(); + + /** + * Enables filtering the list of states in the USA available to venues. + * + * @since 4.5.12 + * + * @param array $states The list of states. + */ + return apply_filters( 'tribe_get_state_options', $states ); + } + + /** + * Builds a set of options for displaying an hour chooser + * + * @param string $date the current date (optional) + * @param bool $isStart + * + * @return string a set of HTML options with hours (current hour selected) + */ + public static function getHourOptions( $date = '', $isStart = false ) { + $hours = self::hours(); + + if ( count( $hours ) == 12 ) { + $h = 'h'; + } else { + $h = 'H'; + } + $options = ''; + + if ( empty( $date ) ) { + $hour = ( $isStart ) ? '08' : ( count( $hours ) == 12 ? '05' : '17' ); + } else { + $timestamp = strtotime( $date ); + $hour = date( $h, $timestamp ); + // fix hours if time_format has changed from what is saved + if ( preg_match( '(pm|PM)', $timestamp ) && $h == 'H' ) { + $hour = $hour + 12; + } + if ( $hour > 12 && $h == 'h' ) { + $hour = $hour - 12; + } + } + + $hour = apply_filters( 'tribe_get_hour_options', $hour, $date, $isStart ); + + foreach ( $hours as $hourText ) { + if ( $hour == $hourText ) { + $selected = 'selected="selected"'; + } else { + $selected = ''; + } + $options .= "\n"; + } + + return $options; + } + + /** + * Builds a set of options for displaying a minute chooser + * + * @param string $date the current date (optional) + * @param bool $isStart + * + * @return string a set of HTML options with minutes (current minute selected) + */ + public static function getMinuteOptions( $date = '', $isStart = false ) { + $options = ''; + + if ( empty( $date ) ) { + $minute = '00'; + } else { + $minute = date( 'i', strtotime( $date ) ); + } + + $minute = apply_filters( 'tribe_get_minute_options', $minute, $date, $isStart ); + $minutes = self::minutes( $minute ); + + foreach ( $minutes as $minuteText ) { + if ( $minute == $minuteText ) { + $selected = 'selected="selected"'; + } else { + $selected = ''; + } + $options .= "\n"; + } + + return $options; + } + + /** + * Helper method to return an array of 1-12 for hours + * + * @return array The hours array. + */ + private static function hours() { + $hours = []; + $rangeMax = self::is_24hr_format() ? 23 : 12; + $rangeStart = $rangeMax > 12 ? 0 : 1; + foreach ( range( $rangeStart, $rangeMax ) as $hour ) { + if ( $hour < 10 ) { + $hour = '0' . $hour; + } + $hours[ $hour ] = $hour; + } + + // In a 12hr context lets put 12 at the start (so the sequence will run 12, 1, 2, 3 ... 11) + if ( 12 === $rangeMax ) { + array_unshift( $hours, array_pop( $hours ) ); + } + + return $hours; + } + + /** + * Determines if the provided date/time format (or else the default WordPress time_format) + * is 24hr or not. + * + * In inconclusive cases, such as if there are now hour-format characters, 12hr format is + * assumed. + * + * @param null $format + * @return bool + */ + public static function is_24hr_format( $format = null ) { + // Use the provided format or else use the value of the current time_format setting + $format = ( null === $format ) ? get_option( 'time_format', Tribe__Date_Utils::TIMEFORMAT ) : $format; + + // Count instances of the H and G symbols + $h_symbols = substr_count( $format, 'H' ); + $g_symbols = substr_count( $format, 'G' ); + + // If none have been found then consider the format to be 12hr + if ( ! $h_symbols && ! $g_symbols ) return false; + + // It's possible H or G have been included as escaped characters + $h_escaped = substr_count( $format, '\H' ); + $g_escaped = substr_count( $format, '\G' ); + + // Final check, accounting for possibility of escaped values + return ( $h_symbols > $h_escaped || $g_symbols > $g_escaped ); + } + + /** + * Helper method to return an array of 00-59 for minutes + * + * @param int $exact_minute optionally specify an exact minute to be included (outwith the default intervals) + * + * @return array The minutes array. + */ + private static function minutes( $exact_minute = 0 ) { + $minutes = []; + + // The exact minute should be an absint between 0 and 59 + $exact_minute = absint( $exact_minute ); + + if ( $exact_minute < 0 || $exact_minute > 59 ) { + $exact_minute = 0; + } + + /** + * Filters the amount of minutes to increment the minutes drop-down by + * + * @param int Increment amount (defaults to 5) + */ + $default_increment = apply_filters( 'tribe_minutes_increment', 5 ); + + // Unless an exact minute has been specified we can minimize the amount of looping we do + $increment = ( 0 === $exact_minute ) ? $default_increment : 1; + + for ( $minute = 0; $minute < 60; $minute += $increment ) { + // Skip if this $minute doesn't meet the increment pattern and isn't an additional exact minute + if ( 0 !== $minute % $default_increment && $exact_minute !== $minute ) { + continue; + } + + if ( $minute < 10 ) { + $minute = '0' . $minute; + } + $minutes[ $minute ] = $minute; + } + + return $minutes; + } + + /** + * Builds a set of options for diplaying a meridian chooser + * + * @param string $date YYYY-MM-DD HH:MM:SS to select (optional) + * @param bool $isStart + * + * @return string a set of HTML options with all meridians + */ + public static function getMeridianOptions( $date = '', $isStart = false ) { + if ( strstr( get_option( 'time_format', Tribe__Date_Utils::TIMEFORMAT ), 'A' ) ) { + $a = 'A'; + $meridians = [ 'AM', 'PM' ]; + } else { + $a = 'a'; + $meridians = [ 'am', 'pm' ]; + } + if ( empty( $date ) ) { + $meridian = ( $isStart ) ? $meridians[0] : $meridians[1]; + } else { + $meridian = date( $a, strtotime( $date ) ); + } + + $meridian = apply_filters( 'tribe_get_meridian_options', $meridian, $date, $isStart ); + + $return = ''; + foreach ( $meridians as $m ) { + $return .= "
          - -
          - - - - diff --git a/ui/admin/help.php b/ui/admin/help.php index d3fcae74ca..ed131589e4 100644 --- a/ui/admin/help.php +++ b/ui/admin/help.php @@ -8,9 +8,9 @@

          Pods.io:', 'pods'); ?>

            -
          • documentation and subscribe to our YouTube Channel', 'pods'); ?>. +
          • documentation and subscribe to our YouTube Channel', 'pods'); ?>. -
          • support forums, or you can join our Slack chat', 'pods'); ?>. +
          • support forums, or you can join our Live Community Slack Chat', 'pods'); ?>.
          • bugs or request features, go to our GitHub.', 'pods' ); ?>
          • diff --git a/ui/admin/settings-reset.php b/ui/admin/settings-reset.php index e2ddf27d05..0abfb772ba 100644 --- a/ui/admin/settings-reset.php +++ b/ui/admin/settings-reset.php @@ -44,9 +44,9 @@ if ( ! empty( $old_version ) ) { ?> -

            +

            -

            +

            @@ -55,9 +55,9 @@


            -

            +

            -

            +

            %1$s', $please_note ) . __( 'This does not remove any items from any Post Types, Taxonomies, Media, Users, or Comments data you have added/modified. Any custom fields stored using the table storage component, content in Advanced Content Types, and relationships between posts will be lost.', 'pods' ); ?>

            @@ -67,9 +67,9 @@


            -

            +

            -

            +

            Please Note: This does not remove any items from any Post Types, Taxonomies, Media, Users, or Comments data you have added/modified.', 'pods' ); ?>

            @@ -79,10 +79,22 @@ -

            - -

            -

            Please Note: This does not remove any items from any Post Types, Taxonomies, Media, Users, or Comments data you have added/modified.', 'pods' ); ?>

            +

            + +

            +

            +
              +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +

            @@ -91,10 +103,22 @@


            -

            - -

            -

            Please Note: This does not remove any items from any Post Types, Taxonomies, Media, Users, or Comments data you have added/modified.', 'pods' ); ?>

            +

            + +

            +

            +
              +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • ๐Ÿ†—   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +
            • โŒ   :
            • +

            @@ -107,10 +131,10 @@ ?>


            -

            +

            -

            -

            +

            +

            diff --git a/ui/admin/settings-settings.php b/ui/admin/settings-settings.php index 75722bba7b..6461e23bbb 100644 --- a/ui/admin/settings-settings.php +++ b/ui/admin/settings-settings.php @@ -1 +1,141 @@ -

            +cache_flush_pods(); + + if ( defined( 'PODS_PRELOAD_CONFIG_AFTER_FLUSH' ) && PODS_PRELOAD_CONFIG_AFTER_FLUSH ) { + $api->load_pods( array( 'bypass_cache' => true ) ); + } + + pods_redirect( pods_query_arg( array( 'pods_cache_flushed' => 1 ), array( 'page', 'tab' ) ) ); + } else { + // Handle saving settings. + $action = __( 'saved', 'pods' ); + + $params = pods_unslash( (array) $_POST ); + + $settings_to_save = []; + + $layout_field_types = PodsForm::layout_field_types(); + + foreach ( $fields as $key => $field ) { + // Auto set the field name. + if ( ! isset( $field['name'] ) ) { + $field['name'] = $key; + } + + // Skip layout field types. + if ( isset( $field['type'] ) && in_array( $field['type'], $layout_field_types, true ) ) { + continue; + } + + $value = ''; + + if ( isset( $params[ 'pods_field_' . $field['name'] ] ) ) { + $value = $params[ 'pods_field_' . $field['name'] ]; + } elseif ( 'boolean' === $field['type'] ) { + $value = '0'; + } + + $sanitize_callback = pods_v( 'sanitize_callback', $field, 'sanitize_text_field', true ); + + // Sanitize value if needed. + if ( is_callable( $sanitize_callback ) ) { + $value = $sanitize_callback( $value ); + } + + $settings_to_save[ $field['name'] ] = $value; + } + + if ( $settings_to_save ) { + pods_update_settings( $settings_to_save ); + + $message = sprintf( __( 'Success! %1$s %2$s successfully.', 'pods' ), __( 'Settings', 'pods' ), $action ); + + pods_message( $message ); + } else { + $error = sprintf( __( 'Error: %1$s %2$s successfully.', 'pods' ), __( 'Settings', 'pods' ), $action ); + + pods_message( $error, 'error' ); + } + } +} elseif ( 1 === (int) pods_v( 'pods_cache_flushed' ) ) { + pods_message( __( 'Pods transients and cache have been cleared.', 'pods' ) ); +} + +$do = 'save'; +?> + +

            + +

            + +

            + +

            + +
            + +
            + + + $field ) { + // Auto set the field name. + if ( ! isset( $field['name'] ) ) { + $fields[ $key ]['name'] = $key; + } + + // Skip if not hidden. + if ( 'hidden' !== $field['type'] ) { + continue; + } + + // Output hidden field at top. + echo PodsForm::field( 'pods_field_' . $field['name'], pods_get_setting( $field['name'], pods_v( 'default', $field ) ), 'hidden' ); + + // Remove from list of fields to render below. + unset( $fields[ $key ] ); + } + ?> + + +
            + +

            + + +

            +
            + + diff --git a/ui/admin/settings-tools.php b/ui/admin/settings-tools.php deleted file mode 100644 index 8dfe811028..0000000000 --- a/ui/admin/settings-tools.php +++ /dev/null @@ -1,105 +0,0 @@ -cache_flush_pods(); - - if ( defined( 'PODS_PRELOAD_CONFIG_AFTER_FLUSH' ) && PODS_PRELOAD_CONFIG_AFTER_FLUSH ) { - $api->load_pods( array( 'bypass_cache' => true ) ); - } - - pods_redirect( pods_query_arg( array( 'pods_clearcache' => 1 ), array( 'page', 'tab' ) ) ); - } -} elseif ( 1 == pods_v_sanitized( 'pods_clearcache' ) ) { - pods_message( 'Pods transients and cache have been cleared.' ); -} -?> - -

            - -

            - -

            - -

            - -
            - -

            - -db_version(); -$plugins = array(); - -$all_plugins = get_plugins(); - -foreach ( $all_plugins as $plugin_file => $plugin_data ) { - if ( is_plugin_active( $plugin_file ) ) { - $plugins[ $plugin_data['Name'] ] = $plugin_data['Version']; - } -} - -$stylesheet = get_stylesheet(); -$theme = wp_get_theme( $stylesheet ); -$theme_name = $theme->get( 'Name' ); - -$opcode_cache = array( - 'Apc' => function_exists( 'apc_cache_info' ) ? 'Yes' : 'No', - 'Memcached' => class_exists( 'eaccelerator_put' ) ? 'Yes' : 'No', - 'OPcache' => function_exists( 'opcache_get_status' ) ? 'Yes' : 'No', - 'Redis' => class_exists( 'xcache_set' ) ? 'Yes' : 'No', -); - -$object_cache = array( - 'APC' => function_exists( 'apc_cache_info' ) ? 'Yes' : 'No', - 'APCu' => function_exists( 'apcu_cache_info' ) ? 'Yes' : 'No', - 'Memcache' => class_exists( 'Memcache' ) ? 'Yes' : 'No', - 'Memcached' => class_exists( 'Memcached' ) ? 'Yes' : 'No', - 'Redis' => class_exists( 'Redis' ) ? 'Yes' : 'No', -); - -$versions = array( - 'WordPress Version' => $wp, - 'PHP Version' => $php, - 'MySQL Version' => $mysql, - 'Server Software' => $_SERVER['SERVER_SOFTWARE'], - 'Your User Agent' => $_SERVER['HTTP_USER_AGENT'], - 'Session Save Path' => session_save_path(), - 'Session Save Path Exists' => ( file_exists( session_save_path() ) ? 'Yes' : 'No' ), - 'Session Save Path Writeable' => ( is_writable( session_save_path() ) ? 'Yes' : 'No' ), - 'Session Max Lifetime' => ini_get( 'session.gc_maxlifetime' ), - 'Opcode Cache' => $opcode_cache, - 'Object Cache' => $object_cache, - 'WPDB Prefix' => $wpdb->prefix, - 'WP Multisite Mode' => ( is_multisite() ? 'Yes' : 'No' ), - 'WP Memory Limit' => WP_MEMORY_LIMIT, - 'Current Memory Usage' => number_format_i18n( memory_get_usage() / 1024 / 1024, 3 ) . 'M', - 'Current Memory Usage (real)' => number_format_i18n( memory_get_usage( true ) / 1024 / 1024, 3 ) . 'M', - 'Pods Network-Wide Activated' => ( is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ? 'Yes' : 'No' ), - 'Pods Install Location' => PODS_DIR, - 'Pods Tableless Mode Activated' => ( ( pods_tableless() ) ? 'Yes' : 'No' ), - 'Pods Light Mode Activated' => ( ( pods_light() ) ? 'Yes' : 'No' ), - 'Currently Active Theme' => $theme_name, - 'Currently Active Plugins' => $plugins, -); - -foreach ( $versions as $what => $version ) { - echo '

            ' . esc_html( $what ) . ': '; - - if ( is_array( $version ) ) { - echo '

              '; - - foreach ( $version as $what_v => $v ) { - echo '
            • ' . esc_html( $what_v ) . ': ' . esc_html( $v ) . '
            • '; - } - - echo '
            '; - } else { - echo esc_html( $version ) . '

            '; - } -} diff --git a/ui/admin/settings.php b/ui/admin/settings.php index 2dd50397ca..0524b1d968 100644 --- a/ui/admin/settings.php +++ b/ui/admin/settings.php @@ -1,17 +1,31 @@
            -
            +

            __( 'Settings', 'pods' ), - 'tools' => __( 'Tools', 'pods' ), - 'reset' => __( 'Cleanup & Reset', 'pods' ), - ); + $tabs = [ + 'settings' => __( 'Settings', 'pods' ), + 'reset' => __( 'Cleanup & Reset', 'pods' ), + ]; + + /** + * Allow filtering of settings page tabs. + * + * @since 2.8.0 + * + * @param array $tabs List of settings page tabs. + */ + $tabs = apply_filters( 'pods_admin_settings_tabs', $tabs ); + + $current_tab = pods_v( 'tab', 'get', $default, true ); + + if ( ! isset( $tabs[ $current_tab ] ) ) { + $current_tab = $default; + } ?>
            diff --git a/ui/admin/setup-add.php b/ui/admin/setup-add.php index f82bb69d2c..5b300725c4 100644 --- a/ui/admin/setup-add.php +++ b/ui/admin/setup-add.php @@ -1,25 +1,72 @@ load_pods( [ 'key_names' => true ] ); + +$quick_actions = []; + +if ( ! isset( $all_pods['post'] ) ) { + $quick_actions[] = [ + 'label' => __( 'Add custom fields to Posts', 'pods' ), + 'create_extend' => 'extend', + 'type' => 'post_type', + 'object' => 'post', + ]; +} + +if ( ! isset( $all_pods['page'] ) ) { + $quick_actions[] = [ + 'label' => __( 'Add custom fields to Pages', 'pods' ), + 'create_extend' => 'extend', + 'type' => 'post_type', + 'object' => 'page', + ]; +} + +if ( ! isset( $all_pods['category'] ) ) { + $quick_actions[] = [ + 'label' => __( 'Add custom fields to Categories', 'pods' ), + 'create_extend' => 'extend', + 'type' => 'taxonomy', + 'object' => 'category', + ]; +} + +if ( ! isset( $all_pods['user'] ) ) { + $quick_actions[] = [ + 'label' => __( 'Add custom fields to Users', 'pods' ), + 'create_extend' => 'extend', + 'type' => 'user', + 'object' => 'user', + ]; +} + +/** + * Allow filtering the list of quick actions. + * + * @since 2.8.0 + * + * @param array $quick_actions List of quick actions with the following info: label, create_extend, type, object. + * @param array $all_pods List of pods, keyed by name. + */ +$quick_actions = apply_filters( 'pods_admin_setup_add_quick_actions', $quick_actions, $all_pods ); ?>
            -

            @@ -31,16 +78,14 @@

            load_pods( array( 'key_names' => true ) ); - - if ( !empty( $all_pods ) ) { - $link = pods_query_arg( array( 'page' => 'pods', 'action' . $obj->num => 'manage' ) ); - ?> - « - 'pods', 'action' . $obj->num => 'manage' ] ); + ?> + « +

            @@ -50,11 +95,11 @@
            • - 1 + 1
            • - 2 + 2
            @@ -63,179 +108,270 @@

            - +

            - Content Type Comparison to help you decide.', 'pods' ); ?> + Content Type Comparison to help you decide.', 'pods' ); ?>

            + +

            + + +
            -

            +

            -

            +

            +

            -
            +
            Content Types There are many content types to choose from, we have put together a comparison between them all to help you decide what fits your needs best.', 'pods' ), 'https://pods.io/docs/comparisons/compare-content-types/' ) ); - - $data = array( - 'post_type' => __( 'Custom Post Type (like Posts or Pages)', 'pods' ), - 'taxonomy' => __( 'Custom Taxonomy (like Categories or Tags)', 'pods' ), - 'settings' => __( 'Custom Settings Page', 'pods' ), - 'pod' => '' // component will fill this in if it's enabled (this exists for placement) - ); - - $data = apply_filters( 'pods_admin_setup_add_create_pod_type', $data ); - - if ( empty( $data[ 'pod' ] ) ) - unset( $data[ 'pod' ] ); + echo PodsForm::label( 'create_pod_type', __( 'Content Type', 'pods' ), [ + __( '

            Content Types

            There are many content types to choose from, we have put together a comparison between them all to help you decide what fits your needs best.', 'pods' ), + 'https://docs.pods.io/creating-editing-pods/compare-content-types/', + ] ); + + $data = [ + 'post_type' => __( 'Custom Post Type (like Posts or Pages)', 'pods' ), + 'taxonomy' => __( 'Custom Taxonomy (like Categories or Tags)', 'pods' ), + 'settings' => __( 'Custom Settings Page', 'pods' ), + 'pod' => '' + // component will fill this in if it's enabled (this exists for placement) + ]; + + $data = apply_filters( 'pods_admin_setup_add_create_pod_type', $data ); + + if ( empty( $data['pod'] ) ) { + unset( $data['pod'] ); + } - echo PodsForm::field( 'create_pod_type', pods_v( 'create_pod_type', 'post' ), 'pick', array( 'data' => $data, 'class' => 'pods-dependent-toggle' ) ); + echo PodsForm::field( 'create_pod_type', pods_v( 'create_pod_type', 'post', 'post_type', true ), 'pick', [ + 'data' => $data, + 'dependency' => true, + ] ); ?>
            -
            + if ( ! pods_tableless() && apply_filters( 'pods_admin_setup_add_create_taxonomy_storage', false ) ) { + ?> +
            Storage Types Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), - 'https://pods.io/docs/comparisons/compare-storage-types/' - ) ); - - $data = array( - 'none' => __( 'Do not enable extra fields to be added', 'pods' ), - 'table' => __( 'Enable extra fields for this Taxonomy (Table Based)', 'pods' ) - ); - - $default = 'none'; - - echo PodsForm::field( 'create_storage_taxonomy', pods_v( 'create_storage_taxonomy', 'post', $default, null, true ), 'pick', array( 'data' => $data ) ); + echo PodsForm::label( 'create_storage_taxonomy', __( 'Enable Extra Fields?', 'pods' ), [ + __( '

            Storage Types

            Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), + 'https://docs.pods.io/creating-editing-pods/meta-vs-table-storage/', + ] ); + + $data = [ + 'none' => __( 'Do not enable extra fields to be added', 'pods' ), + 'table' => __( 'Enable extra fields for this Taxonomy (Table Based)', 'pods' ), + ]; + + $default = 'none'; + + echo PodsForm::field( 'create_storage_taxonomy', pods_v( 'create_storage_taxonomy', 'post', $default, null, true ), 'pick', [ + 'data' => $data, + 'depends-on' => [ + 'create_pod_type' => 'taxonomy', + ], + ] ); ?>
            - -
            -
            - Singular Label This is the label for 1 item (Singular) that will appear throughout the WordPress admin area for managing the content.', 'pods' ) ); - echo PodsForm::field( 'create_label_singular', pods_v( 'create_label_singular', 'post' ), 'text', array( 'class' => 'pods-validate pods-validate-required', 'text_max_length' => 30 ) ); - ?> -
            -
            - Plural Label This is the label for more than 1 item (Plural) that will appear throughout the WordPress admin area for managing the content.', 'pods' ) ); - echo PodsForm::field( 'create_label_plural', pods_v( 'create_label_plural', 'post' ), 'text', array( 'text_max_length' => 30 ) ); - ?> -
            +
            + Singular Label This is the label for 1 item (Singular) that will appear throughout the WordPress admin area for managing the content.', 'pods' ) ); + echo PodsForm::field( 'create_label_singular', pods_v( 'create_label_singular', 'post' ), 'text', [ + 'class' => 'pods-validate pods-validate-required', + 'text_max_length' => 30, + 'excludes-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); + ?>
            -
            -
            - Page Title This is the text that will appear at the top of your settings page.', 'pods' ) ); - echo PodsForm::field( 'create_label_title', pods_v( 'create_label_title', 'post' ), 'text', array( 'class' => 'pods-validate pods-validate-required', 'text_max_length' => 30 ) ); - ?> -
            -
            - Menu Label This is the label that will appear throughout the WordPress admin area for your settings.', 'pods' ) ); - echo PodsForm::field( 'create_label_menu', pods_v( 'create_label_menu', 'post' ), 'text', array( 'text_max_length' => 30 ) ); - ?> -
            -
            - Menu Location This is the location where the new settings page will be added in the WordPress Dashboard menu.', 'pods' ) ); - - $data = array( - 'settings' => __( 'Add to Settings menu', 'pods' ), - 'appearances' => __( 'Add to Appearances menu', 'pods' ), - 'top' => __( 'Make a new menu item below Settings', 'pods' ) - ); - - echo PodsForm::field( 'create_menu_location', pods_v( 'create_menu_location', 'post' ), 'pick', array( 'data' => $data ) ); - ?> -
            +
            + Plural Label This is the label for more than 1 item (Plural) that will appear throughout the WordPress admin area for managing the content.', 'pods' ) ); + echo PodsForm::field( 'create_label_plural', pods_v( 'create_label_plural', 'post' ), 'text', [ + 'text_max_length' => 30, + 'excludes-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); + ?> +
            +
            + Page Title This is the text that will appear at the top of your settings page.', 'pods' ) ); + echo PodsForm::field( 'create_label_title', pods_v( 'create_label_title', 'post' ), 'text', [ + 'class' => 'pods-validate pods-validate-required', + 'text_max_length' => 30, + 'depends-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); + ?> +
            +
            + Menu Label This is the label that will appear throughout the WordPress admin area for your settings.', 'pods' ) ); + echo PodsForm::field( 'create_label_menu', pods_v( 'create_label_menu', 'post' ), 'text', [ + 'text_max_length' => 30, + 'depends-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); + ?> +
            +
            + Menu Location This is the location where the new settings page will be added in the WordPress Dashboard menu.', 'pods' ) ); + + $data = [ + 'settings' => __( 'Add to Settings menu', 'pods' ), + 'appearances' => __( 'Add to Appearances menu', 'pods' ), + 'top' => __( 'Make a new menu item below Settings', 'pods' ), + ]; + + echo PodsForm::field( 'create_menu_location', pods_v( 'create_menu_location', 'post' ), 'pick', [ + 'data' => $data, + 'depends-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); + ?>

            - + + +

            -
            +
            prefix . 'pods_' ); - - echo PodsForm::label( 'create_name', __( 'Pod Name', 'pods' ), __( '
            Pod Identifier
            This is different than the labels users will see in the WordPress admin areas, it is the name you will use to programatically reference this object throughout your theme, WordPress, and other PHP.', 'pods' ) ); - echo PodsForm::field( 'create_name', pods_v( 'create_name', 'post' ), 'db', array( 'attributes' => array( 'maxlength' => $max_length_name, 'size' => 25 ) ) ); + global $wpdb; + $max_length_name = 64; + $max_length_name -= 10; // Allow for WP Multisite or prefix changes in the future + $max_length_name -= strlen( $wpdb->prefix . 'pods_' ); + + echo PodsForm::label( 'create_name', __( 'Pod Name', 'pods' ), __( '

            Pod Identifier

            This is different than the labels users will see in the WordPress admin areas, it is the name you will use to programatically reference this object throughout your theme, WordPress, and other PHP.', 'pods' ) ); + echo PodsForm::field( 'create_name', pods_v( 'create_name', 'post' ), 'slug', [ + 'attributes' => [ + 'maxlength' => $max_length_name, + 'size' => 25, + ], + 'excludes-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); ?>
            -
            +
            prefix . 'pods_' ); - - echo PodsForm::label( 'create_setting_name', __( 'Pod Name', 'pods' ), __( '
            Pod Identifier
            This is different than the labels users will see in the WordPress admin areas, it is the name you will use to programatically reference this object throughout your theme, WordPress, and other PHP.', 'pods' ) ); - echo PodsForm::field( 'create_setting_name', pods_v( 'create_setting_name', 'post' ), 'db', array( 'attributes' => array( 'maxlength' => $max_length_name, 'size' => 25 ) ) ); + global $wpdb; + $max_length_name = 64; + $max_length_name -= 10; // Allow for WP Multisite or prefix changes in the future + $max_length_name -= strlen( $wpdb->prefix . 'pods_' ); + + echo PodsForm::label( 'create_setting_name', __( 'Pod Name', 'pods' ), __( '

            Pod Identifier

            This is different than the labels users will see in the WordPress admin areas, it is the name you will use to programatically reference this object throughout your theme, WordPress, and other PHP.', 'pods' ) ); + echo PodsForm::field( 'create_setting_name', pods_v( 'create_setting_name', 'post' ), 'slug', [ + 'attributes' => [ + 'maxlength' => $max_length_name, + 'size' => 25, + ], + 'depends-on' => [ + 'create_pod_type' => 'settings', + ], + ] ); + ?> +
            +
            + 1, + 'depends-on' => [ + 'create_pod_type' => [ + 'post_type', + 'taxonomy', + ], + ], + ] ); ?>
            -
            + if ( ! pods_tableless() && apply_filters( 'pods_admin_setup_add_create_storage', false ) ) { + ?> +
            Storage Types Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), - 'https://pods.io/docs/comparisons/compare-storage-types/' - ) ); - - $data = array( - 'meta' => __( 'Meta Based (WP Default)', 'pods' ), - 'table' => __( 'Table Based', 'pods' ) - ); - - echo PodsForm::field( 'create_storage', pods_v( 'create_storage', 'post' ), 'pick', array( 'data' => $data ) ); + echo PodsForm::label( 'create_storage', __( 'Storage Type', 'pods' ), [ + __( '

            Storage Types

            Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), + 'https://docs.pods.io/creating-editing-pods/meta-vs-table-storage/', + ] ); + + $data = [ + 'meta' => __( 'Meta Based (WP Default)', 'pods' ), + 'table' => __( 'Table Based', 'pods' ), + ]; + + echo PodsForm::field( 'create_storage', pods_v( 'create_storage', 'post' ), 'pick', [ + 'data' => $data, + 'depends-on' => [ + 'create_pod_type' => [ + 'post_type', + 'taxonomy', + ], + ], + ] ); ?>
            -
            @@ -243,159 +379,199 @@
            -

            +

            -

            +

            + +

            -
            +
            Content Types There are many content types to choose from, we have put together a comparison between them all to help you decide what fits your needs best.', 'pods' ), 'https://pods.io/docs/comparisons/compare-content-types/' ) ); - - $data = array( - 'post_type' => __( 'Post Types (Posts, Pages, etc..)', 'pods' ), - 'taxonomy' => '', // component will fill this in if it's enabled (this exists for placement) - 'media' => __( 'Media', 'pods' ), - 'user' => __( 'Users', 'pods' ), - 'comment' => __( 'Comments', 'pods' ) - ); - - if ( function_exists( 'get_term_meta' ) ) { - $data[ 'taxonomy' ] = __( 'Taxonomies (Categories, Tags, etc..)', 'pods' ); - } + echo PodsForm::label( 'extend_pod_type', __( 'Content Type', 'pods' ), [ + __( '

            Content Types

            There are many content types to choose from, we have put together a comparison between them all to help you decide what fits your needs best.', 'pods' ), + 'https://docs.pods.io/creating-editing-pods/compare-content-types/', + ] ); + + $data = [ + 'post_type' => __( 'Post Types (Posts, Pages, etc..)', 'pods' ), + 'taxonomy' => '', + // component will fill this in if it's enabled (this exists for placement) + 'media' => __( 'Media', 'pods' ), + 'user' => __( 'Users', 'pods' ), + 'comment' => __( 'Comments', 'pods' ), + ]; + + if ( function_exists( 'get_term_meta' ) ) { + $data['taxonomy'] = __( 'Taxonomies (Categories, Tags, etc..)', 'pods' ); + } - if ( isset( $all_pods[ 'media' ] ) && 'media' == $all_pods[ 'media' ][ 'type' ] ) - unset( $data[ 'media' ] ); + if ( isset( $all_pods['media'] ) && 'media' == $all_pods['media']['type'] ) { + unset( $data['media'] ); + } - if ( isset( $all_pods[ 'user' ] ) && 'user' == $all_pods[ 'user' ][ 'type' ] ) - unset( $data[ 'user' ] ); + if ( isset( $all_pods['user'] ) && 'user' == $all_pods['user']['type'] ) { + unset( $data['user'] ); + } - if ( isset( $all_pods[ 'comment' ] ) && 'comment' == $all_pods[ 'comment' ][ 'type' ] ) - unset( $data[ 'comment' ] ); + if ( isset( $all_pods['comment'] ) && 'comment' == $all_pods['comment']['type'] ) { + unset( $data['comment'] ); + } - $data = apply_filters( 'pods_admin_setup_add_extend_pod_type', $data ); + $data = apply_filters( 'pods_admin_setup_add_extend_pod_type', $data ); - if ( empty( $data[ 'taxonomy' ] ) ) - unset( $data[ 'taxonomy' ] ); + if ( empty( $data['taxonomy'] ) ) { + unset( $data['taxonomy'] ); + } - echo PodsForm::field( 'extend_pod_type', pods_v( 'extend_pod_type', 'post' ), 'pick', array( 'data' => $data, 'class' => 'pods-dependent-toggle' ) ); + echo PodsForm::field( 'extend_pod_type', pods_v( 'extend_pod_type', 'post', 'post_type', true ), 'pick', [ + 'data' => $data, + 'dependency' => true, + ] ); ?>
            -
            +
            $label ) { - if ( in_array( $post_type, $ignore, true ) || empty( $post_type ) || 0 === strpos( $post_type, '_pods_' ) ) { - // Post type is ignored - unset( $post_types[ $post_type ] ); - - continue; - } - elseif ( isset( $all_pods[ $post_type ] ) && 'post_type' == $all_pods[ $post_type ][ 'type' ] ) { - unset( $post_types[ $post_type ] ); - continue; - } - - $post_type = get_post_type_object( $post_type ); - $post_types[ $post_type->name ] = $post_type->label; + $post_types = get_post_types(); + + foreach ( $post_types as $post_type => $label ) { + if ( in_array( $post_type, $ignore, true ) || empty( $post_type ) || 0 === strpos( $post_type, '_pods_' ) ) { + // Post type is ignored + unset( $post_types[ $post_type ] ); + + continue; + } elseif ( isset( $all_pods[ $post_type ] ) && 'post_type' === $all_pods[ $post_type ]['type'] ) { + unset( $post_types[ $post_type ] ); + + continue; } - echo PodsForm::label( 'extend_post_type', __( 'Post Type', 'pods' ), array( __( '
            Post Types
            WordPress can hold and display many different types of content. Internally, these are all stored in the same place, in the wp_posts table. These are differentiated by a column called post_type.', 'pods' ), 'http://codex.wordpress.org/Post_Types' ) ); - echo PodsForm::field( 'extend_post_type', pods_v( 'extend_post_type', 'post', 'table', null, true ), 'pick', array( 'data' => $post_types ) ); + $post_type = get_post_type_object( $post_type ); + $post_types[ $post_type->name ] = $post_type->label; + } + + echo PodsForm::label( 'extend_post_type', __( 'Post Type', 'pods' ), [ + __( '

            Post Types

            WordPress can hold and display many different types of content. Internally, these are all stored in the same place, in the wp_posts table. These are differentiated by a column called post_type.', 'pods' ), + 'http://codex.wordpress.org/Post_Types', + ] ); + echo PodsForm::field( 'extend_post_type', pods_v( 'extend_post_type', 'post' ), 'pick', [ + 'data' => $post_types, + 'depends-on' => [ + 'extend_pod_type' => 'post_type', + ], + ] ); ?>
            -
            +
            $label ) { - if ( in_array( $taxonomy, $ignore, true ) ) { - // Taxonomy is ignored - unset( $taxonomies[ $taxonomy ] ); - - continue; - } - elseif ( isset( $all_pods[ $taxonomy ] ) && 'taxonomy' == $all_pods[ $taxonomy ][ 'type' ] ) { - unset( $taxonomies[ $taxonomy ] ); - continue; - } - - $taxonomy = get_taxonomy( $taxonomy ); - $taxonomies[ $taxonomy->name ] = $taxonomy->label; + $taxonomies = get_taxonomies(); + + foreach ( $taxonomies as $taxonomy => $label ) { + if ( in_array( $taxonomy, $ignore, true ) ) { + // Taxonomy is ignored + unset( $taxonomies[ $taxonomy ] ); + + continue; + } elseif ( isset( $all_pods[ $taxonomy ] ) && 'taxonomy' == $all_pods[ $taxonomy ]['type'] ) { + unset( $taxonomies[ $taxonomy ] ); + continue; } - echo PodsForm::label( 'extend_taxonomy', __( 'Taxonomy', 'pods' ), array( __( '
            Taxonomies
            A taxonomy is a way to group Post Types.', 'pods' ), 'http://codex.wordpress.org/Taxonomies' ) ); - echo PodsForm::field( 'extend_taxonomy', pods_v( 'extend_taxonomy', 'post' ), 'pick', array( 'data' => $taxonomies ) ); + $taxonomy = get_taxonomy( $taxonomy ); + $taxonomies[ $taxonomy->name ] = $taxonomy->label; + } + + echo PodsForm::label( 'extend_taxonomy', __( 'Taxonomy', 'pods' ), [ + __( '

            Taxonomies

            A taxonomy is a way to group Post Types.', 'pods' ), + 'http://codex.wordpress.org/Taxonomies', + ] ); + echo PodsForm::field( 'extend_taxonomy', pods_v( 'extend_taxonomy', 'post' ), 'pick', [ + 'data' => $taxonomies, + 'depends-on' => [ + 'extend_pod_type' => 'taxonomy', + ], + ] ); ?>
            -
            + if ( ! pods_tableless() && apply_filters( 'pods_admin_setup_add_extend_taxonomy_storage', false ) ) { + ?> +
            Storage Types Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), - 'https://pods.io/docs/comparisons/compare-storage-types/' - ) ); - - $data = array( - 'none' => __( 'Do not enable extra fields to be added', 'pods' ), - 'table' => __( 'Enable extra fields for this Taxonomy (Table Based)', 'pods' ), - ); - - $default = 'none'; - - echo PodsForm::field( 'extend_storage_taxonomy', pods_v( 'extend_storage_taxonomy', 'post', $default, null, true ), 'pick', array( 'data' => $data ) ); + echo PodsForm::label( 'extend_storage_taxonomy', __( 'Enable Extra Fields?', 'pods' ), [ + __( '

            Storage Types

            Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), + 'https://docs.pods.io/creating-editing-pods/meta-vs-table-storage/', + ] ); + + $data = [ + 'none' => __( 'Do not enable extra fields to be added', 'pods' ), + 'table' => __( 'Enable extra fields for this Taxonomy (Table Based)', 'pods' ), + ]; + + $default = 'none'; + + echo PodsForm::field( 'extend_storage_taxonomy', pods_v( 'extend_storage_taxonomy', 'post', $default, null, true ), 'pick', [ + 'data' => $data, + 'depends-on' => [ + 'extend_pod_type' => 'taxonomy', + ], + ] ); ?>
            - +

            + + +

            - if ( function_exists( 'get_term_meta' ) ) { - $extra_class = ' pods-depends-on-extend-pod-type-taxonomy'; - } - ?> -
            -

            +

            - -
            -
            - Storage Types Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), - 'https://pods.io/docs/comparisons/compare-storage-types/' - ) ); - - $data = array( - 'meta' => __( 'Meta Based (WP Default)', 'pods' ), - 'table' => __( 'Table Based', 'pods' ) - ); - - echo PodsForm::field( 'extend_storage', pods_v( 'extend_storage', 'post' ), 'pick', array( 'data' => $data ) ); - ?> -
            +
            +
            + Storage Types Table based storage will operate in a way where each field you create for your content type becomes a field in a table. Meta based storage relies upon the WordPress meta storage table for all field data.', 'pods' ), + 'https://docs.pods.io/creating-editing-pods/meta-vs-table-storage/', + ] ); + + $data = [ + 'meta' => __( 'Meta Based (WP Default)', 'pods' ), + 'table' => __( 'Table Based', 'pods' ), + ]; + + echo PodsForm::field( 'extend_storage', pods_v( 'extend_storage', 'post' ), 'pick', [ + 'data' => $data, + 'depends-on' => [ + 'extend_pod_type' => [ + 'post_type', + 'taxonomy', + 'media', + 'user', + 'comment', + ], + ], + ] ); + ?>
            -
            -
            +
            - + +
            @@ -412,7 +588,8 @@ if ( !isNaN( id ) ) { document.location = 'admin.php?page=pods&action=edit&id=' + id + '&do=create'; - } else { + } + else { document.location = 'admin.php?page=pods&do=create'; } }; @@ -427,17 +604,27 @@ $document.Pods( 'validate' ); $document.Pods( 'submit' ); $document.Pods( 'wizard' ); - $document.Pods( 'dependency' ); $document.Pods( 'advanced' ); $document.Pods( 'confirm' ); $document.Pods( 'sluggable' ); - var $admin = $( '.pods-admin' ), - $toggles = $admin.find( '.pods-dependent-toggle[data-name-clean]' ); + const $quick_actions = $( '.pods-wizard-quick-action' ); + + if ( $quick_actions[0] ) { + $quick_actions.on( 'click', function( e ) { + e.preventDefault(); - $toggles.trigger( 'change' ); - $admin.on( 'render', '.pods-form-ui-field', function ( e ) { - $toggles.trigger( 'change' ); - } ); + const $action = $( this ); + const createExtend = $action.data( 'create-extend' ); + const objectName = $action.data( 'object' ); + const objectType = $action.data( 'type' ); + + jQuery( '#pods_create_extend' ).val( createExtend ); + jQuery( '#pods-form-ui-' + createExtend + '-pod-type' ).val( objectType ); + jQuery( '#pods-form-ui-' + createExtend + '-' + objectType.replace( '_', '-' ) ).val( objectName ); + + $action.closest( 'form' ).submit(); + } ); + } } ); diff --git a/ui/admin/setup-edit-field-fluid.php b/ui/admin/setup-edit-field-fluid.php deleted file mode 100644 index fde62e73a0..0000000000 --- a/ui/admin/setup-edit-field-fluid.php +++ /dev/null @@ -1,310 +0,0 @@ - - - - <?php esc_attr_e( 'Move', 'pods' ); ?> - - - - - - - -
            - - | - - | - - - -
            -
            - - -
            -
            -
              - $label ) { - if ( ! in_array( - $tab, array( - 'basic', - 'additional-field', - 'advanced', - ), true - ) && ( ! isset( $field_tab_options[ $tab ] ) || empty( $field_tab_options[ $tab ] ) ) ) { - continue; - } - - $class = ''; - $extra_classes = ''; - - $tab = sanitize_title( $tab ); - - if ( $tab === $default ) { - $class = ' selected'; - } - - if ( 'additional-field' === $tab ) { - $extra_classes = ' pods-excludes-on pods-excludes-on-field-data-type pods-excludes-on-field-data-type-' . implode( ' pods-excludes-on-field-data-type-', $no_additional ); - } - ?> -
            • - - - -
            • - -
            - -
            -
            -
            - - 'pods-validate pods-validate-required' ) ); ?> -
            -
            - - array( - 'maxlength' => 50, - 'data-sluggable' => 'field_data[' . $pods_i . '][label]', - ), - 'class' => 'pods-validate pods-validate-required pods-slugged-lower pods-slugged-sanitize-title', - ) - ); - ?> -
            -
            - - -
            -
            - - pods_v( 'field_types_select', $field_settings ), - 'class' => 'pods-dependent-toggle', - ) - ); - ?> -
            -
            -
            - - true, - 'data' => pods_v( 'pick_object', $field_settings ), - 'class' => 'pods-dependent-toggle', - ) - ); - ?> -
            -
            - value|Label for separate values and labels', 'pods' ) ); ?> - -
            -
            - - true, - 'data' => pods_v( 'pick_table', $field_settings ), - ) - ); - ?> -
            -
            -
            For example, when you update a Parent pod item to relate to a Child item, when you go to edit that Child item you will see the Parent pod item selected.', 'pods' ) ); ?> - -
            - -
            -
            -
            -
            -

            - -

            - - 'pods-dependent-toggle', - 'boolean_yes_label' => __( 'Required', 'pods' ), - 'help' => __( 'help', 'pods' ) - ) ); - if ( 'table' == $pod[ 'storage' ] ) { - ?> -
            -
              -
            • - -
            • -
            • - 'pods-dependent-toggle', - 'boolean_yes_label' => __( 'Unique', 'pods' ), - 'help' => __( 'help', 'pods' ) - ) ); ?> -
            • -
            -
            - -
            -
            - - $tab_label ) { - $tab = sanitize_title( $tab ); - - if ( 'basic' === $tab || ! isset( $field_tab_options[ $tab ] ) || empty( $field_tab_options[ $tab ] ) ) { - continue; - } - ?> -
            - $field_type_fields ) { - $first_field = current( $field_type_fields ); - ?> -
            - $group_fields ) { - ?> -

            - -
            - $group_fields ) { - ?> -

            - -
            - -
            - -
            -
            - -
            -

            -    - -

            -
            -
            -
            -
            - - - - - - [type: ' . pods_v_sanitized( 'type', $field ) . ']'; - - if ( 'pick' == pods_v_sanitized( 'type', $field ) && '' != pods_v_sanitized( 'pick_object', $field, '' ) ) { - $pick_object_name = null; - - foreach ( $field_settings[ 'pick_object' ] as $object => $object_label ) { - if ( null !== $pick_object_name ) { - break; - } - - if ( '-- Select --' === $object_label ) { - continue; - } - - if ( is_array( $object_label ) ) { - foreach ( $object_label as $sub_object => $sub_object_label ) { - if ( $pick_object === $sub_object ) { - $object = rtrim( $object, 's' ); - - if ( false !== strpos( $object, 'ies' ) ) { - $object = str_replace( 'ies', 'y', $object ); - } - - $pick_object_name = esc_html( $sub_object_label ) . ' (' . esc_html( $object ) . ')'; - - break; - } - } - } elseif ( pods_v_sanitized( 'pick_object', $field ) === $object ) { - $pick_object_name = $object_label; - - break; - } - }//end foreach - - if ( null === $pick_object_name ) { - $pick_object_name = ucwords( str_replace( array( - '-', - '_' - ), ' ', pods_v( 'pick_object', $field ) ) ); - - if ( 0 < strlen( pods_v( 'pick_val', $field ) ) ) { - $pick_object_name = pods_v( 'pick_val', $field ) . ' (' . $pick_object_name . ')'; - } - } - ?> -
            - - - diff --git a/ui/admin/setup-edit-field.php b/ui/admin/setup-edit-field.php deleted file mode 100644 index 93cf90f020..0000000000 --- a/ui/admin/setup-edit-field.php +++ /dev/null @@ -1,159 +0,0 @@ - $pods_i, -); -?> -> - - <?php esc_attr_e( 'Move', 'pods' ); ?> - - - - - - - * - - - - - [id: ] - - - -
            - - | - - | - - - -
            -
            - =' ) ? json_encode( $field, JSON_UNESCAPED_UNICODE ) : json_encode( $field ) ); - $hidden_field_value = str_replace( '&', '&', $hidden_field_value ); - ?> - - -
            - -
            -
            - - - - - - (' . esc_html__( 'Bi-directional Field', 'pods' ) . ')'; - } - - echo $type . ' [type: ' . esc_html( $field_type ) . ']'; - - $pick_object = trim( pods_v( 'pick_object', $field ) . '-' . pods_v( 'pick_val', $field ), '-' ); - - if ( 'pick' === pods_v( 'type', $field ) && '' !== pods_v( 'pick_object', $field, '' ) ) { - $pick_object_name = null; - - foreach ( $field_settings['pick_object'] as $object => $object_label ) { - if ( null !== $pick_object_name ) { - break; - } - - if ( '-- Select --' === $object_label ) { - continue; - } - - if ( is_array( $object_label ) ) { - foreach ( $object_label as $sub_object => $sub_object_label ) { - if ( $pick_object === $sub_object ) { - $ies = strlen( $object ) - 3; - - if ( $ies === strpos( $object, 'ies' ) ) { - $object = substr( $object, 0, $ies ) . 'y'; - } - - $object = rtrim( $object, 's' ); - - $pick_object_name = esc_html( $sub_object_label ) . ' (' . esc_html( $object ) . ')'; - - break; - } - } - } elseif ( pods_v( 'pick_object', $field ) === $object ) { - $pick_object_name = esc_html( $object_label ); - - break; - }//end if - }//end foreach - - if ( null === $pick_object_name ) { - $pick_object_name = esc_html( ucwords( str_replace( array( '-', '_' ), ' ', pods_v( 'pick_object', $field ) ) ) ); - - if ( 0 < strlen( pods_v( 'pick_val', $field ) ) ) { - $pick_object_name = esc_html( pods_v( 'pick_val', $field ) . ' (' . $pick_object_name . ')' ); - } - } - ?> - -
            - - - diff --git a/ui/admin/setup-edit.php b/ui/admin/setup-edit.php index 70d6bc4c6e..8d34e7769b 100644 --- a/ui/admin/setup-edit.php +++ b/ui/admin/setup-edit.php @@ -1,926 +1,18 @@ 'edit-pod', + 'fieldEmbed' => false, +]; -$pod = $api->load_pod( array( 'id' => $obj->id ) ); - -$pod_type = pods_v( 'type', $pod ); - -if ( 'taxonomy' == $pod[ 'type' ] && 'none' == $pod[ 'storage' ] && 1 == pods_v( 'enable_extra_fields' ) ) { - $api->save_pod( array( 'id' => $obj->id, 'storage' => 'table' ) ); - - $pod = $api->load_pod( array( 'id' => $obj->id ) ); - - unset( $_GET[ 'enable_extra_fields' ] ); - - pods_message( __( 'Extra fields were successfully enabled for this Custom Taxonomy.', 'pods' ) ); -} - -$field_types = PodsForm::field_types(); - -$field_types_select = array(); - -foreach ( $field_types as $type => $field_type_data ) { - /** - * @var $field_type PodsField - */ - $field_type = PodsForm::field_loader( $type, $field_type_data[ 'file' ] ); - - $field_type_vars = get_class_vars( get_class( $field_type ) ); - - if ( !isset( $field_type_vars[ 'pod_types' ] ) ) - $field_type_vars[ 'pod_types' ] = true; - - // Only show supported field types - if ( true !== $field_type_vars[ 'pod_types' ] ) { - if ( empty( $field_type_vars[ 'pod_types' ] ) ) - continue; - elseif ( is_array( $field_type_vars[ 'pod_types' ] ) && !in_array( $pod_type, $field_type_vars[ 'pod_types' ], true ) ) - continue; - elseif ( !is_array( $field_type_vars[ 'pod_types' ] ) && $pod_type != $field_type_vars[ 'pod_types' ] ) - continue; - } - - if ( !empty( PodsForm::$field_group ) ) { - if ( !isset( $field_types_select[ PodsForm::$field_group ] ) ) - $field_types_select[ PodsForm::$field_group ] = array(); - - $field_types_select[ PodsForm::$field_group ][ $type ] = $field_type_data[ 'label' ]; - } - else { - if ( !isset( $field_types_select[ __( 'Other', 'pods' ) ] ) ) - $field_types_select[ __( 'Other', 'pods' ) ] = array(); - - $field_types_select[ __( 'Other', 'pods' ) ][ $type ] = $field_type_data[ 'label' ]; - } -} - -$field_defaults = array( - 'name' => 'new_field', - 'label' => 'New Field', - 'description' => '', - 'type' => 'text', - 'pick_object' => '', - 'sister_id' => '', - 'required' => 0, - 'unique' => 0, -); - -$pick_object = PodsForm::field_method( 'pick', 'related_objects', true ); - -$tableless_field_types = PodsForm::tableless_field_types(); -$simple_tableless_objects = PodsForm::field_method( 'pick', 'simple_objects' ); -$bidirectional_objects = PodsForm::field_method( 'pick', 'bidirectional_objects' ); - -foreach ( $pod[ 'options' ] as $_option => $_value ) { - $pod[ $_option ] = $_value; -} - -foreach ( $pod[ 'fields' ] as $_field => $_data ) { - $_data[ 'options' ] = (array) $_data[ 'options' ]; - - foreach ( $_data[ 'options' ] as $_option => $_value ) { - $pod[ 'fields' ][ $_field ][ $_option ] = $_value; - } -} - -$pod_name = $pod[ 'name' ]; - -$field_defaults = apply_filters( 'pods_field_defaults', apply_filters( "pods_field_defaults_{$pod_name}", $field_defaults, $pod ) ); - -$pick_table = pods_transient_get( 'pods_tables' ); - -if ( empty( $pick_table ) ) { - $pick_table = array( - '' => __( '-- Select Table --', 'pods' ) - ); - - global $wpdb; - - $tables = $wpdb->get_results( "SHOW TABLES", ARRAY_N ); - - if ( !empty( $tables ) ) { - foreach ( $tables as $table ) { - $pick_table[ $table[ 0 ] ] = $table[ 0 ]; - } - } - - pods_transient_set( 'pods_tables', $pick_table ); -} - -$field_settings = array( - 'field_types_select' => $field_types_select, - 'field_defaults' => $field_defaults, - 'pick_object' => $pick_object, - 'pick_table' => $pick_table, - 'sister_id' => array( '' => __( 'No Related Fields Found', 'pods' ) ) -); - -$field_settings = apply_filters( 'pods_field_settings', apply_filters( "pods_field_settings_{$pod_name}", $field_settings, $pod ) ); - -$pod[ 'fields' ] = apply_filters( 'pods_fields_edit', apply_filters( "pods_fields_edit_{$pod_name}", $pod[ 'fields' ], $pod ) ); - -global $wpdb; -$max_length_name = 64; -$max_length_name -= 10; // Allow for WP Multisite or prefix changes in the future -$max_length_name -= strlen( $wpdb->prefix . 'pods_' ); - -$tabs = PodsInit::$admin->admin_setup_edit_tabs( $pod ); -$tab_options = PodsInit::$admin->admin_setup_edit_options( $pod ); - -$field_tabs = PodsInit::$admin->admin_setup_edit_field_tabs( $pod ); -$field_tab_options = PodsInit::$admin->admin_setup_edit_field_options( $pod ); - -$no_additional = array(); - -foreach ( $field_tab_options[ 'additional-field' ] as $field_type => $field_type_fields ) { - if ( empty( $field_type_fields ) ) - $no_additional[] = $field_type; -} - -/** - * Make use of the WP core meta box functionality - * - * Currently only context 'side' is available - * - * @since 2.7.0 - * @see https://codex.wordpress.org/Plugin_API/Action_Reference/add_meta_boxes - * @param array $pod The Pod object as an array - */ -do_action( 'pods_add_meta_boxes', '_pods_pod', $pod ); - -$pod_post = get_post( $pod['id'] ); - -/** This action is documented in wp-admin/edit-form-advanced.php */ -do_action( 'add_meta_boxes', $pod_post->post_type, $pod_post ); +$data = wp_json_encode( $data, JSON_HEX_TAG ); ?>
            -

            - -
            - - - - - - -

            - : - - - - - - - - - - array( - 'maxlength' => $max_length_name, - 'size' => 25 - ), - 'class' => 'pods-validate pods-validate-required' - ) ); ?> - - - - -

            - - - - - +

            +
            - -Success! %1$s %2$s successfully.', 'pods' ), $obj->item, $action ); - - echo $obj->message( $message ); -} -?> - -
            - - -
            -
            - - -
            -

            - -

            - - ' . __( 'Manage Fields', 'pods' ) . ''; - - do_action( 'pods_admin_ui_setup_edit_fields', $pod, $obj ); - ?> - - - - - - - - - - - - - - - - - - - - - '__1', - 'name' => '', - 'label' => '', - 'type' => 'text' - ); - - include PODS_DIR . 'ui/admin/setup-edit-field-fluid.php'; - - $pods_i = 1; - - foreach ( $pod[ 'fields' ] as $field ) { - include PODS_DIR . 'ui/admin/setup-edit-field.php'; - - $pods_i++; - } - ?> - - - - -
            -   - - " . __( 'Label', 'pods' ) . "" . __( 'The label is the descriptive name to identify the Pod field.', 'pods' ) ); ?> - - " . __( 'Name', 'pods' ) . "" . __( 'The name attribute is what is used to identify and access the Pod field programatically.', 'pods' ) ); ?> - - " . __( 'Field Type', 'pods' ) . "" . __( 'Field types are used to determine what kind of data will be stored in the Pod. They can range from, dates, text, files, etc.', 'pods' ) ); ?> -
            -   - - " . __( 'Label', 'pods' ) . "" . __( 'The label is the descriptive name to identify the Pod field.', 'pods' ) ); ?> - - " . __( 'Name', 'pods' ) . "" . __( 'The name attribute is what is used to identify and access the Pod field programatically.', 'pods' ) ); ?> - - " . __( 'Field Type', 'pods' ) . "" . __( 'Field types are used to determine what kind of data will be stored in the Pod. They can range from, dates, text, files, etc.', 'pods' ) ); ?> -
            - -

            - -

            -
            - -
            - -
            - -
            - -
            -

            - -

            - -
            -
              -
            • -
              - __( 'Title', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Editor', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Author', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Featured Image', 'pods' ), 'dependency' => true ) ); ?> -
              -
            • -
            • -
              - __( 'Excerpt', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Trackbacks', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Custom Fields', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Comments', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Revisions', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Page Attributes', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Post Formats', 'pods' ) ) ); ?> -
              -
            • - - -
            • -
              - __( 'Genesis: SEO', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Genesis: Layouts', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Genesis: Simple Sidebars', 'pods' ) ) ); ?> -
              -
            • - - - -
            • -
              - __( 'YARPP Support', 'pods' ) ) ); ?> -
              -
            • - - - -
            • -
              - __( 'Jetpack Publicize Support', 'pods' ) ) ); ?> -
              -
            • -
            • -
              - __( 'Jetpack Markdown Support', 'pods' ) ) ); ?> -
              -
            • - -
            -
            -
            -
            - - -
            -
            -

            - -

            - -
            -
              - $label ) { - $taxonomy = pods_str_replace( 'taxonomy-', '', $taxonomy, 1 ); - ?> -
            • -
              - $label . ' (' . $taxonomy . ')' ) ); ?> -
              -
            • - -
            -
            -
            - -
            -

            - -

            - -
            -
              - $label ) { - $post_type = pods_str_replace( 'post_type-', '', $post_type, 1 ); - $label = str_replace( array( '(', ')' ), array( '(', ')' ), $label ); - ?> -
            • -
              - $label ) ); ?> -
              -
            • - -
            • -
              - 'Media (attachment)' ) ); ?> -
              -
            • -
            -
            -
            - -
            - - -
            - - 'ID' ); - - foreach ( $pod[ 'fields' ] as $field ) { - if ( !in_array( $field[ 'type' ], $tableless_field_types, true ) ) - $index_fields[ $field[ 'name' ] ] = $field[ 'label' ]; - } - ?> - -
            - - $index_fields ) ); ?> -
            - -
            - - true, 'boolean_yes_label' => '' ) ); ?> -
            - - __( 'No Hierarchical Fields found', 'pods' ) ); - ?> - -
            - - $hierarchical_fields ) ); ?> -
            - - - -
            - '-- Select --' ); - - $helpers = $api->load_helpers( array( 'options' => array( 'helper_type' => 'pre_save' ) ) ); - - foreach ( $helpers as $helper ) { - $pre_save_helpers[ $helper[ 'name' ] ] = $helper[ 'name' ]; - } - - echo PodsForm::label( 'pre_save_helpers', __( 'Pre-Save Helper(s)', 'pods' ), __( 'help', 'pods' ) ); - echo PodsForm::field( 'pre_save_helpers', pods_v( 'pre_save_helpers', $pod ), 'pick', array( 'data' => $pre_save_helpers ) ); - ?> -
            -
            - '-- Select --' ); - - $helpers = $api->load_helpers( array( 'options' => array( 'helper_type' => 'post_save' ) ) ); - - foreach ( $helpers as $helper ) { - $post_save_helpers[ $helper[ 'name' ] ] = $helper[ 'name' ]; - } - - echo PodsForm::label( 'post_save_helpers', __( 'Post-Save Helper(s)', 'pods' ), __( 'help', 'pods' ) ); - echo PodsForm::field( 'post_save_helpers', pods_v( 'post_save_helpers', $pod ), 'pick', array( 'data' => $post_save_helpers ) ); - ?> -
            -
            - '-- Select --' ); - - $helpers = $api->load_helpers( array( 'options' => array( 'helper_type' => 'pre_delete' ) ) ); - - foreach ( $helpers as $helper ) { - $pre_delete_helpers[ $helper[ 'name' ] ] = $helper[ 'name' ]; - } - - echo PodsForm::label( 'pre_delete_helpers', __( 'Pre-Delete Helper(s)', 'pods' ), __( 'help', 'pods' ) ); - echo PodsForm::field( 'pre_delete_helpers', pods_v( 'pre_delete_helpers', $pod ), 'pick', array( 'data' => $pre_delete_helpers ) ); - ?> -
            -
            - '-- Select --' ); - - $helpers = $api->load_helpers( array( 'options' => array( 'helper_type' => 'post_delete' ) ) ); - - foreach ( $helpers as $helper ) { - $post_delete_helpers[ $helper[ 'name' ] ] = $helper[ 'name' ]; - } - - echo PodsForm::label( 'post_delete_helpers', __( 'Post-Delete Helper(s)', 'pods' ), __( 'help', 'pods' ) ); - echo PodsForm::field( 'post_delete_helpers', pods_v( 'post_delete_helpers', $pod ), 'pick', array( 'data' => $post_delete_helpers ) ); - ?> -
            - -
            - $tab_label ) { - $tab = sanitize_title( $tab ); - - if ( in_array( $tab, array( 'manage-fields', 'labels', 'advanced', 'extra-fields' ), true ) || !isset( $tab_options[ $tab ] ) || empty( $tab_options[ $tab ] ) ) - continue; -?> -
            - -
            - -
            -

            - -

            %s.', 'pods' ), $wpdb->prefix . 'pods_' . pods_v( 'name', $pod ) ); ?>

            - -

            »

            - -

            - -

            -
            - -
            - - -
            -
            -
            -
            -

            (« ) -

            -
            -
            -
            -
            - Pod -
            -
            - - -
            -
            -
            -
            -
            -
            - -
            - -
            -
            -
            -
            -
            - -
            - - -
            - diff --git a/ui/admin/upgrade/upgrade_2_0_0.php b/ui/admin/upgrade/upgrade_2_0_0.php index cffddc3131..c0743f0ab4 100644 --- a/ui/admin/upgrade/upgrade_2_0_0.php +++ b/ui/admin/upgrade/upgrade_2_0_0.php @@ -2,9 +2,6 @@ global $wpdb; ?>
            -

            diff --git a/ui/admin/upgrade/upgrade_2_1_0.php b/ui/admin/upgrade/upgrade_2_1_0.php index 739f45f6ff..72d90b6c89 100644 --- a/ui/admin/upgrade/upgrade_2_1_0.php +++ b/ui/admin/upgrade/upgrade_2_1_0.php @@ -2,9 +2,6 @@ global $wpdb; ?>
            -

            diff --git a/ui/admin/view.php b/ui/admin/view.php index 2cf0d8e382..3e5d44f05e 100644 --- a/ui/admin/view.php +++ b/ui/admin/view.php @@ -187,7 +187,7 @@ } /** This filter is documented in classes/PodsMeta.php */ - $title = apply_filters( 'pods_meta_default_box_title', $title, $pod, $fields, $pod->api->pod_data['type'], $pod->pod ); + $title = apply_filters( 'pods_meta_default_box_title', $title, $pod, $fields, $pod->pod_data['type'], $pod->pod ); ?>
            diff --git a/ui/admin/widgets/list.php b/ui/admin/widgets/list.php index 46a98f7284..e5df1980f7 100644 --- a/ui/admin/widgets/list.php +++ b/ui/admin/widgets/list.php @@ -10,7 +10,7 @@ } -

            magic tags.', 'pods'); ?>

            +

            magic tags.', 'pods'); ?>

            1. diff --git a/ui/admin/widgets/single.php b/ui/admin/widgets/single.php index 7e5a7e06a1..eb003e6893 100644 --- a/ui/admin/widgets/single.php +++ b/ui/admin/widgets/single.php @@ -10,7 +10,7 @@ } -

              magic tags.', 'pods'); ?>

              +

              magic tags.', 'pods'); ?>

              1. diff --git a/ui/fields/attachment.php b/ui/fields/attachment.php index 2bcca7fd15..f385450a5b 100644 --- a/ui/fields/attachment.php +++ b/ui/fields/attachment.php @@ -5,10 +5,8 @@ wp_enqueue_script( 'jquery-ui-core' ); wp_enqueue_script( 'jquery-ui-sortable' ); wp_enqueue_script( 'thickbox' ); -wp_enqueue_script( 'pods-attach' ); wp_enqueue_style( 'thickbox' ); -wp_enqueue_style( 'pods-attach' ); $field_file = PodsForm::field_loader( 'file' ); diff --git a/ui/fields/text.php b/ui/fields/text.php index 0ac2101cbc..ee67a0192f 100644 --- a/ui/fields/text.php +++ b/ui/fields/text.php @@ -15,4 +15,4 @@ ?> /> +
                + + + < + class="pods-form-ui-heading pods-form-ui-heading-"> + + > + + + + + + +
                diff --git a/ui/forms/div-rows.php b/ui/forms/div-rows.php new file mode 100644 index 0000000000..abe7efe76e --- /dev/null +++ b/ui/forms/div-rows.php @@ -0,0 +1,57 @@ +field( [ 'name' => $field['name'], 'in_form' => true ] ); + } + + $row_classes = $field_row_classes . ' pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ); + $row_classes = trim( $row_classes ); + + if ( ! empty( $pre_callback ) && is_callable( $pre_callback ) ) { + $pre_callback( $field['name'], $id, $field, $pod ); + } + + pods_view( PODS_DIR . 'ui/forms/div-row.php', compact( array_keys( get_defined_vars() ) ) ); + + if ( ! empty( $post_callback ) && is_callable( $post_callback ) ) { + $post_callback( $field['name'], $id, $field, $pod ); + } +} diff --git a/ui/forms/form.php b/ui/forms/form.php new file mode 100644 index 0000000000..5028e90483 --- /dev/null +++ b/ui/forms/form.php @@ -0,0 +1,234 @@ +pod_data['type']; + +if ( empty( $fields ) || ! is_array( $fields ) ) { + $fields = $obj->pod->fields; +} + +if ( ! isset( $duplicate ) || $is_settings_pod ) { + $duplicate = false; +} else { + $duplicate = (boolean) $duplicate; +} + +$groups = PodsInit::$meta->groups_get( $pod->pod_data['type'], $pod->pod_data['name'], $fields ); + +if ( 1 === count( $groups ) ) { + $first_group = current( $groups ); + + if ( 0 === count( $first_group['fields'] ) ) { + $groups = []; + } +} + +$pod_name = $pod->pod_data['name']; +$pod_options = $pod->pod_data['options']; +$pod_options = apply_filters( "pods_advanced_content_type_pod_data_{$pod_name}", $pod_options, $pod->pod_data['name'] ); +$pod_options = apply_filters( 'pods_advanced_content_type_pod_data', $pod_options, $pod->pod_data['name'] ); + +$group_fields = array(); +$submittable_fields = array(); + +foreach ( $groups as $g => $group ) { + // unset fields + foreach ( $group['fields'] as $k => $field ) { + if ( in_array( $field['name'], array( 'created', 'modified' ), true ) ) { + unset( $group['fields'][ $k ] ); + + continue; + } elseif ( ! pods_permission( $field ) ) { + if ( (boolean) pods_v( 'hidden', $field['options'], false ) ) { + $group['fields'][ $k ]['type'] = 'hidden'; + } elseif ( (boolean) pods_v( 'read_only', $field['options'], false ) ) { + $group['fields'][ $k ]['readonly'] = true; + } else { + unset( $group['fields'][ $k ] ); + + continue; + } + } elseif ( ! pods_has_permissions( $field ) ) { + if ( (boolean) pods_v( 'hidden', $field['options'], false ) ) { + $group['fields'][ $k ]['type'] = 'hidden'; + } elseif ( (boolean) pods_v( 'read_only', $field['options'], false ) ) { + $group['fields'][ $k ]['readonly'] = true; + } + }//end if + + if ( ! pods_v_sanitized( 'readonly', $field, false ) ) { + $submittable_fields[ $field['name'] ] = $group['fields'][ $k ]; + } + + $group_fields[ $field['name'] ] = $group['fields'][ $k ]; + }//end foreach + $groups[ $g ] = $group; +}//end foreach + +if ( ! isset( $thank_you_alt ) ) { + $thank_you_alt = $thank_you; +} + +$uri_hash = wp_create_nonce( 'pods_uri_' . pods_current_path() ); +$field_hash = wp_create_nonce( 'pods_fields_' . implode( ',', array_keys( $submittable_fields ) ) ); + +if ( is_user_logged_in() ) { + $uid = 'user_' . get_current_user_id(); +} else { + $uid = pods_session_id(); +} + +$nonce = wp_create_nonce( 'pods_form_' . $pod->pod . '_' . $uid . '_' . ( $duplicate ? 0 : $pod->id() ) . '_' . $uri_hash . '_' . $field_hash ); + +$submit_result = null; + +if ( isset( $_POST['_pods_nonce'] ) ) { + try { + $params = pods_unslash( (array) $_POST ); + $id = $pod->api->process_form( $params, $pod, $submittable_fields, $thank_you ); + + $submit_result = 0 < $id; + } catch ( Exception $e ) { + echo $obj->error( $e->getMessage() ); + } +} elseif ( isset( $_GET['do'] ) ) { + $submit_result = 0 < $pod->id(); +} + +if ( null !== $submit_result ) { + $messages = [ + 'success' => __( 'Success!', 'pods' ), + 'error' => __( 'Error:', 'pods' ), + // translators: %s: The singular item label. + 'view_item' => __( 'View %s', 'pods' ), + // translators: %s: The singular item label. + 'success_saved' => _x( '%s saved successfully', 'The success message shown after saving form', 'pods' ), + // translators: %s: The singular item label. + 'success_created' => _x( '%s created successfully', 'The success message shown after saving form', 'pods' ), + // translators: %s: The singular item label. + 'success_duplicated' => _x( '%s duplicated successfully', 'The success message shown after saving form', 'pods' ), + // translators: %s: The singular item label. + 'error_saved' => _x( '%s not saved', 'The error message shown after saving form', 'pods' ), + // translators: %s: The singular item label. + 'error_created' => _x( '%s not created', 'The error message shown after saving form', 'pods' ), + // translators: %s: The singular item label. + 'error_duplicated' => _x( '%s not duplicated', 'The error message shown after saving form', 'pods' ), + ]; + + $success_message = sprintf( '%1$s %2$s.', $messages['success'], $messages['success_saved'] ); + $error_message = sprintf( '%1$s %2$s.', $messages['error'], $messages['error_saved'] ); + + if ( ! $is_settings_pod ) { + if ( 'create' === pods_v( 'do', 'post', pods_v( 'do', 'get', 'save' ) ) ) { + $success_message = sprintf( '%1$s %2$s.', $messages['success'], $messages['success_created'] ); + $error_message = sprintf( '%1$s %2$s.', $messages['error'], $messages['error_created'] ); + } elseif ( 'duplicate' === pods_v( 'do', 'get', 'save' ) ) { + $success_message = sprintf( '%1$s %2$s.', $messages['success'], $messages['success_duplicated'] ); + $error_message = sprintf( '%1$s %2$s.', $messages['error'], $messages['error_duplicated'] ); + } + } + + if ( $submit_result ) { + $message = sprintf( $success_message, $obj->item ); + + if ( ! $is_settings_pod && ! empty( $pod_options['detail_url'] ) ) { + $message_view = + $message .= sprintf( + ' %2$s', + esc_url( $pod->field( 'detail_url' ) ), + esc_html( sprintf( $messages['view_item'], $obj->item ) ) + ); + } + + echo $obj->message( $message ); + } else { + $error = sprintf( $error_message, $obj->item ); + + echo $obj->error( $error ); + } +} + +if ( ! isset( $label ) ) { + $label = __( 'Save', 'pods' ); +} + +$do = 'create'; + +if ( 0 < $pod->id() ) { + if ( $duplicate ) { + $do = 'duplicate'; + } else { + $do = 'save'; + } +} +?> + +
                +
                + pod, 'hidden' ); + echo PodsForm::field( '_pods_id', ( $duplicate ? 0 : $pod->id() ), 'hidden' ); + echo PodsForm::field( '_pods_uri', $uri_hash, 'hidden' ); + echo PodsForm::field( '_pods_form', implode( ',', array_keys( $submittable_fields ) ), 'hidden' ); + echo PodsForm::field( '_pods_location', $_SERVER['REQUEST_URI'], 'hidden' ); + + pods_view( PODS_DIR . 'ui/forms/type/' . sanitize_title( $form_type ) . '.php', compact( array_keys( get_defined_vars() ) ) ); + ?> +
                +
                + + diff --git a/ui/forms/list-row.php b/ui/forms/list-row.php new file mode 100644 index 0000000000..cf87ed655c --- /dev/null +++ b/ui/forms/list-row.php @@ -0,0 +1,33 @@ + +
              2. + + + < + class="pods-form-ui-heading pods-form-ui-heading-"> + + > + + + + +
                + +
                + +
                + id() ); ?> + +
                + +
              3. diff --git a/ui/forms/list-rows.php b/ui/forms/list-rows.php new file mode 100644 index 0000000000..fb78299e57 --- /dev/null +++ b/ui/forms/list-rows.php @@ -0,0 +1,68 @@ +field( [ 'name' => $field['name'], 'in_form' => true ] ); + } + + $row_classes = $field_row_classes . ' pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ); + + /** + * Filter the html class used on form field list item element. + * + * @since 2.7.2 + * + * @param string $html_class The HTML class. + * @param array $field The current field. + */ + $row_classes = apply_filters( 'pods_form_html_class', $row_classes ); + + $row_classes = trim( $row_classes ); + + if ( ! empty( $pre_callback ) && is_callable( $pre_callback ) ) { + $pre_callback( $field['name'], $id, $field, $pod ); + } + + pods_view( PODS_DIR . 'ui/forms/list-row.php', compact( array_keys( get_defined_vars() ) ) ); + + if ( ! empty( $post_callback ) && is_callable( $post_callback ) ) { + $post_callback( $field['name'], $id, $field, $pod ); + } +} diff --git a/ui/forms/p-row.php b/ui/forms/p-row.php new file mode 100644 index 0000000000..e8c79fe473 --- /dev/null +++ b/ui/forms/p-row.php @@ -0,0 +1,33 @@ + +
                + + + < + class="pods-form-ui-heading pods-form-ui-heading-"> + + > + + + + + + class=" + > + +

                + +
                diff --git a/ui/forms/p-rows.php b/ui/forms/p-rows.php new file mode 100644 index 0000000000..253f2a8906 --- /dev/null +++ b/ui/forms/p-rows.php @@ -0,0 +1,57 @@ +field( [ 'name' => $field['name'], 'in_form' => true ] ); + } + + $row_classes = $field_row_classes . ' pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ); + $row_classes = trim( $row_classes ); + + if ( ! empty( $pre_callback ) && is_callable( $pre_callback ) ) { + $pre_callback( $field['name'], $id, $field, $pod ); + } + + pods_view( PODS_DIR . 'ui/forms/p-row.php', compact( array_keys( get_defined_vars() ) ) ); + + if ( ! empty( $post_callback ) && is_callable( $post_callback ) ) { + $post_callback( $field['name'], $id, $field, $pod ); + } +} diff --git a/ui/forms/table-row.php b/ui/forms/table-row.php new file mode 100644 index 0000000000..77615622bd --- /dev/null +++ b/ui/forms/table-row.php @@ -0,0 +1,43 @@ + + + + + + < + class="pods-form-ui-heading pods-form-ui-heading-"> + + > + + + + + + + + + scope="" + > + + + +
                + +
                + + + diff --git a/ui/forms/table-rows.php b/ui/forms/table-rows.php new file mode 100644 index 0000000000..6e232f1fbc --- /dev/null +++ b/ui/forms/table-rows.php @@ -0,0 +1,59 @@ +field( [ 'name' => $field['name'], 'in_form' => true ] ); + } + + $row_classes = $field_row_classes . ' pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ); + $row_classes = trim( $row_classes ); + + if ( ! empty( $pre_callback ) && is_callable( $pre_callback ) ) { + $pre_callback( $field['name'], $id, $field, $pod ); + } + + pods_view( PODS_DIR . 'ui/forms/table-row.php', compact( array_keys( get_defined_vars() ) ) ); + + if ( ! empty( $post_callback ) && is_callable( $post_callback ) ) { + $post_callback( $field['name'], $id, $field, $pod ); + } +} diff --git a/ui/forms/type/post.php b/ui/forms/type/post.php new file mode 100644 index 0000000000..d5f737c751 --- /dev/null +++ b/ui/forms/type/post.php @@ -0,0 +1,476 @@ + +
                +
                + +
                + +
                + + +
                +
                + id() && ( isset( $pod->pod_data['fields']['created'] ) || isset( $pod->pod_data['fields']['modified'] ) || 0 < strlen( pods_v_sanitized( 'detail_url', $pod_options ) ) ) ) { + ?> +
                + +
                + +
                +
                + pod_data['fields']['created'] ) || isset( $pod->pod_data['fields']['modified'] ) ) { + ?> +
                + pod_data['fields']['created'] ) ) { + $date = date_i18n( $datef, strtotime( $pod->field( 'created' ) ) ); + ?> +
                + : +
                + pod_data['fields']['modified'] ) && $pod->display( 'created' ) != $pod->display( 'modified' ) ) { + $date = date_i18n( $datef, strtotime( $pod->field( 'modified' ) ) ); + ?> +
                + : +
                + + + +
                + +
                + + + +
                + pod, + ) + ) && null !== $pod->id() && ! $duplicate && ! in_array( 'delete', (array) $obj->actions_disabled, true ) && ! in_array( 'delete', (array) $obj->actions_hidden, true ) ) { + $link = pods_query_arg( + array( + 'action' => 'delete', + '_wpnonce' => wp_create_nonce( 'pods-ui-action-delete' ), + ) + ); + ?> +
                + +
                + + + +
                + + + +
                + + +
                +
                + + + +
                + +
                + +
                + + actions_disabled, true ) && ! in_array( 'navigate', (array) $obj->actions_hidden, true ) ) { + if ( ! isset( $singular_label ) ) { + $singular_label = ucwords( str_replace( '_', ' ', $pod->pod_data['name'] ) ); + } + + $singular_label = pods_v( 'label', $pod_options, $singular_label, null, true ); + $singular_label = pods_v( 'label_singular', $pod_options, $singular_label, null, true ); + + $pod->params = $obj->get_params( null, 'manage' ); + + $prev_next = apply_filters( 'pods_ui_prev_next_ids', array(), $pod, $obj ); + + if ( empty( $prev_next ) ) { + $prev_next = array( + 'prev' => $pod->prev_id(), + 'next' => $pod->next_id(), + ); + } + + $prev = $prev_next['prev']; + $next = $prev_next['next']; + + if ( 0 < $prev || 0 < $next ) { + ?> + + +
                + + +
                + + +
                +
                + pod_data['field_index'] != $pod->pod_data['field_id'] ) { + foreach ( $group_fields as $field ) { + if ( $pod->pod_data['field_index'] != $field['name'] || 'text' !== $field['type'] ) { + continue; + } + + $more = true; + $extra = ''; + + $max_length = (int) pods_v_sanitized( 'maxlength', $field['options'], pods_v_sanitized( $field['type'] . '_max_length', $field['options'], 0 ), null, true ); + + if ( 0 < $max_length ) { + $extra .= ' maxlength="' . esc_attr( $max_length ) . '"'; + } + + /** + * Filter that lets you make the title field readonly + * + * @param Pods $pod Current Pods object. + * @param PodsUI $obj Current PodsUI object. + * + * @since 2.5.0 + */ + if ( pods_v( 'readonly', $field['options'], pods_v( 'readonly', $field, false ) ) || apply_filters( 'pods_ui_form_title_readonly', false, $pod, $obj ) ) { + ?> +
                +
                +

                index() ); ?>

                + /> +
                + +
                + + +
                + +
                + + /> + +
                + + +
                +
                +
                + +
                + +
                + + pod_data['field_index'] ] ) ) { + $groups = array(); + } + } + + if ( 0 < count( $groups ) ) { + ?> +
                + pod_data['type'], $pod->pod ); + ?> +
                + + +
                + + + id(); + + foreach ( $group['fields'] as $field ) { + if ( ! isset( $group_fields[ $field['name'] ] ) ) { + continue; + } + + $fields[ $field['name'] ] = $field; + } + + pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) ); + ?> +
                + +
                + +
                + + +
                + + + + + + + +
                + + +
                +
                + + +
                +
                + diff --git a/ui/forms/type/settings.php b/ui/forms/type/settings.php new file mode 100644 index 0000000000..52c5ee2ae2 --- /dev/null +++ b/ui/forms/type/settings.php @@ -0,0 +1,58 @@ + +
                + +

                + + + + id(); + + pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) ); + ?> +
                +
                + + +

                + + +

                diff --git a/ui/front/form.php b/ui/front/form.php index 6a383d6c04..1d019ea3f5 100644 --- a/ui/front/form.php +++ b/ui/front/form.php @@ -1,40 +1,48 @@ $field ) { +$pod_name = $pod->pod; +$id = $pod->id(); +// Set up fields. +foreach ( $fields as $k => $field ) { // Make sure all required array keys exist. - $field = wp_parse_args( $field, array( - 'name' => '', - 'type' => '', - 'label' => '', - 'help' => '', - 'options' => array(), - ) ); - $fields[ $k ] = $field; - - if ( in_array( $field[ 'name' ], array( 'created', 'modified' ), true ) ) { - unset( $fields[ $k ] ); + if ( ! $field instanceof \Pods\Whatsit\Field ) { + $field = wp_parse_args( $field, [ + 'name' => '', + 'type' => '', + 'label' => '', + 'help' => '', + ] ); + + $fields[ $k ] = $field; } - elseif ( false === PodsForm::permission( $field[ 'type' ], $field[ 'name' ], $field[ 'options' ], $fields, $pod, $pod->id() ) ) { - if ( pods_var( 'hidden', $field[ 'options' ], false ) ) { - $fields[ $k ][ 'type' ] = 'hidden'; - } - elseif ( pods_var( 'read_only', $field[ 'options' ], false ) ) { - $fields[ $k ][ 'readonly' ] = true; - } - else { + + if ( in_array( $field['name'], [ 'created', 'modified' ], true ) ) { + unset( $fields[ $k ] ); + } elseif ( ! pods_permission( $field ) ) { + if ( pods_v( 'hidden', $field, false ) ) { + $fields[ $k ]['type'] = 'hidden'; + } elseif ( pods_v( 'read_only', $field, false ) ) { + $fields[ $k ]['readonly'] = true; + } else { unset( $fields[ $k ] ); } - } - elseif ( !pods_has_permissions( $field[ 'options' ] ) ) { - if ( pods_var( 'hidden', $field[ 'options' ], false ) ) { - $fields[ $k ][ 'type' ] = 'hidden'; - } - elseif ( pods_var( 'read_only', $field[ 'options' ], false ) ) { - $fields[ $k ][ 'readonly' ] = true; + } elseif ( ! pods_has_permissions( $field ) ) { + if ( pods_v( 'hidden', $field, false ) ) { + $fields[ $k ]['type'] = 'hidden'; + } elseif ( pods_v( 'read_only', $field, false ) ) { + $fields[ $k ]['readonly'] = true; } } } @@ -42,12 +50,14 @@ $submittable_fields = $fields; foreach ( $submittable_fields as $k => $field ) { - if ( pods_var( 'readonly', $field, false ) ) { - unset( $submittable_fields[ $k ] ); + if ( ! pods_v( 'readonly', $field, false ) ) { + continue; } + + unset( $submittable_fields[ $k ] ); } -$uri_hash = wp_create_nonce( 'pods_uri_' . $_SERVER[ 'REQUEST_URI' ] ); +$uri_hash = wp_create_nonce( 'pods_uri_' . $_SERVER['REQUEST_URI'] ); $field_hash = wp_create_nonce( 'pods_fields_' . implode( ',', array_keys( $submittable_fields ) ) ); $uid = pods_session_id(); @@ -56,163 +66,135 @@ $uid = 'user_' . get_current_user_id(); } -$nonce = wp_create_nonce( 'pods_form_' . $pod->pod . '_' . $uid . '_' . $pod->id() . '_' . $uri_hash . '_' . $field_hash ); +$nonce = wp_create_nonce( 'pods_form_' . $pod_name . '_' . $uid . '_' . $id . '_' . $uri_hash . '_' . $field_hash ); -if ( isset( $_POST[ '_pods_nonce' ] ) ) { - try { - $id = $pod->api->process_form( $_POST, $pod, $submittable_fields, $thank_you ); - } - catch ( Exception $e ) { - echo '
                ' . $e->getMessage() . '
                '; - } +if ( isset( $_POST['_pods_nonce'] ) ) { + try { + $id = $pod->api->process_form( $_POST, $pod, $submittable_fields, $thank_you ); + } catch ( Exception $e ) { + echo '
                ' . $e->getMessage() . '
                '; + } } $field_prefix = ''; - -if ( !$fields_only ) { - $field_prefix = 'pods_field_'; ?> -
                -
                - - - id() ? 'save' : 'create' ), 'hidden' ); ?> - - pod, 'hidden' ); ?> - id(), 'hidden' ); ?> - - - - + + + +
                + + + + + + + + + + + + '; + $template_after = ''; + } -
                  - -
                • > -
                  - -
                  - -
                  - field( array( 'name' => $field[ 'name' ], 'in_form' => true ) ), $field[ 'type' ], $field, $pod, $pod->id() ); ?> - - -
                  -
                • - -
                + echo $template_before; - field( array( 'name' => $field[ 'name' ], 'in_form' => true ) ), 'hidden', $field, $pod, $pod->id() ); - } + echo $template_after; - /** - * Runs after all fields are outputted. - * - * @params array $fields Fields of the form - * @params object $pod The current Pod object - * @params array $params The form's parameters. - * - * @since 2.3.19 - */ - do_action( 'pods_form_after_fields', $fields, $pod, $params ); - ?> + /** + * Runs after all fields are outputted. + * + * @params array $fields Fields of the form + * @params object $pod The current Pod object + * @params array $params The form's parameters. + * + * @since 2.3.19 + */ + do_action( 'pods_form_after_fields', $fields, $pod, $params ); + ?> - -

                - - + +

                + <?php esc_attr_e( 'Submitting...', 'pods' ); ?> + - -

                -
                + +

                +
                - - + diff --git a/ui/front/pagination/advanced.php b/ui/front/pagination/advanced.php index 258db35ef0..6f8ebdc9b2 100644 --- a/ui/front/pagination/advanced.php +++ b/ui/front/pagination/advanced.php @@ -7,13 +7,13 @@ if ( 1 < $params->page ) { ?> first_last ) { ?> - first_text; ?> + first_text; ?> prev_next ) { ?> - prev_text; ?> + prev_text; ?> - 1 + 1 page < $params->total ) { ?> - total; ?> + total; ?> prev_next ) { ?> - next_text; ?> + next_text; ?> first_last ) { ?> - last_text; ?> + last_text; ?> -
              4. +
              5. @@ -39,4 +39,4 @@ }//end foreach ?>
          -
          \ No newline at end of file +
          diff --git a/ui/images/pods-form-placeholder.svg b/ui/images/pods-form-placeholder.svg new file mode 100644 index 0000000000..83eb02ddab --- /dev/null +++ b/ui/images/pods-form-placeholder.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/images/pods-logo-green.svg b/ui/images/pods-logo-green.svg new file mode 100644 index 0000000000..3ccf66e1c9 --- /dev/null +++ b/ui/images/pods-logo-green.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ui/images/pods-view-placeholder.svg b/ui/images/pods-view-placeholder.svg new file mode 100644 index 0000000000..1d7f745ca0 --- /dev/null +++ b/ui/images/pods-view-placeholder.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/js/blocks/block-types/README.md b/ui/js/blocks/block-types/README.md new file mode 100644 index 0000000000..ee018f1906 --- /dev/null +++ b/ui/js/blocks/block-types/README.md @@ -0,0 +1,7 @@ +# Pods Block Types + +All the block types are defined here for `block.json` configurations only. They are dynamically built through Pods in these places: + +* `ui/js/blocks/src/blocks/index.js` - This is where the blocks get registered dynamically with WordPress via the JS `registerBlockType()`. +* `src/Pods/Blocks` - This is the place where all the Blocks-related functionality is located. +* Additional custom blocks can be registered through the Pods Blocks PHP API which will be dynamically generated but will not have their own `block.json` file. diff --git a/ui/js/blocks/block-types/pods-block-field/block.json b/ui/js/blocks/block-types/pods-block-field/block.json new file mode 100644 index 0000000000..ca25ecde61 --- /dev/null +++ b/ui/js/blocks/block-types/pods-block-field/block.json @@ -0,0 +1,65 @@ +{ + "apiVersion": "1", + "name": "pods/pods-block-field", + "title": "Pods Field Value", + "description": "Display a single Pod item's field value (custom fields).", + "category": "pods", + "icon": "pods", + "keywords": [ + "pods", + "field", + "value", + "custom", + "meta" + ], + "editorScript": "file:../../pods-blocks-api.min.js", + "editorStyle": "file:../../../../styles/dist/pods.css", + "supports": { + "html": false, + "align": true, + "alignWide": true, + "anchor": true, + "customClassName": true, + "inserter": true, + "multiple": true, + "reusable": true, + "__experimentalColor": true, + "__experimentalFontSize": true, + "__experimentalPadding": true, + "__experimentalLineHeight": true, + "jsx": false + }, + "attributes": { + "align": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "string" + }, + "name": { + "type": "object", + "default": { + "label": "- Use Current Pod -", + "value": "" + } + }, + "slug": { + "type": "string" + }, + "field": { + "type": "string" + } + } +} diff --git a/ui/js/blocks/block-types/pods-block-form/block.json b/ui/js/blocks/block-types/pods-block-form/block.json new file mode 100644 index 0000000000..bff54ea647 --- /dev/null +++ b/ui/js/blocks/block-types/pods-block-form/block.json @@ -0,0 +1,76 @@ +{ + "apiVersion": "1", + "name": "pods/pods-block-form", + "title": "Pods Form", + "description": "Display a form for creating and editing Pod items.", + "category": "pods", + "icon": "pods", + "keywords": [ + "pods", + "form", + "input" + ], + "editorScript": "file:../../pods-blocks-api.min.js", + "editorStyle": "file:../../../../styles/dist/pods.css", + "supports": { + "html": false, + "align": true, + "alignWide": true, + "anchor": true, + "customClassName": true, + "inserter": true, + "multiple": true, + "reusable": true, + "__experimentalColor": true, + "__experimentalFontSize": true, + "__experimentalPadding": true, + "__experimentalLineHeight": true, + "jsx": false + }, + "attributes": { + "align": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "string" + }, + "name": { + "type": "object", + "default": { + "label": "- Use Current Pod -", + "value": "" + } + }, + "slug": { + "type": "string" + }, + "fields": { + "type": "string" + }, + "label": { + "type": "string" + }, + "thank_you": { + "type": "string" + }, + "form_output_type": { + "type": "object", + "default": { + "label": "Div containers (
          )", + "value": "div" + } + } + } +} diff --git a/ui/js/blocks/block-types/pods-block-list/block.json b/ui/js/blocks/block-types/pods-block-list/block.json new file mode 100644 index 0000000000..7ee348cdc3 --- /dev/null +++ b/ui/js/blocks/block-types/pods-block-list/block.json @@ -0,0 +1,128 @@ +{ + "apiVersion": "1", + "name": "pods/pods-block-list", + "title": "Pods Item List", + "description": "List multiple Pod items.", + "category": "pods", + "icon": "pods", + "keywords": [ + "pods", + "item", + "list" + ], + "editorScript": "file:../../pods-blocks-api.min.js", + "editorStyle": "file:../../../../styles/dist/pods.css", + "supports": { + "html": false, + "align": true, + "alignWide": true, + "anchor": true, + "customClassName": true, + "inserter": true, + "multiple": true, + "reusable": true, + "__experimentalColor": true, + "__experimentalFontSize": true, + "__experimentalPadding": true, + "__experimentalLineHeight": true, + "jsx": false + }, + "attributes": { + "align": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "string" + }, + "name": { + "type": "object", + "default": { + "label": "- Use Current Pod -", + "value": "" + } + }, + "template": { + "type": "object", + "default": { + "label": "- Use Custom Template -", + "value": "" + } + }, + "template_custom": { + "type": "string" + }, + "content_before": { + "type": "string" + }, + "content_after": { + "type": "string" + }, + "not_found": { + "type": "string" + }, + "limit": { + "type": "number", + "default": 15 + }, + "orderby": { + "type": "string" + }, + "where": { + "type": "string" + }, + "pagination": { + "type": "boolean", + "default": false + }, + "pagination_location": { + "type": "object", + "default": { + "label": "After list", + "value": "after" + } + }, + "pagination_type": { + "type": "object", + "default": { + "label": "Basic links", + "value": "advanced" + } + }, + "filters": { + "type": "string" + }, + "filters_label": { + "type": "string" + }, + "filters_location": { + "type": "object", + "default": { + "label": "Before list", + "value": "before" + } + }, + "expires": { + "type": "number", + "default": 300 + }, + "cache_mode": { + "type": "object", + "default": { + "label": "Disable Caching", + "value": "none" + } + } + } +} diff --git a/ui/js/blocks/block-types/pods-block-single/block.json b/ui/js/blocks/block-types/pods-block-single/block.json new file mode 100644 index 0000000000..92ef4acabc --- /dev/null +++ b/ui/js/blocks/block-types/pods-block-single/block.json @@ -0,0 +1,71 @@ +{ + "apiVersion": "1", + "name": "pods/pods-block-single", + "title": "Pods Single Item", + "description": "Display a single Pod item.", + "category": "pods", + "icon": "pods", + "keywords": [ + "pods", + "single", + "item", + "field" + ], + "editorScript": "file:../../pods-blocks-api.min.js", + "editorStyle": "file:../../../../styles/dist/pods.css", + "supports": { + "html": false, + "align": true, + "alignWide": true, + "anchor": true, + "customClassName": true, + "inserter": true, + "multiple": true, + "reusable": true, + "__experimentalColor": true, + "__experimentalFontSize": true, + "__experimentalPadding": true, + "__experimentalLineHeight": true, + "jsx": false + }, + "attributes": { + "align": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "string" + }, + "name": { + "type": "object", + "default": { + "label": "- Use Current Pod -", + "value": "" + } + }, + "slug": { + "type": "string" + }, + "template": { + "type": "object", + "default": { + "label": "- Use Custom Template -", + "value": "" + } + }, + "template_custom": { + "type": "string" + } + } +} diff --git a/ui/js/blocks/block-types/pods-block-view/block.json b/ui/js/blocks/block-types/pods-block-view/block.json new file mode 100644 index 0000000000..b1203387a8 --- /dev/null +++ b/ui/js/blocks/block-types/pods-block-view/block.json @@ -0,0 +1,64 @@ +{ + "apiVersion": "1", + "name": "pods/pods-block-view", + "title": "Pods View", + "description": "Include a file from a theme, with caching options", + "category": "pods", + "icon": "pods", + "keywords": [ + "pods", + "view", + "include" + ], + "editorScript": "file:../../pods-blocks-api.min.js", + "editorStyle": "file:../../../../styles/dist/pods.css", + "supports": { + "html": false, + "align": true, + "alignWide": true, + "anchor": true, + "customClassName": true, + "inserter": true, + "multiple": true, + "reusable": true, + "__experimentalColor": true, + "__experimentalFontSize": true, + "__experimentalPadding": true, + "__experimentalLineHeight": true, + "jsx": false + }, + "attributes": { + "align": { + "type": "string" + }, + "anchor": { + "type": "string" + }, + "textColor": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "fontSize": { + "type": "string" + }, + "style": { + "type": "string" + }, + "view": { + "type": "string" + }, + "expires": { + "type": "number", + "default": 300 + }, + "cache_mode": { + "type": "object", + "default": { + "label": "Disable Caching", + "value": "none" + } + } + } +} diff --git a/ui/js/blocks/pods-blocks-api.min.asset.json b/ui/js/blocks/pods-blocks-api.min.asset.json new file mode 100644 index 0000000000..0efaa066b3 --- /dev/null +++ b/ui/js/blocks/pods-blocks-api.min.asset.json @@ -0,0 +1 @@ +{"dependencies":["wp-api-fetch","wp-autop","wp-block-editor","wp-blocks","wp-components","wp-compose","wp-date","wp-element","wp-i18n","wp-keycodes","wp-server-side-render","wp-url"],"version":"1ae572d3f990891697f42359d4789570"} \ No newline at end of file diff --git a/ui/js/blocks/pods-blocks-api.min.js b/ui/js/blocks/pods-blocks-api.min.js new file mode 100644 index 0000000000..b4704679ce --- /dev/null +++ b/ui/js/blocks/pods-blocks-api.min.js @@ -0,0 +1 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=241)}([function(e,t){e.exports=React},function(e,t,n){e.exports=n(58)()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t,n){"use strict";n.d(t,"a",(function(){return p})),n.d(t,"b",(function(){return u})),n.d(t,"c",(function(){return a})),n.d(t,"d",(function(){return c}));var r=n(0),o=(n(38),n(10)),i=(n(50),n(27),n(39),n(23)),s=n(25),a=(n(33),function(e,t){var n=arguments;if(null==t||!o.e.call(t,"css"))return r.createElement.apply(void 0,n);var i=n.length,s=new Array(i);s[0]=o.b,s[1]=Object(o.d)(e,t);for(var a=2;a-1}function A(e){return k(e)?window.pageYOffset:e.scrollTop}function E(e,t){k(e)?window.scrollTo(0,t):e.scrollTop=t}function M(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function N(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:200,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:w,o=A(e),i=t-o,s=10,a=0;function u(){var t=M(a+=s,o,i,n);E(e,t),an.bottom?E(e,Math.min(t.offsetTop+t.clientHeight-e.offsetHeight+o,e.scrollHeight)):r.top-o=h)return{placement:"bottom",maxHeight:t};if(x>=h&&!s)return i&&N(u,S,160),{placement:"bottom",maxHeight:t};if(!s&&x>=r||s&&w>=r)return i&&N(u,S,160),{placement:"bottom",maxHeight:s?w-v:x-v};if("auto"===o||s){var j=t,k=s?_:O;return k>=r&&(j=Math.min(k-v-a.controlHeight,t)),{placement:"top",maxHeight:j}}if("bottom"===o)return i&&E(u,S),{placement:"bottom",maxHeight:t};break;case"top":if(_>=h)return{placement:"top",maxHeight:t};if(O>=h&&!s)return i&&N(u,C,160),{placement:"top",maxHeight:t};if(!s&&O>=r||s&&_>=r){var M=t;return(!s&&O>=r||s&&_>=r)&&(M=s?_-y:O-y),i&&N(u,C,160),{placement:"top",maxHeight:M}}return{placement:"bottom",maxHeight:t};default:throw new Error('Invalid placement provided "'.concat(o,'".'))}return c}var U=function(e){return"auto"===e?"bottom":e},F=function(e){var t,n=e.placement,r=e.theme,o=r.borderRadius,i=r.spacing,s=r.colors;return t={label:"menu"},Object(p.a)(t,function(e){return e?{bottom:"top",top:"bottom"}[e]:"bottom"}(n),"100%"),Object(p.a)(t,"backgroundColor",s.neutral0),Object(p.a)(t,"borderRadius",o),Object(p.a)(t,"boxShadow","0 0 0 1px hsla(0, 0%, 0%, 0.1), 0 4px 11px hsla(0, 0%, 0%, 0.1)"),Object(p.a)(t,"marginBottom",i.menuGutter),Object(p.a)(t,"marginTop",i.menuGutter),Object(p.a)(t,"position","absolute"),Object(p.a)(t,"width","100%"),Object(p.a)(t,"zIndex",1),t},q=Object(h.createContext)({getPortalPlacement:null}),H=function(e){Object(f.a)(n,e);var t=_(n);function n(){var e;Object(c.a)(this,n);for(var r=arguments.length,o=new Array(r),i=0;i0?d(C,--x):0,w--,10===S&&(w=1,_--),S}function E(){return S=x2||P(S)>3?"":" "}function V(e,t){for(;--t&&E()&&!(S<48||S>102||S>57&&S<65||S>70&&S<97););return T(e,N()+(t<6&&32==M()&&32==E()))}function B(e,t){for(;E()&&e+S!==57&&(e+S!==84||47!==M()););return"/*"+T(t,x-1)+"*"+l(47===e?e:E())}function U(e){for(;!P(M());)E();return T(e,x)}function F(e){return R(function e(t,n,r,o,i,s,a,u,c){var f=0,h=0,d=a,m=0,b=0,y=0,_=1,w=1,O=1,x=0,S="",C=i,j=s,k=o,T=S;for(;w;)switch(y=x,x=E()){case 34:case 39:case 91:case 40:T+=I(x);break;case 9:case 10:case 13:case 32:T+=D(y);break;case 92:T+=V(N()-1,7);continue;case 47:switch(M()){case 42:case 47:v(H(B(E(),N()),n,r),c);break;default:T+="/"}break;case 123*_:u[f++]=g(T)*O;case 125*_:case 59:case 0:switch(x){case 0:case 125:w=0;case 59+h:b>0&&g(T)-d&&v(b>32?z(T+";",o,r,d-1):z(p(T," ","")+";",o,r,d-2),c);break;case 59:T+=";";default:if(v(k=q(T,n,r,f,h,i,u,S,C=[],j=[],d),s),123===x)if(0===h)e(T,n,k,k,C,s,d,u,j);else switch(m){case 100:case 109:case 115:e(t,k,k,o&&v(q(t,k,k,0,0,i,u,S,i,C=[],d),j),i,j,d,u,o?C:j);break;default:e(T,k,k,k,[""],j,d,u,j)}}f=h=b=0,_=O=1,S=T="",d=a;break;case 58:d=1+g(T),b=y;default:if(_<1)if(123==x)--_;else if(125==x&&0==_++&&125==A())continue;switch(T+=l(x),x*_){case 38:O=h>0?1:(T+="\f",-1);break;case 44:u[f++]=(g(T)-1)*O,O=1;break;case 64:45===M()&&(T+=I(E())),m=M(),h=g(S=T+=U(N())),x++;break;case 45:45===y&&2==g(T)&&(_=0)}}return s}("",null,null,null,[""],e=L(e),0,[0],e))}function q(e,t,n,r,o,i,s,u,l,h,d){for(var g=o-1,v=0===o?i:[""],y=b(v),_=0,w=0,O=0;_0?v[x]+" "+S:p(S,/&\f/g,v[x])))&&(l[O++]=C);return j(e,t,n,0===o?a:u,l,h,d)}function H(e,t,n){return j(e,t,n,s,l(S),m(e,2,-2),0)}function z(e,t,n,r){return j(e,t,n,u,m(e,0,r),m(e,r+1,-1),r)}function G(e,t){switch(function(e,t){return(((t<<2^d(e,0))<<2^d(e,1))<<2^d(e,2))<<2^d(e,3)}(e,t)){case 5103:return i+"print-"+e+e;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 6391:case 5879:case 5623:case 6135:case 4599:case 4855:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:return i+e+e;case 5349:case 4246:case 4810:case 6968:case 2756:return i+e+o+e+r+e+e;case 6828:case 4268:return i+e+r+e+e;case 6165:return i+e+r+"flex-"+e+e;case 5187:return i+e+p(e,/(\w+).+(:[^]+)/,i+"box-$1$2"+r+"flex-$1$2")+e;case 5443:return i+e+r+"flex-item-"+p(e,/flex-|-self/,"")+e;case 4675:return i+e+r+"flex-line-pack"+p(e,/align-content|flex-|-self/,"")+e;case 5548:return i+e+r+p(e,"shrink","negative")+e;case 5292:return i+e+r+p(e,"basis","preferred-size")+e;case 6060:return i+"box-"+p(e,"-grow","")+i+e+r+p(e,"grow","positive")+e;case 4554:return i+p(e,/([^-])(transform)/g,"$1"+i+"$2")+e;case 6187:return p(p(p(e,/(zoom-|grab)/,i+"$1"),/(image-set)/,i+"$1"),e,"")+e;case 5495:case 3959:return p(e,/(image-set\([^]*)/,i+"$1$`$1");case 4968:return p(p(e,/(.+:)(flex-)?(.*)/,i+"box-pack:$3"+r+"flex-pack:$3"),/s.+-b[^;]+/,"justify")+i+e+e;case 4095:case 3583:case 4068:case 2532:return p(e,/(.+)-inline(.+)/,i+"$1$2")+e;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if(g(e)-1-t>6)switch(d(e,t+1)){case 109:if(45!==d(e,t+4))break;case 102:return p(e,/(.+:)(.+)-([^]+)/,"$1"+i+"$2-$3$1"+o+(108==d(e,t+3)?"$3":"$2-$3"))+e;case 115:return~h(e,"stretch")?G(p(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==d(e,t+1))break;case 6444:switch(d(e,g(e)-3-(~h(e,"!important")&&10))){case 107:return p(e,":",":"+i)+e;case 101:return p(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+i+(45===d(e,14)?"inline-":"")+"box$3$1"+i+"$2$3$1"+r+"$2box$3")+e}break;case 5936:switch(d(e,t+11)){case 114:return i+e+r+p(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return i+e+r+p(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return i+e+r+p(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return i+e+r+e+e}return e}function $(e,t){for(var n="",r=b(e),o=0;o=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";function r(e,t){for(var n=0;n=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,s=!0,a=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return s=e.done,e},e:function(e){a=!0,i=e},f:function(){try{s||null==n.return||n.return()}finally{if(a)throw i}}}}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0?s-4:s;for(n=0;n>16&255,u[l++]=t>>8&255,u[l++]=255&t;return 2===a&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,u[l++]=255&t),1===a&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,u[l++]=t>>8&255,u[l++]=255&t),u},n.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],s=0,a=n-o;sa?a:s+16383));return 1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"=")),i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,u=s.length;a0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,s=[],a=t;a>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return s.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},{}],2:[function(e,t,n){},{}],3:[function(e,t,n){(function(t){var r=e("base64-js"),o=e("ieee754");function i(e){if(e>2147483647)throw new RangeError('The value "'+e+'" is invalid for option "size"');var n=new Uint8Array(e);return n.__proto__=t.prototype,n}function t(e,t,n){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return u(e)}return s(e,t,n)}function s(e,n,r){if("string"==typeof e)return function(e,n){if("string"==typeof n&&""!==n||(n="utf8"),!t.isEncoding(n))throw new TypeError("Unknown encoding: "+n);var r=0|p(e,n),o=i(r),s=o.write(e,n);return s!==r&&(o=o.slice(0,s)),o}(e,n);if(ArrayBuffer.isView(e))return l(e);if(null==e)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+c(e));if(V(e,ArrayBuffer)||e&&V(e.buffer,ArrayBuffer))return function(e,n,r){if(n<0||e.byteLength=2147483647)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+2147483647..toString(16)+" bytes");return 0|e}function p(e,n){if(t.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||V(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+c(e));var r=e.length,o=arguments.length>2&&!0===arguments[2];if(!o&&0===r)return 0;for(var i=!1;;)switch(n){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return R(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return I(e).length;default:if(i)return o?-1:R(e).length;n=(""+n).toLowerCase(),i=!0}}function h(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return k(this,t,n);case"utf8":case"utf-8":return S(this,t,n);case"ascii":return C(this,t,n);case"latin1":case"binary":return j(this,t,n);case"base64":return x(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return A(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function d(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function m(e,n,r,o,i){if(0===e.length)return-1;if("string"==typeof r?(o=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),B(r=+r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof n&&(n=t.from(n,o)),t.isBuffer(n))return 0===n.length?-1:g(e,n,r,o,i);if("number"==typeof n)return n&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,n,r):Uint8Array.prototype.lastIndexOf.call(e,n,r):g(e,[n],r,o,i);throw new TypeError("val must be string, number or Buffer")}function g(e,t,n,r,o){var i,s=1,a=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;s=2,a/=2,u/=2,n/=2}function c(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(o){var l=-1;for(i=n;ia&&(n=a-u),i=n;i>=0;i--){for(var f=!0,p=0;po&&(r=o):r=o;var i=t.length;r>i/2&&(r=i/2);for(var s=0;s>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function x(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function S(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],s=e[o+2],128==(192&i)&&128==(192&s)&&(u=(15&c)<<12|(63&i)<<6|63&s)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],s=e[o+2],a=e[o+3],128==(192&i)&&128==(192&s)&&128==(192&a)&&(u=(15&c)<<18|(63&i)<<12|(63&s)<<6|63&a)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=4096)return String.fromCharCode.apply(String,e);for(var n="",r=0;ro)&&(n=o);for(var i="",s=t;sn)throw new RangeError("Trying to access beyond buffer length")}function M(e,n,r,o,i,s){if(!t.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(n>i||ne.length)throw new RangeError("Index out of range")}function N(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function T(e,t,n,r,i){return t=+t,n>>>=0,i||N(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function P(e,t,n,r,i){return t=+t,n>>>=0,i||N(e,0,n,8),o.write(e,t,n,r,52,8),n+8}n.Buffer=t,n.SlowBuffer=function(e){return+e!=e&&(e=0),t.alloc(+e)},n.INSPECT_MAX_BYTES=50,n.kMaxLength=2147483647,t.TYPED_ARRAY_SUPPORT=function(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()}catch(e){return!1}}(),t.TYPED_ARRAY_SUPPORT||"undefined"==typeof console||"function"!=typeof console.error||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(t.prototype,"parent",{enumerable:!0,get:function(){if(t.isBuffer(this))return this.buffer}}),Object.defineProperty(t.prototype,"offset",{enumerable:!0,get:function(){if(t.isBuffer(this))return this.byteOffset}}),"undefined"!=typeof Symbol&&null!=Symbol.species&&t[Symbol.species]===t&&Object.defineProperty(t,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),t.poolSize=8192,t.from=function(e,t,n){return s(e,t,n)},t.prototype.__proto__=Uint8Array.prototype,t.__proto__=Uint8Array,t.alloc=function(e,t,n){return function(e,t,n){return a(e),e<=0?i(e):void 0!==t?"string"==typeof n?i(e).fill(t,n):i(e).fill(t):i(e)}(e,t,n)},t.allocUnsafe=function(e){return u(e)},t.allocUnsafeSlow=function(e){return u(e)},t.isBuffer=function(e){return null!=e&&!0===e._isBuffer&&e!==t.prototype},t.compare=function(e,n){if(V(e,Uint8Array)&&(e=t.from(e,e.offset,e.byteLength)),V(n,Uint8Array)&&(n=t.from(n,n.offset,n.byteLength)),!t.isBuffer(e)||!t.isBuffer(n))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(e===n)return 0;for(var r=e.length,o=n.length,i=0,s=Math.min(r,o);it&&(e+=" ... "),""},t.prototype.compare=function(e,n,r,o,i){if(V(e,Uint8Array)&&(e=t.from(e,e.offset,e.byteLength)),!t.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+c(e));if(void 0===n&&(n=0),void 0===r&&(r=e?e.length:0),void 0===o&&(o=0),void 0===i&&(i=this.length),n<0||r>e.length||o<0||i>this.length)throw new RangeError("out of range index");if(o>=i&&n>=r)return 0;if(o>=i)return-1;if(n>=r)return 1;if(this===e)return 0;for(var s=(i>>>=0)-(o>>>=0),a=(r>>>=0)-(n>>>=0),u=Math.min(s,a),l=this.slice(o,i),f=e.slice(n,r),p=0;p>>=0,isFinite(n)?(n>>>=0,void 0===r&&(r="utf8")):(r=n,n=void 0)}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return v(this,e,t,n);case"ascii":return y(this,e,t,n);case"latin1":case"binary":return _(this,e,t,n);case"base64":return w(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},t.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}},t.prototype.slice=function(e,n){var r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(n=void 0===n?r:~~n)<0?(n+=r)<0&&(n=0):n>r&&(n=r),n>>=0,t>>>=0,n||E(e,t,this.length);for(var r=this[e],o=1,i=0;++i>>=0,t>>>=0,n||E(e,t,this.length);for(var r=this[e+--t],o=1;t>0&&(o*=256);)r+=this[e+--t]*o;return r},t.prototype.readUInt8=function(e,t){return e>>>=0,t||E(e,1,this.length),this[e]},t.prototype.readUInt16LE=function(e,t){return e>>>=0,t||E(e,2,this.length),this[e]|this[e+1]<<8},t.prototype.readUInt16BE=function(e,t){return e>>>=0,t||E(e,2,this.length),this[e]<<8|this[e+1]},t.prototype.readUInt32LE=function(e,t){return e>>>=0,t||E(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},t.prototype.readUInt32BE=function(e,t){return e>>>=0,t||E(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},t.prototype.readIntLE=function(e,t,n){e>>>=0,t>>>=0,n||E(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},t.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||E(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},t.prototype.readInt8=function(e,t){return e>>>=0,t||E(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},t.prototype.readInt16LE=function(e,t){e>>>=0,t||E(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},t.prototype.readInt16BE=function(e,t){e>>>=0,t||E(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},t.prototype.readInt32LE=function(e,t){return e>>>=0,t||E(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},t.prototype.readInt32BE=function(e,t){return e>>>=0,t||E(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},t.prototype.readFloatLE=function(e,t){return e>>>=0,t||E(e,4,this.length),o.read(this,e,!0,23,4)},t.prototype.readFloatBE=function(e,t){return e>>>=0,t||E(e,4,this.length),o.read(this,e,!1,23,4)},t.prototype.readDoubleLE=function(e,t){return e>>>=0,t||E(e,8,this.length),o.read(this,e,!0,52,8)},t.prototype.readDoubleBE=function(e,t){return e>>>=0,t||E(e,8,this.length),o.read(this,e,!1,52,8)},t.prototype.writeUIntLE=function(e,t,n,r){e=+e,t>>>=0,n>>>=0,r||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i>>=0,n>>>=0,r||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=n-1,i=1;for(this[t+o]=255&e;--o>=0&&(i*=256);)this[t+o]=e/i&255;return t+n},t.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,1,255,0),this[t]=255&e,t+1},t.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},t.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},t.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},t.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},t.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,s=1,a=0;for(this[t]=255&e;++i>0)-a&255;return t+n},t.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,s=1,a=0;for(this[t+i]=255&e;--i>=0&&(s*=256);)e<0&&0===a&&0!==this[t+i+1]&&(a=1),this[t+i]=(e/s>>0)-a&255;return t+n},t.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},t.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},t.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},t.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},t.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},t.prototype.writeFloatLE=function(e,t,n){return T(this,e,t,!0,n)},t.prototype.writeFloatBE=function(e,t,n){return T(this,e,t,!1,n)},t.prototype.writeDoubleLE=function(e,t,n){return P(this,e,t,!0,n)},t.prototype.writeDoubleBE=function(e,t,n){return P(this,e,t,!1,n)},t.prototype.copy=function(e,n,r,o){if(!t.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),o||0===o||(o=this.length),n>=e.length&&(n=e.length),n||(n=0),o>0&&o=this.length)throw new RangeError("Index out of range");if(o<0)throw new RangeError("sourceEnd out of bounds");o>this.length&&(o=this.length),e.length-n=0;--s)e[s+n]=this[s+r];else Uint8Array.prototype.set.call(e,this.subarray(r,o),n);return i},t.prototype.fill=function(e,n,r,o){if("string"==typeof e){if("string"==typeof n?(o=n,n=0,r=this.length):"string"==typeof r&&(o=r,r=this.length),void 0!==o&&"string"!=typeof o)throw new TypeError("encoding must be a string");if("string"==typeof o&&!t.isEncoding(o))throw new TypeError("Unknown encoding: "+o);if(1===e.length){var i=e.charCodeAt(0);("utf8"===o&&i<128||"latin1"===o)&&(e=i)}}else"number"==typeof e&&(e&=255);if(n<0||this.length>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(s=n;s55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(s+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function I(e){return r.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(L,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function D(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}function V(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function B(e){return e!=e}}).call(this,e("buffer").Buffer)},{"base64-js":1,buffer:3,ieee754:32}],4:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.attributeNames=n.elementNames=void 0,n.elementNames=new Map([["altglyph","altGlyph"],["altglyphdef","altGlyphDef"],["altglyphitem","altGlyphItem"],["animatecolor","animateColor"],["animatemotion","animateMotion"],["animatetransform","animateTransform"],["clippath","clipPath"],["feblend","feBlend"],["fecolormatrix","feColorMatrix"],["fecomponenttransfer","feComponentTransfer"],["fecomposite","feComposite"],["feconvolvematrix","feConvolveMatrix"],["fediffuselighting","feDiffuseLighting"],["fedisplacementmap","feDisplacementMap"],["fedistantlight","feDistantLight"],["fedropshadow","feDropShadow"],["feflood","feFlood"],["fefunca","feFuncA"],["fefuncb","feFuncB"],["fefuncg","feFuncG"],["fefuncr","feFuncR"],["fegaussianblur","feGaussianBlur"],["feimage","feImage"],["femerge","feMerge"],["femergenode","feMergeNode"],["femorphology","feMorphology"],["feoffset","feOffset"],["fepointlight","fePointLight"],["fespecularlighting","feSpecularLighting"],["fespotlight","feSpotLight"],["fetile","feTile"],["feturbulence","feTurbulence"],["foreignobject","foreignObject"],["glyphref","glyphRef"],["lineargradient","linearGradient"],["radialgradient","radialGradient"],["textpath","textPath"]]),n.attributeNames=new Map([["definitionurl","definitionURL"],["attributename","attributeName"],["attributetype","attributeType"],["basefrequency","baseFrequency"],["baseprofile","baseProfile"],["calcmode","calcMode"],["clippathunits","clipPathUnits"],["diffuseconstant","diffuseConstant"],["edgemode","edgeMode"],["filterunits","filterUnits"],["glyphref","glyphRef"],["gradienttransform","gradientTransform"],["gradientunits","gradientUnits"],["kernelmatrix","kernelMatrix"],["kernelunitlength","kernelUnitLength"],["keypoints","keyPoints"],["keysplines","keySplines"],["keytimes","keyTimes"],["lengthadjust","lengthAdjust"],["limitingconeangle","limitingConeAngle"],["markerheight","markerHeight"],["markerunits","markerUnits"],["markerwidth","markerWidth"],["maskcontentunits","maskContentUnits"],["maskunits","maskUnits"],["numoctaves","numOctaves"],["pathlength","pathLength"],["patterncontentunits","patternContentUnits"],["patterntransform","patternTransform"],["patternunits","patternUnits"],["pointsatx","pointsAtX"],["pointsaty","pointsAtY"],["pointsatz","pointsAtZ"],["preservealpha","preserveAlpha"],["preserveaspectratio","preserveAspectRatio"],["primitiveunits","primitiveUnits"],["refx","refX"],["refy","refY"],["repeatcount","repeatCount"],["repeatdur","repeatDur"],["requiredextensions","requiredExtensions"],["requiredfeatures","requiredFeatures"],["specularconstant","specularConstant"],["specularexponent","specularExponent"],["spreadmethod","spreadMethod"],["startoffset","startOffset"],["stddeviation","stdDeviation"],["stitchtiles","stitchTiles"],["surfacescale","surfaceScale"],["systemlanguage","systemLanguage"],["tablevalues","tableValues"],["targetx","targetX"],["targety","targetY"],["textlength","textLength"],["viewbox","viewBox"],["viewtarget","viewTarget"],["xchannelselector","xChannelSelector"],["ychannelselector","yChannelSelector"],["zoomandpan","zoomAndPan"]])},{}],5:[function(e,t,n){var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n";case a.Comment:return function(e){return"\x3c!--"+e.data+"--\x3e"}(e);case a.CDATA:return function(e){return""}(e);default:return a.isTag(e)?function(e,t){var n;"foreign"===t.xmlMode&&(e.name=null!==(n=c.elementNames.get(e.name))&&void 0!==n?n:e.name,e.parent&&d.has(e.parent.name)&&(t=r(r({},t),{xmlMode:!1}))),!t.xmlMode&&m.has(e.name)&&(t=r(r({},t),{xmlMode:"foreign"}));var o="<"+e.name,i=function(e,t){if(e)return Object.keys(e).map((function(n){var r,o,i=null!==(r=e[n])&&void 0!==r?r:"";return"foreign"===t.xmlMode&&(n=null!==(o=c.attributeNames.get(n))&&void 0!==o?o:n),t.emptyAttrs||t.xmlMode||""!==i?n+'="'+(t.decodeEntities?u.encodeXML(i):i.replace(/"/g,"""))+'"':n})).join(" ")}(e.attribs,t);return i&&(o+=" "+i),0===e.children.length&&(t.xmlMode?!1!==t.selfClosingTags:t.selfClosingTags&&f.has(e.name))?(t.xmlMode||(o+=" "),o+="/>"):(o+=">",e.children.length>0&&(o+=p(e.children,t)),!t.xmlMode&&f.has(e.name)||(o+="")),o}(e,t):function(e,t){var n=e.data||"";return!t.decodeEntities||e.parent&&l.has(e.parent.name)||(n=u.encodeXML(n)),n}(e,t)}}n.default=p;var d=new Set(["mi","mo","mn","ms","mtext","annotation-xml","foreignObject","desc","title"]),m=new Set(["svg","math"])},{"./foreignNames":4,domelementtype:6,entities:20}],6:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.Doctype=n.CDATA=n.Tag=n.Style=n.Script=n.Comment=n.Directive=n.Text=n.isTag=void 0,n.isTag=function(e){return"tag"===e.type||"script"===e.type||"style"===e.type},n.Text="text",n.Directive="directive",n.Comment="comment",n.Script="script",n.Style="style",n.Tag="tag",n.CDATA="cdata",n.Doctype="doctype"},{}],7:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});var r=e("./node");n.Node=r.Node,n.Element=r.Element,n.DataNode=r.DataNode,n.NodeWithChildren=r.NodeWithChildren;var o=/\s+/g,i={normalizeWhitespace:!1,withStartIndices:!1,withEndIndices:!1},s=function(){function e(e,t,n){this.dom=[],this._done=!1,this._tagStack=[],this._lastNode=null,this._parser=null,"function"==typeof t&&(n=t,t=i),"object"===c(e)&&(t=e,e=void 0),this._callback=e||null,this._options=t||i,this._elementCB=n||null}return e.prototype.onparserinit=function(e){this._parser=e},e.prototype.onreset=function(){this.dom=[],this._done=!1,this._tagStack=[],this._lastNode=null,this._parser=this._parser||null},e.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this.handleCallback(null))},e.prototype.onerror=function(e){this.handleCallback(e)},e.prototype.onclosetag=function(){this._lastNode=null;var e=this._tagStack.pop();e&&this._parser&&(this._options.withEndIndices&&(e.endIndex=this._parser.endIndex),this._elementCB&&this._elementCB(e))},e.prototype.onopentag=function(e,t){var n=new r.Element(e,t);this.addNode(n),this._tagStack.push(n)},e.prototype.ontext=function(e){var t=this._options.normalizeWhitespace,n=this._lastNode;if(n&&"text"===n.type)t?n.data=(n.data+e).replace(o," "):n.data+=e;else{t&&(e=e.replace(o," "));var i=new r.DataNode("text",e);this.addNode(i),this._lastNode=i}},e.prototype.oncomment=function(e){if(this._lastNode&&"comment"===this._lastNode.type)this._lastNode.data+=e;else{var t=new r.DataNode("comment",e);this.addNode(t),this._lastNode=t}},e.prototype.oncommentend=function(){this._lastNode=null},e.prototype.oncdatastart=function(){var e=new r.DataNode("text",""),t=new r.NodeWithChildren("cdata",[e]);this.addNode(t),e.parent=t,this._lastNode=e},e.prototype.oncdataend=function(){this._lastNode=null},e.prototype.onprocessinginstruction=function(e,t){var n=new r.ProcessingInstruction(e,t);this.addNode(n)},e.prototype.handleCallback=function(e){if("function"==typeof this._callback)this._callback(e,this.dom);else if(e)throw e},e.prototype.addNode=function(e){var t=this._tagStack[this._tagStack.length-1],n=t?t.children:this.dom,r=n[n.length-1];this._parser&&(this._options.withStartIndices&&(e.startIndex=this._parser.startIndex),this._options.withEndIndices&&(e.endIndex=this._parser.endIndex)),n.push(e),r&&(e.prev=r,r.next=e),t&&(e.parent=t),this._lastNode=null},e.prototype.addDataNode=function(e){this.addNode(e),this._lastNode=e},e}();n.DomHandler=s,n.default=s},{"./node":8}],8:[function(e,t,n){var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(n,"__esModule",{value:!0});var i=new Map([["tag",1],["script",1],["style",1],["directive",1],["text",3],["cdata",4],["comment",8]]),s=function(){function e(e){this.type=e,this.parent=null,this.prev=null,this.next=null,this.startIndex=null,this.endIndex=null}return Object.defineProperty(e.prototype,"nodeType",{get:function(){return i.get(this.type)||1},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"parentNode",{get:function(){return this.parent||null},set:function(e){this.parent=e},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"previousSibling",{get:function(){return this.prev||null},set:function(e){this.prev=e},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"nextSibling",{get:function(){return this.next||null},set:function(e){this.next=e},enumerable:!0,configurable:!0}),e}();n.Node=s;var a=function(e){function t(t,n){var r=e.call(this,t)||this;return r.data=n,r}return o(t,e),Object.defineProperty(t.prototype,"nodeValue",{get:function(){return this.data},set:function(e){this.data=e},enumerable:!0,configurable:!0}),t}(s);n.DataNode=a;var u=function(e){function t(t,n){var r=e.call(this,"directive",n)||this;return r.name=t,r}return o(t,e),t}(a);n.ProcessingInstruction=u;var c=function(e){function t(t,n){var r=e.call(this,t)||this;return r.children=n,r}return o(t,e),Object.defineProperty(t.prototype,"firstChild",{get:function(){return this.children[0]||null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"lastChild",{get:function(){return this.children[this.children.length-1]||null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"childNodes",{get:function(){return this.children},set:function(e){this.children=e},enumerable:!0,configurable:!0}),t}(s);n.NodeWithChildren=c;var l=function(e){function t(t,n){var r=e.call(this,"script"===t?"script":"style"===t?"style":"tag",[])||this;return r.name=t,r.attribs=n,r.attribs=n,r}return o(t,e),Object.defineProperty(t.prototype,"tagName",{get:function(){return this.name},set:function(e){this.name=e},enumerable:!0,configurable:!0}),t}(c);n.Element=l},{}],9:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.uniqueSort=n.compareDocumentPosition=n.removeSubsets=void 0;var r=e("./tagtypes");function o(e,t){var n=[],o=[];if(e===t)return 0;for(var i=r.hasChildren(e)?e:e.parent;i;)n.unshift(i),i=i.parent;for(i=r.hasChildren(t)?t:t.parent;i;)o.unshift(i),i=i.parent;for(var s=Math.min(n.length,o.length),a=0;ac.indexOf(f)?u===t?20:4:u===e?10:2}n.removeSubsets=function(e){for(var t=e.length;--t>=0;){var n=e[t];if(t>0&&e.lastIndexOf(n,t-1)>=0)e.splice(t,1);else for(var r=n.parent;r;r=r.parent)if(e.includes(r)){e.splice(t,1);break}}return e},n.compareDocumentPosition=o,n.uniqueSort=function(e){return(e=e.filter((function(e,t,n){return!n.includes(e,t+1)}))).sort((function(e,t){var n=o(e,t);return 2&n?-1:4&n?1:0})),e}},{"./tagtypes":15}],10:[function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(n,"__esModule",{value:!0}),o(e("./stringify"),n),o(e("./traversal"),n),o(e("./manipulation"),n),o(e("./querying"),n),o(e("./legacy"),n),o(e("./helpers"),n),o(e("./tagtypes"),n)},{"./helpers":9,"./legacy":11,"./manipulation":12,"./querying":13,"./stringify":14,"./tagtypes":15,"./traversal":16}],11:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.getElementsByTagType=n.getElementsByTagName=n.getElementById=n.getElements=n.testElement=void 0;var r=e("./querying"),o=e("./tagtypes");function i(e){return"text"===e.type}var s={tag_name:function(e){return"function"==typeof e?function(t){return o.isTag(t)&&e(t.name)}:"*"===e?o.isTag:function(t){return o.isTag(t)&&t.name===e}},tag_type:function(e){return"function"==typeof e?function(t){return e(t.type)}:function(t){return t.type===e}},tag_contains:function(e){return"function"==typeof e?function(t){return i(t)&&e(t.data)}:function(t){return i(t)&&t.data===e}}};function a(e,t){return"function"==typeof t?function(n){return o.isTag(n)&&t(n.attribs[e])}:function(n){return o.isTag(n)&&n.attribs[e]===t}}function u(e,t){return function(n){return e(n)||t(n)}}function c(e){var t=Object.keys(e).map((function(t){var n=e[t];return t in s?s[t](n):a(t,n)}));return 0===t.length?null:t.reduce(u)}n.testElement=function(e,t){var n=c(e);return!n||n(t)},n.getElements=function(e,t,n,o){void 0===o&&(o=1/0);var i=c(e);return i?r.filter(i,t,n,o):[]},n.getElementById=function(e,t,n){return void 0===n&&(n=!0),Array.isArray(t)||(t=[t]),r.findOne(a("id",e),t,n)},n.getElementsByTagName=function(e,t,n,o){return void 0===o&&(o=1/0),r.filter(s.tag_name(e),t,n,o)},n.getElementsByTagType=function(e,t,n,o){return void 0===n&&(n=!0),void 0===o&&(o=1/0),r.filter(s.tag_type(e),t,n,o)}},{"./querying":13,"./tagtypes":15}],12:[function(e,t,n){function r(e){if(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e.parent){var t=e.parent.children;t.splice(t.lastIndexOf(e),1)}}Object.defineProperty(n,"__esModule",{value:!0}),n.prepend=n.append=n.appendChild=n.replaceElement=n.removeElement=void 0,n.removeElement=r,n.replaceElement=function(e,t){var n=t.prev=e.prev;n&&(n.next=t);var r=t.next=e.next;r&&(r.prev=t);var o=t.parent=e.parent;if(o){var i=o.children;i[i.lastIndexOf(e)]=t}},n.appendChild=function(e,t){if(r(t),t.parent=e,1!==e.children.push(t)){var n=e.children[e.children.length-2];n.next=t,t.prev=n,t.next=null}},n.append=function(e,t){r(t);var n=e.parent,o=e.next;if(t.next=o,t.prev=e,e.next=t,t.parent=n,o){if(o.prev=t,n){var i=n.children;i.splice(i.lastIndexOf(o),0,t)}}else n&&n.children.push(t)},n.prepend=function(e,t){var n=e.parent;if(n){var r=n.children;r.splice(r.lastIndexOf(e),0,t)}e.prev&&(e.prev.next=t),t.parent=n,t.prev=e.prev,t.next=e,e.prev=t}},{}],13:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.findAll=n.existsOne=n.findOne=n.findOneChild=n.find=n.filter=void 0;var r=e("./tagtypes");function o(e,t,n,i){for(var s=[],a=0,u=t;a0){var l=o(e,c.children,n,i);if(s.push.apply(s,l),(i-=l.length)<=0)break}}return s}n.filter=function(e,t,n,r){return void 0===n&&(n=!0),void 0===r&&(r=1/0),Array.isArray(t)||(t=[t]),o(e,t,n,r)},n.find=o,n.findOneChild=function(e,t){return t.find(e)},n.findOne=function e(t,n,o){void 0===o&&(o=!0);for(var i=null,s=0;s0&&(i=e(t,a.children)))}return i},n.existsOne=function e(t,n){return n.some((function(n){return r.isTag(n)&&(t(n)||n.children.length>0&&e(t,n.children))}))},n.findAll=function(e,t){for(var n,o,i=[],s=t.filter(r.isTag);o=s.shift();){var a=null===(n=o.children)||void 0===n?void 0:n.filter(r.isTag);a&&a.length>0&&s.unshift.apply(s,a),e(o)&&i.push(o)}return i}},{"./tagtypes":15}],14:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.getText=n.getInnerHTML=n.getOuterHTML=void 0;var o=e("./tagtypes"),i=r(e("dom-serializer"));function s(e,t){return i.default(e,t)}n.getOuterHTML=s,n.getInnerHTML=function(e,t){return o.hasChildren(e)?e.children.map((function(e){return s(e,t)})).join(""):""},n.getText=function e(t){return Array.isArray(t)?t.map(e).join(""):o.isTag(t)?"br"===t.name?"\n":e(t.children):o.isCDATA(t)?e(t.children):o.isText(t)?t.data:""}},{"./tagtypes":15,"dom-serializer":5}],15:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.hasChildren=n.isComment=n.isText=n.isCDATA=n.isTag=void 0;var r=e("domelementtype");n.isTag=function(e){return r.isTag(e)},n.isCDATA=function(e){return"cdata"===e.type},n.isText=function(e){return"text"===e.type},n.isComment=function(e){return"comment"===e.type},n.hasChildren=function(e){return Object.prototype.hasOwnProperty.call(e,"children")}},{domelementtype:6}],16:[function(e,t,n){function r(e){return e.children||null}function o(e){return e.parent||null}Object.defineProperty(n,"__esModule",{value:!0}),n.nextElementSibling=n.getName=n.hasAttrib=n.getAttributeValue=n.getSiblings=n.getParent=n.getChildren=void 0,n.getChildren=r,n.getParent=o,n.getSiblings=function(e){var t=o(e);return t?r(t):[e]},n.getAttributeValue=function(e,t){var n;return null===(n=e.attribs)||void 0===n?void 0:n[t]},n.hasAttrib=function(e,t){return!!e.attribs&&Object.prototype.hasOwnProperty.call(e.attribs,t)&&null!=e.attribs[t]},n.getName=function(e){return e.name},n.nextElementSibling=function(e){for(var t=e.next;null!==t&&"tag"!==t.type;)t=t.next;return t}},{}],17:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.decodeHTML=n.decodeHTMLStrict=n.decodeXML=void 0;var o=r(e("./maps/entities.json")),i=r(e("./maps/legacy.json")),s=r(e("./maps/xml.json")),a=r(e("./decode_codepoint"));function u(e){var t=Object.keys(e).join("|"),n=l(e),r=new RegExp("&(?:"+(t+="|#[xX][\\da-fA-F]+|#\\d+")+");","g");return function(e){return String(e).replace(r,n)}}n.decodeXML=u(s.default),n.decodeHTMLStrict=u(o.default);var c=function(e,t){return e=55296&&e<=57343||e>1114111)return"๏ฟฝ";e in o.default&&(e=o.default[e]);var t="";return e>65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|1023&e),t+=String.fromCharCode(e)}},{"./maps/decode.json":21}],19:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.escape=n.encodeHTML=n.encodeXML=void 0;var o=u(r(e("./maps/xml.json")).default),i=c(o);n.encodeXML=p(o,i);var s=u(r(e("./maps/entities.json")).default),a=c(s);function u(e){return Object.keys(e).sort().reduce((function(t,n){return t[e[n]]="&"+n+";",t}),{})}function c(e){for(var t=[],n=[],r=0,o=Object.keys(e);r",GT:">",Gt:"โ‰ซ",gtdot:"โ‹—",gtlPar:"โฆ•",gtquest:"โฉผ",gtrapprox:"โช†",gtrarr:"โฅธ",gtrdot:"โ‹—",gtreqless:"โ‹›",gtreqqless:"โชŒ",gtrless:"โ‰ท",gtrsim:"โ‰ณ",gvertneqq:"โ‰ฉ๏ธ€",gvnE:"โ‰ฉ๏ธ€",Hacek:"ห‡",hairsp:"โ€Š",half:"ยฝ",hamilt:"โ„‹",HARDcy:"ะช",hardcy:"ัŠ",harrcir:"โฅˆ",harr:"โ†”",hArr:"โ‡”",harrw:"โ†ญ",Hat:"^",hbar:"โ„",Hcirc:"ฤค",hcirc:"ฤฅ",hearts:"โ™ฅ",heartsuit:"โ™ฅ",hellip:"โ€ฆ",hercon:"โŠน",hfr:"๐”ฅ",Hfr:"โ„Œ",HilbertSpace:"โ„‹",hksearow:"โคฅ",hkswarow:"โคฆ",hoarr:"โ‡ฟ",homtht:"โˆป",hookleftarrow:"โ†ฉ",hookrightarrow:"โ†ช",hopf:"๐•™",Hopf:"โ„",horbar:"โ€•",HorizontalLine:"โ”€",hscr:"๐’ฝ",Hscr:"โ„‹",hslash:"โ„",Hstrok:"ฤฆ",hstrok:"ฤง",HumpDownHump:"โ‰Ž",HumpEqual:"โ‰",hybull:"โƒ",hyphen:"โ€",Iacute:"ร",iacute:"รญ",ic:"โฃ",Icirc:"รŽ",icirc:"รฎ",Icy:"ะ˜",icy:"ะธ",Idot:"ฤฐ",IEcy:"ะ•",iecy:"ะต",iexcl:"ยก",iff:"โ‡”",ifr:"๐”ฆ",Ifr:"โ„‘",Igrave:"รŒ",igrave:"รฌ",ii:"โ…ˆ",iiiint:"โจŒ",iiint:"โˆญ",iinfin:"โงœ",iiota:"โ„ฉ",IJlig:"ฤฒ",ijlig:"ฤณ",Imacr:"ฤช",imacr:"ฤซ",image:"โ„‘",ImaginaryI:"โ…ˆ",imagline:"โ„",imagpart:"โ„‘",imath:"ฤฑ",Im:"โ„‘",imof:"โŠท",imped:"ฦต",Implies:"โ‡’",incare:"โ„…",in:"โˆˆ",infin:"โˆž",infintie:"โง",inodot:"ฤฑ",intcal:"โŠบ",int:"โˆซ",Int:"โˆฌ",integers:"โ„ค",Integral:"โˆซ",intercal:"โŠบ",Intersection:"โ‹‚",intlarhk:"โจ—",intprod:"โจผ",InvisibleComma:"โฃ",InvisibleTimes:"โข",IOcy:"ะ",iocy:"ั‘",Iogon:"ฤฎ",iogon:"ฤฏ",Iopf:"๐•€",iopf:"๐•š",Iota:"ฮ™",iota:"ฮน",iprod:"โจผ",iquest:"ยฟ",iscr:"๐’พ",Iscr:"โ„",isin:"โˆˆ",isindot:"โ‹ต",isinE:"โ‹น",isins:"โ‹ด",isinsv:"โ‹ณ",isinv:"โˆˆ",it:"โข",Itilde:"ฤจ",itilde:"ฤฉ",Iukcy:"ะ†",iukcy:"ั–",Iuml:"ร",iuml:"รฏ",Jcirc:"ฤด",jcirc:"ฤต",Jcy:"ะ™",jcy:"ะน",Jfr:"๐”",jfr:"๐”ง",jmath:"ศท",Jopf:"๐•",jopf:"๐•›",Jscr:"๐’ฅ",jscr:"๐’ฟ",Jsercy:"ะˆ",jsercy:"ั˜",Jukcy:"ะ„",jukcy:"ั”",Kappa:"ฮš",kappa:"ฮบ",kappav:"ฯฐ",Kcedil:"ฤถ",kcedil:"ฤท",Kcy:"ะš",kcy:"ะบ",Kfr:"๐”Ž",kfr:"๐”จ",kgreen:"ฤธ",KHcy:"ะฅ",khcy:"ั…",KJcy:"ะŒ",kjcy:"ัœ",Kopf:"๐•‚",kopf:"๐•œ",Kscr:"๐’ฆ",kscr:"๐“€",lAarr:"โ‡š",Lacute:"ฤน",lacute:"ฤบ",laemptyv:"โฆด",lagran:"โ„’",Lambda:"ฮ›",lambda:"ฮป",lang:"โŸจ",Lang:"โŸช",langd:"โฆ‘",langle:"โŸจ",lap:"โช…",Laplacetrf:"โ„’",laquo:"ยซ",larrb:"โ‡ค",larrbfs:"โคŸ",larr:"โ†",Larr:"โ†ž",lArr:"โ‡",larrfs:"โค",larrhk:"โ†ฉ",larrlp:"โ†ซ",larrpl:"โคน",larrsim:"โฅณ",larrtl:"โ†ข",latail:"โค™",lAtail:"โค›",lat:"โชซ",late:"โชญ",lates:"โชญ๏ธ€",lbarr:"โคŒ",lBarr:"โคŽ",lbbrk:"โฒ",lbrace:"{",lbrack:"[",lbrke:"โฆ‹",lbrksld:"โฆ",lbrkslu:"โฆ",Lcaron:"ฤฝ",lcaron:"ฤพ",Lcedil:"ฤป",lcedil:"ฤผ",lceil:"โŒˆ",lcub:"{",Lcy:"ะ›",lcy:"ะป",ldca:"โคถ",ldquo:"โ€œ",ldquor:"โ€ž",ldrdhar:"โฅง",ldrushar:"โฅ‹",ldsh:"โ†ฒ",le:"โ‰ค",lE:"โ‰ฆ",LeftAngleBracket:"โŸจ",LeftArrowBar:"โ‡ค",leftarrow:"โ†",LeftArrow:"โ†",Leftarrow:"โ‡",LeftArrowRightArrow:"โ‡†",leftarrowtail:"โ†ข",LeftCeiling:"โŒˆ",LeftDoubleBracket:"โŸฆ",LeftDownTeeVector:"โฅก",LeftDownVectorBar:"โฅ™",LeftDownVector:"โ‡ƒ",LeftFloor:"โŒŠ",leftharpoondown:"โ†ฝ",leftharpoonup:"โ†ผ",leftleftarrows:"โ‡‡",leftrightarrow:"โ†”",LeftRightArrow:"โ†”",Leftrightarrow:"โ‡”",leftrightarrows:"โ‡†",leftrightharpoons:"โ‡‹",leftrightsquigarrow:"โ†ญ",LeftRightVector:"โฅŽ",LeftTeeArrow:"โ†ค",LeftTee:"โŠฃ",LeftTeeVector:"โฅš",leftthreetimes:"โ‹‹",LeftTriangleBar:"โง",LeftTriangle:"โŠฒ",LeftTriangleEqual:"โŠด",LeftUpDownVector:"โฅ‘",LeftUpTeeVector:"โฅ ",LeftUpVectorBar:"โฅ˜",LeftUpVector:"โ†ฟ",LeftVectorBar:"โฅ’",LeftVector:"โ†ผ",lEg:"โช‹",leg:"โ‹š",leq:"โ‰ค",leqq:"โ‰ฆ",leqslant:"โฉฝ",lescc:"โชจ",les:"โฉฝ",lesdot:"โฉฟ",lesdoto:"โช",lesdotor:"โชƒ",lesg:"โ‹š๏ธ€",lesges:"โช“",lessapprox:"โช…",lessdot:"โ‹–",lesseqgtr:"โ‹š",lesseqqgtr:"โช‹",LessEqualGreater:"โ‹š",LessFullEqual:"โ‰ฆ",LessGreater:"โ‰ถ",lessgtr:"โ‰ถ",LessLess:"โชก",lesssim:"โ‰ฒ",LessSlantEqual:"โฉฝ",LessTilde:"โ‰ฒ",lfisht:"โฅผ",lfloor:"โŒŠ",Lfr:"๐”",lfr:"๐”ฉ",lg:"โ‰ถ",lgE:"โช‘",lHar:"โฅข",lhard:"โ†ฝ",lharu:"โ†ผ",lharul:"โฅช",lhblk:"โ–„",LJcy:"ะ‰",ljcy:"ั™",llarr:"โ‡‡",ll:"โ‰ช",Ll:"โ‹˜",llcorner:"โŒž",Lleftarrow:"โ‡š",llhard:"โฅซ",lltri:"โ—บ",Lmidot:"ฤฟ",lmidot:"ล€",lmoustache:"โŽฐ",lmoust:"โŽฐ",lnap:"โช‰",lnapprox:"โช‰",lne:"โช‡",lnE:"โ‰จ",lneq:"โช‡",lneqq:"โ‰จ",lnsim:"โ‹ฆ",loang:"โŸฌ",loarr:"โ‡ฝ",lobrk:"โŸฆ",longleftarrow:"โŸต",LongLeftArrow:"โŸต",Longleftarrow:"โŸธ",longleftrightarrow:"โŸท",LongLeftRightArrow:"โŸท",Longleftrightarrow:"โŸบ",longmapsto:"โŸผ",longrightarrow:"โŸถ",LongRightArrow:"โŸถ",Longrightarrow:"โŸน",looparrowleft:"โ†ซ",looparrowright:"โ†ฌ",lopar:"โฆ…",Lopf:"๐•ƒ",lopf:"๐•",loplus:"โจญ",lotimes:"โจด",lowast:"โˆ—",lowbar:"_",LowerLeftArrow:"โ†™",LowerRightArrow:"โ†˜",loz:"โ—Š",lozenge:"โ—Š",lozf:"โงซ",lpar:"(",lparlt:"โฆ“",lrarr:"โ‡†",lrcorner:"โŒŸ",lrhar:"โ‡‹",lrhard:"โฅญ",lrm:"โ€Ž",lrtri:"โŠฟ",lsaquo:"โ€น",lscr:"๐“",Lscr:"โ„’",lsh:"โ†ฐ",Lsh:"โ†ฐ",lsim:"โ‰ฒ",lsime:"โช",lsimg:"โช",lsqb:"[",lsquo:"โ€˜",lsquor:"โ€š",Lstrok:"ล",lstrok:"ล‚",ltcc:"โชฆ",ltcir:"โฉน",lt:"<",LT:"<",Lt:"โ‰ช",ltdot:"โ‹–",lthree:"โ‹‹",ltimes:"โ‹‰",ltlarr:"โฅถ",ltquest:"โฉป",ltri:"โ—ƒ",ltrie:"โŠด",ltrif:"โ—‚",ltrPar:"โฆ–",lurdshar:"โฅŠ",luruhar:"โฅฆ",lvertneqq:"โ‰จ๏ธ€",lvnE:"โ‰จ๏ธ€",macr:"ยฏ",male:"โ™‚",malt:"โœ ",maltese:"โœ ",Map:"โค…",map:"โ†ฆ",mapsto:"โ†ฆ",mapstodown:"โ†ง",mapstoleft:"โ†ค",mapstoup:"โ†ฅ",marker:"โ–ฎ",mcomma:"โจฉ",Mcy:"ะœ",mcy:"ะผ",mdash:"โ€”",mDDot:"โˆบ",measuredangle:"โˆก",MediumSpace:"โŸ",Mellintrf:"โ„ณ",Mfr:"๐”",mfr:"๐”ช",mho:"โ„ง",micro:"ยต",midast:"*",midcir:"โซฐ",mid:"โˆฃ",middot:"ยท",minusb:"โŠŸ",minus:"โˆ’",minusd:"โˆธ",minusdu:"โจช",MinusPlus:"โˆ“",mlcp:"โซ›",mldr:"โ€ฆ",mnplus:"โˆ“",models:"โŠง",Mopf:"๐•„",mopf:"๐•ž",mp:"โˆ“",mscr:"๐“‚",Mscr:"โ„ณ",mstpos:"โˆพ",Mu:"ฮœ",mu:"ฮผ",multimap:"โŠธ",mumap:"โŠธ",nabla:"โˆ‡",Nacute:"ลƒ",nacute:"ล„",nang:"โˆ โƒ’",nap:"โ‰‰",napE:"โฉฐฬธ",napid:"โ‰‹ฬธ",napos:"ล‰",napprox:"โ‰‰",natural:"โ™ฎ",naturals:"โ„•",natur:"โ™ฎ",nbsp:"ย ",nbump:"โ‰Žฬธ",nbumpe:"โ‰ฬธ",ncap:"โฉƒ",Ncaron:"ล‡",ncaron:"ลˆ",Ncedil:"ล…",ncedil:"ล†",ncong:"โ‰‡",ncongdot:"โฉญฬธ",ncup:"โฉ‚",Ncy:"ะ",ncy:"ะฝ",ndash:"โ€“",nearhk:"โคค",nearr:"โ†—",neArr:"โ‡—",nearrow:"โ†—",ne:"โ‰ ",nedot:"โ‰ฬธ",NegativeMediumSpace:"โ€‹",NegativeThickSpace:"โ€‹",NegativeThinSpace:"โ€‹",NegativeVeryThinSpace:"โ€‹",nequiv:"โ‰ข",nesear:"โคจ",nesim:"โ‰‚ฬธ",NestedGreaterGreater:"โ‰ซ",NestedLessLess:"โ‰ช",NewLine:"\n",nexist:"โˆ„",nexists:"โˆ„",Nfr:"๐”‘",nfr:"๐”ซ",ngE:"โ‰งฬธ",nge:"โ‰ฑ",ngeq:"โ‰ฑ",ngeqq:"โ‰งฬธ",ngeqslant:"โฉพฬธ",nges:"โฉพฬธ",nGg:"โ‹™ฬธ",ngsim:"โ‰ต",nGt:"โ‰ซโƒ’",ngt:"โ‰ฏ",ngtr:"โ‰ฏ",nGtv:"โ‰ซฬธ",nharr:"โ†ฎ",nhArr:"โ‡Ž",nhpar:"โซฒ",ni:"โˆ‹",nis:"โ‹ผ",nisd:"โ‹บ",niv:"โˆ‹",NJcy:"ะŠ",njcy:"ัš",nlarr:"โ†š",nlArr:"โ‡",nldr:"โ€ฅ",nlE:"โ‰ฆฬธ",nle:"โ‰ฐ",nleftarrow:"โ†š",nLeftarrow:"โ‡",nleftrightarrow:"โ†ฎ",nLeftrightarrow:"โ‡Ž",nleq:"โ‰ฐ",nleqq:"โ‰ฆฬธ",nleqslant:"โฉฝฬธ",nles:"โฉฝฬธ",nless:"โ‰ฎ",nLl:"โ‹˜ฬธ",nlsim:"โ‰ด",nLt:"โ‰ชโƒ’",nlt:"โ‰ฎ",nltri:"โ‹ช",nltrie:"โ‹ฌ",nLtv:"โ‰ชฬธ",nmid:"โˆค",NoBreak:"โ ",NonBreakingSpace:"ย ",nopf:"๐•Ÿ",Nopf:"โ„•",Not:"โซฌ",not:"ยฌ",NotCongruent:"โ‰ข",NotCupCap:"โ‰ญ",NotDoubleVerticalBar:"โˆฆ",NotElement:"โˆ‰",NotEqual:"โ‰ ",NotEqualTilde:"โ‰‚ฬธ",NotExists:"โˆ„",NotGreater:"โ‰ฏ",NotGreaterEqual:"โ‰ฑ",NotGreaterFullEqual:"โ‰งฬธ",NotGreaterGreater:"โ‰ซฬธ",NotGreaterLess:"โ‰น",NotGreaterSlantEqual:"โฉพฬธ",NotGreaterTilde:"โ‰ต",NotHumpDownHump:"โ‰Žฬธ",NotHumpEqual:"โ‰ฬธ",notin:"โˆ‰",notindot:"โ‹ตฬธ",notinE:"โ‹นฬธ",notinva:"โˆ‰",notinvb:"โ‹ท",notinvc:"โ‹ถ",NotLeftTriangleBar:"โงฬธ",NotLeftTriangle:"โ‹ช",NotLeftTriangleEqual:"โ‹ฌ",NotLess:"โ‰ฎ",NotLessEqual:"โ‰ฐ",NotLessGreater:"โ‰ธ",NotLessLess:"โ‰ชฬธ",NotLessSlantEqual:"โฉฝฬธ",NotLessTilde:"โ‰ด",NotNestedGreaterGreater:"โชขฬธ",NotNestedLessLess:"โชกฬธ",notni:"โˆŒ",notniva:"โˆŒ",notnivb:"โ‹พ",notnivc:"โ‹ฝ",NotPrecedes:"โŠ€",NotPrecedesEqual:"โชฏฬธ",NotPrecedesSlantEqual:"โ‹ ",NotReverseElement:"โˆŒ",NotRightTriangleBar:"โงฬธ",NotRightTriangle:"โ‹ซ",NotRightTriangleEqual:"โ‹ญ",NotSquareSubset:"โŠฬธ",NotSquareSubsetEqual:"โ‹ข",NotSquareSuperset:"โŠฬธ",NotSquareSupersetEqual:"โ‹ฃ",NotSubset:"โŠ‚โƒ’",NotSubsetEqual:"โŠˆ",NotSucceeds:"โŠ",NotSucceedsEqual:"โชฐฬธ",NotSucceedsSlantEqual:"โ‹ก",NotSucceedsTilde:"โ‰ฟฬธ",NotSuperset:"โŠƒโƒ’",NotSupersetEqual:"โŠ‰",NotTilde:"โ‰",NotTildeEqual:"โ‰„",NotTildeFullEqual:"โ‰‡",NotTildeTilde:"โ‰‰",NotVerticalBar:"โˆค",nparallel:"โˆฆ",npar:"โˆฆ",nparsl:"โซฝโƒฅ",npart:"โˆ‚ฬธ",npolint:"โจ”",npr:"โŠ€",nprcue:"โ‹ ",nprec:"โŠ€",npreceq:"โชฏฬธ",npre:"โชฏฬธ",nrarrc:"โคณฬธ",nrarr:"โ†›",nrArr:"โ‡",nrarrw:"โ†ฬธ",nrightarrow:"โ†›",nRightarrow:"โ‡",nrtri:"โ‹ซ",nrtrie:"โ‹ญ",nsc:"โŠ",nsccue:"โ‹ก",nsce:"โชฐฬธ",Nscr:"๐’ฉ",nscr:"๐“ƒ",nshortmid:"โˆค",nshortparallel:"โˆฆ",nsim:"โ‰",nsime:"โ‰„",nsimeq:"โ‰„",nsmid:"โˆค",nspar:"โˆฆ",nsqsube:"โ‹ข",nsqsupe:"โ‹ฃ",nsub:"โŠ„",nsubE:"โซ…ฬธ",nsube:"โŠˆ",nsubset:"โŠ‚โƒ’",nsubseteq:"โŠˆ",nsubseteqq:"โซ…ฬธ",nsucc:"โŠ",nsucceq:"โชฐฬธ",nsup:"โŠ…",nsupE:"โซ†ฬธ",nsupe:"โŠ‰",nsupset:"โŠƒโƒ’",nsupseteq:"โŠ‰",nsupseteqq:"โซ†ฬธ",ntgl:"โ‰น",Ntilde:"ร‘",ntilde:"รฑ",ntlg:"โ‰ธ",ntriangleleft:"โ‹ช",ntrianglelefteq:"โ‹ฌ",ntriangleright:"โ‹ซ",ntrianglerighteq:"โ‹ญ",Nu:"ฮ",nu:"ฮฝ",num:"#",numero:"โ„–",numsp:"โ€‡",nvap:"โ‰โƒ’",nvdash:"โŠฌ",nvDash:"โŠญ",nVdash:"โŠฎ",nVDash:"โŠฏ",nvge:"โ‰ฅโƒ’",nvgt:">โƒ’",nvHarr:"โค„",nvinfin:"โงž",nvlArr:"โค‚",nvle:"โ‰คโƒ’",nvlt:"<โƒ’",nvltrie:"โŠดโƒ’",nvrArr:"โคƒ",nvrtrie:"โŠตโƒ’",nvsim:"โˆผโƒ’",nwarhk:"โคฃ",nwarr:"โ†–",nwArr:"โ‡–",nwarrow:"โ†–",nwnear:"โคง",Oacute:"ร“",oacute:"รณ",oast:"โŠ›",Ocirc:"ร”",ocirc:"รด",ocir:"โŠš",Ocy:"ะž",ocy:"ะพ",odash:"โŠ",Odblac:"ล",odblac:"ล‘",odiv:"โจธ",odot:"โŠ™",odsold:"โฆผ",OElig:"ล’",oelig:"ล“",ofcir:"โฆฟ",Ofr:"๐”’",ofr:"๐”ฌ",ogon:"ห›",Ograve:"ร’",ograve:"รฒ",ogt:"โง",ohbar:"โฆต",ohm:"ฮฉ",oint:"โˆฎ",olarr:"โ†บ",olcir:"โฆพ",olcross:"โฆป",oline:"โ€พ",olt:"โง€",Omacr:"ลŒ",omacr:"ล",Omega:"ฮฉ",omega:"ฯ‰",Omicron:"ฮŸ",omicron:"ฮฟ",omid:"โฆถ",ominus:"โŠ–",Oopf:"๐•†",oopf:"๐• ",opar:"โฆท",OpenCurlyDoubleQuote:"โ€œ",OpenCurlyQuote:"โ€˜",operp:"โฆน",oplus:"โŠ•",orarr:"โ†ป",Or:"โฉ”",or:"โˆจ",ord:"โฉ",order:"โ„ด",orderof:"โ„ด",ordf:"ยช",ordm:"ยบ",origof:"โŠถ",oror:"โฉ–",orslope:"โฉ—",orv:"โฉ›",oS:"โ“ˆ",Oscr:"๐’ช",oscr:"โ„ด",Oslash:"ร˜",oslash:"รธ",osol:"โŠ˜",Otilde:"ร•",otilde:"รต",otimesas:"โจถ",Otimes:"โจท",otimes:"โŠ—",Ouml:"ร–",ouml:"รถ",ovbar:"โŒฝ",OverBar:"โ€พ",OverBrace:"โž",OverBracket:"โŽด",OverParenthesis:"โœ",para:"ยถ",parallel:"โˆฅ",par:"โˆฅ",parsim:"โซณ",parsl:"โซฝ",part:"โˆ‚",PartialD:"โˆ‚",Pcy:"ะŸ",pcy:"ะฟ",percnt:"%",period:".",permil:"โ€ฐ",perp:"โŠฅ",pertenk:"โ€ฑ",Pfr:"๐”“",pfr:"๐”ญ",Phi:"ฮฆ",phi:"ฯ†",phiv:"ฯ•",phmmat:"โ„ณ",phone:"โ˜Ž",Pi:"ฮ ",pi:"ฯ€",pitchfork:"โ‹”",piv:"ฯ–",planck:"โ„",planckh:"โ„Ž",plankv:"โ„",plusacir:"โจฃ",plusb:"โŠž",pluscir:"โจข",plus:"+",plusdo:"โˆ”",plusdu:"โจฅ",pluse:"โฉฒ",PlusMinus:"ยฑ",plusmn:"ยฑ",plussim:"โจฆ",plustwo:"โจง",pm:"ยฑ",Poincareplane:"โ„Œ",pointint:"โจ•",popf:"๐•ก",Popf:"โ„™",pound:"ยฃ",prap:"โชท",Pr:"โชป",pr:"โ‰บ",prcue:"โ‰ผ",precapprox:"โชท",prec:"โ‰บ",preccurlyeq:"โ‰ผ",Precedes:"โ‰บ",PrecedesEqual:"โชฏ",PrecedesSlantEqual:"โ‰ผ",PrecedesTilde:"โ‰พ",preceq:"โชฏ",precnapprox:"โชน",precneqq:"โชต",precnsim:"โ‹จ",pre:"โชฏ",prE:"โชณ",precsim:"โ‰พ",prime:"โ€ฒ",Prime:"โ€ณ",primes:"โ„™",prnap:"โชน",prnE:"โชต",prnsim:"โ‹จ",prod:"โˆ",Product:"โˆ",profalar:"โŒฎ",profline:"โŒ’",profsurf:"โŒ“",prop:"โˆ",Proportional:"โˆ",Proportion:"โˆท",propto:"โˆ",prsim:"โ‰พ",prurel:"โŠฐ",Pscr:"๐’ซ",pscr:"๐“…",Psi:"ฮจ",psi:"ฯˆ",puncsp:"โ€ˆ",Qfr:"๐””",qfr:"๐”ฎ",qint:"โจŒ",qopf:"๐•ข",Qopf:"โ„š",qprime:"โ—",Qscr:"๐’ฌ",qscr:"๐“†",quaternions:"โ„",quatint:"โจ–",quest:"?",questeq:"โ‰Ÿ",quot:'"',QUOT:'"',rAarr:"โ‡›",race:"โˆฝฬฑ",Racute:"ล”",racute:"ล•",radic:"โˆš",raemptyv:"โฆณ",rang:"โŸฉ",Rang:"โŸซ",rangd:"โฆ’",range:"โฆฅ",rangle:"โŸฉ",raquo:"ยป",rarrap:"โฅต",rarrb:"โ‡ฅ",rarrbfs:"โค ",rarrc:"โคณ",rarr:"โ†’",Rarr:"โ† ",rArr:"โ‡’",rarrfs:"โคž",rarrhk:"โ†ช",rarrlp:"โ†ฌ",rarrpl:"โฅ…",rarrsim:"โฅด",Rarrtl:"โค–",rarrtl:"โ†ฃ",rarrw:"โ†",ratail:"โคš",rAtail:"โคœ",ratio:"โˆถ",rationals:"โ„š",rbarr:"โค",rBarr:"โค",RBarr:"โค",rbbrk:"โณ",rbrace:"}",rbrack:"]",rbrke:"โฆŒ",rbrksld:"โฆŽ",rbrkslu:"โฆ",Rcaron:"ล˜",rcaron:"ล™",Rcedil:"ล–",rcedil:"ล—",rceil:"โŒ‰",rcub:"}",Rcy:"ะ ",rcy:"ั€",rdca:"โคท",rdldhar:"โฅฉ",rdquo:"โ€",rdquor:"โ€",rdsh:"โ†ณ",real:"โ„œ",realine:"โ„›",realpart:"โ„œ",reals:"โ„",Re:"โ„œ",rect:"โ–ญ",reg:"ยฎ",REG:"ยฎ",ReverseElement:"โˆ‹",ReverseEquilibrium:"โ‡‹",ReverseUpEquilibrium:"โฅฏ",rfisht:"โฅฝ",rfloor:"โŒ‹",rfr:"๐”ฏ",Rfr:"โ„œ",rHar:"โฅค",rhard:"โ‡",rharu:"โ‡€",rharul:"โฅฌ",Rho:"ฮก",rho:"ฯ",rhov:"ฯฑ",RightAngleBracket:"โŸฉ",RightArrowBar:"โ‡ฅ",rightarrow:"โ†’",RightArrow:"โ†’",Rightarrow:"โ‡’",RightArrowLeftArrow:"โ‡„",rightarrowtail:"โ†ฃ",RightCeiling:"โŒ‰",RightDoubleBracket:"โŸง",RightDownTeeVector:"โฅ",RightDownVectorBar:"โฅ•",RightDownVector:"โ‡‚",RightFloor:"โŒ‹",rightharpoondown:"โ‡",rightharpoonup:"โ‡€",rightleftarrows:"โ‡„",rightleftharpoons:"โ‡Œ",rightrightarrows:"โ‡‰",rightsquigarrow:"โ†",RightTeeArrow:"โ†ฆ",RightTee:"โŠข",RightTeeVector:"โฅ›",rightthreetimes:"โ‹Œ",RightTriangleBar:"โง",RightTriangle:"โŠณ",RightTriangleEqual:"โŠต",RightUpDownVector:"โฅ",RightUpTeeVector:"โฅœ",RightUpVectorBar:"โฅ”",RightUpVector:"โ†พ",RightVectorBar:"โฅ“",RightVector:"โ‡€",ring:"หš",risingdotseq:"โ‰“",rlarr:"โ‡„",rlhar:"โ‡Œ",rlm:"โ€",rmoustache:"โŽฑ",rmoust:"โŽฑ",rnmid:"โซฎ",roang:"โŸญ",roarr:"โ‡พ",robrk:"โŸง",ropar:"โฆ†",ropf:"๐•ฃ",Ropf:"โ„",roplus:"โจฎ",rotimes:"โจต",RoundImplies:"โฅฐ",rpar:")",rpargt:"โฆ”",rppolint:"โจ’",rrarr:"โ‡‰",Rrightarrow:"โ‡›",rsaquo:"โ€บ",rscr:"๐“‡",Rscr:"โ„›",rsh:"โ†ฑ",Rsh:"โ†ฑ",rsqb:"]",rsquo:"โ€™",rsquor:"โ€™",rthree:"โ‹Œ",rtimes:"โ‹Š",rtri:"โ–น",rtrie:"โŠต",rtrif:"โ–ธ",rtriltri:"โงŽ",RuleDelayed:"โงด",ruluhar:"โฅจ",rx:"โ„ž",Sacute:"ลš",sacute:"ล›",sbquo:"โ€š",scap:"โชธ",Scaron:"ล ",scaron:"ลก",Sc:"โชผ",sc:"โ‰ป",sccue:"โ‰ฝ",sce:"โชฐ",scE:"โชด",Scedil:"ลž",scedil:"ลŸ",Scirc:"ลœ",scirc:"ล",scnap:"โชบ",scnE:"โชถ",scnsim:"โ‹ฉ",scpolint:"โจ“",scsim:"โ‰ฟ",Scy:"ะก",scy:"ั",sdotb:"โŠก",sdot:"โ‹…",sdote:"โฉฆ",searhk:"โคฅ",searr:"โ†˜",seArr:"โ‡˜",searrow:"โ†˜",sect:"ยง",semi:";",seswar:"โคฉ",setminus:"โˆ–",setmn:"โˆ–",sext:"โœถ",Sfr:"๐”–",sfr:"๐”ฐ",sfrown:"โŒข",sharp:"โ™ฏ",SHCHcy:"ะฉ",shchcy:"ั‰",SHcy:"ะจ",shcy:"ัˆ",ShortDownArrow:"โ†“",ShortLeftArrow:"โ†",shortmid:"โˆฃ",shortparallel:"โˆฅ",ShortRightArrow:"โ†’",ShortUpArrow:"โ†‘",shy:"ยญ",Sigma:"ฮฃ",sigma:"ฯƒ",sigmaf:"ฯ‚",sigmav:"ฯ‚",sim:"โˆผ",simdot:"โฉช",sime:"โ‰ƒ",simeq:"โ‰ƒ",simg:"โชž",simgE:"โช ",siml:"โช",simlE:"โชŸ",simne:"โ‰†",simplus:"โจค",simrarr:"โฅฒ",slarr:"โ†",SmallCircle:"โˆ˜",smallsetminus:"โˆ–",smashp:"โจณ",smeparsl:"โงค",smid:"โˆฃ",smile:"โŒฃ",smt:"โชช",smte:"โชฌ",smtes:"โชฌ๏ธ€",SOFTcy:"ะฌ",softcy:"ัŒ",solbar:"โŒฟ",solb:"โง„",sol:"/",Sopf:"๐•Š",sopf:"๐•ค",spades:"โ™ ",spadesuit:"โ™ ",spar:"โˆฅ",sqcap:"โŠ“",sqcaps:"โŠ“๏ธ€",sqcup:"โŠ”",sqcups:"โŠ”๏ธ€",Sqrt:"โˆš",sqsub:"โŠ",sqsube:"โŠ‘",sqsubset:"โŠ",sqsubseteq:"โŠ‘",sqsup:"โŠ",sqsupe:"โŠ’",sqsupset:"โŠ",sqsupseteq:"โŠ’",square:"โ–ก",Square:"โ–ก",SquareIntersection:"โŠ“",SquareSubset:"โŠ",SquareSubsetEqual:"โŠ‘",SquareSuperset:"โŠ",SquareSupersetEqual:"โŠ’",SquareUnion:"โŠ”",squarf:"โ–ช",squ:"โ–ก",squf:"โ–ช",srarr:"โ†’",Sscr:"๐’ฎ",sscr:"๐“ˆ",ssetmn:"โˆ–",ssmile:"โŒฃ",sstarf:"โ‹†",Star:"โ‹†",star:"โ˜†",starf:"โ˜…",straightepsilon:"ฯต",straightphi:"ฯ•",strns:"ยฏ",sub:"โŠ‚",Sub:"โ‹",subdot:"โชฝ",subE:"โซ…",sube:"โŠ†",subedot:"โซƒ",submult:"โซ",subnE:"โซ‹",subne:"โŠŠ",subplus:"โชฟ",subrarr:"โฅน",subset:"โŠ‚",Subset:"โ‹",subseteq:"โŠ†",subseteqq:"โซ…",SubsetEqual:"โŠ†",subsetneq:"โŠŠ",subsetneqq:"โซ‹",subsim:"โซ‡",subsub:"โซ•",subsup:"โซ“",succapprox:"โชธ",succ:"โ‰ป",succcurlyeq:"โ‰ฝ",Succeeds:"โ‰ป",SucceedsEqual:"โชฐ",SucceedsSlantEqual:"โ‰ฝ",SucceedsTilde:"โ‰ฟ",succeq:"โชฐ",succnapprox:"โชบ",succneqq:"โชถ",succnsim:"โ‹ฉ",succsim:"โ‰ฟ",SuchThat:"โˆ‹",sum:"โˆ‘",Sum:"โˆ‘",sung:"โ™ช",sup1:"ยน",sup2:"ยฒ",sup3:"ยณ",sup:"โŠƒ",Sup:"โ‹‘",supdot:"โชพ",supdsub:"โซ˜",supE:"โซ†",supe:"โŠ‡",supedot:"โซ„",Superset:"โŠƒ",SupersetEqual:"โŠ‡",suphsol:"โŸ‰",suphsub:"โซ—",suplarr:"โฅป",supmult:"โซ‚",supnE:"โซŒ",supne:"โŠ‹",supplus:"โซ€",supset:"โŠƒ",Supset:"โ‹‘",supseteq:"โŠ‡",supseteqq:"โซ†",supsetneq:"โŠ‹",supsetneqq:"โซŒ",supsim:"โซˆ",supsub:"โซ”",supsup:"โซ–",swarhk:"โคฆ",swarr:"โ†™",swArr:"โ‡™",swarrow:"โ†™",swnwar:"โคช",szlig:"รŸ",Tab:"\t",target:"โŒ–",Tau:"ฮค",tau:"ฯ„",tbrk:"โŽด",Tcaron:"ลค",tcaron:"ลฅ",Tcedil:"ลข",tcedil:"ลฃ",Tcy:"ะข",tcy:"ั‚",tdot:"โƒ›",telrec:"โŒ•",Tfr:"๐”—",tfr:"๐”ฑ",there4:"โˆด",therefore:"โˆด",Therefore:"โˆด",Theta:"ฮ˜",theta:"ฮธ",thetasym:"ฯ‘",thetav:"ฯ‘",thickapprox:"โ‰ˆ",thicksim:"โˆผ",ThickSpace:"โŸโ€Š",ThinSpace:"โ€‰",thinsp:"โ€‰",thkap:"โ‰ˆ",thksim:"โˆผ",THORN:"รž",thorn:"รพ",tilde:"หœ",Tilde:"โˆผ",TildeEqual:"โ‰ƒ",TildeFullEqual:"โ‰…",TildeTilde:"โ‰ˆ",timesbar:"โจฑ",timesb:"โŠ ",times:"ร—",timesd:"โจฐ",tint:"โˆญ",toea:"โคจ",topbot:"โŒถ",topcir:"โซฑ",top:"โŠค",Topf:"๐•‹",topf:"๐•ฅ",topfork:"โซš",tosa:"โคฉ",tprime:"โ€ด",trade:"โ„ข",TRADE:"โ„ข",triangle:"โ–ต",triangledown:"โ–ฟ",triangleleft:"โ—ƒ",trianglelefteq:"โŠด",triangleq:"โ‰œ",triangleright:"โ–น",trianglerighteq:"โŠต",tridot:"โ—ฌ",trie:"โ‰œ",triminus:"โจบ",TripleDot:"โƒ›",triplus:"โจน",trisb:"โง",tritime:"โจป",trpezium:"โข",Tscr:"๐’ฏ",tscr:"๐“‰",TScy:"ะฆ",tscy:"ั†",TSHcy:"ะ‹",tshcy:"ั›",Tstrok:"ลฆ",tstrok:"ลง",twixt:"โ‰ฌ",twoheadleftarrow:"โ†ž",twoheadrightarrow:"โ† ",Uacute:"รš",uacute:"รบ",uarr:"โ†‘",Uarr:"โ†Ÿ",uArr:"โ‡‘",Uarrocir:"โฅ‰",Ubrcy:"ะŽ",ubrcy:"ัž",Ubreve:"ลฌ",ubreve:"ลญ",Ucirc:"ร›",ucirc:"รป",Ucy:"ะฃ",ucy:"ัƒ",udarr:"โ‡…",Udblac:"ลฐ",udblac:"ลฑ",udhar:"โฅฎ",ufisht:"โฅพ",Ufr:"๐”˜",ufr:"๐”ฒ",Ugrave:"ร™",ugrave:"รน",uHar:"โฅฃ",uharl:"โ†ฟ",uharr:"โ†พ",uhblk:"โ–€",ulcorn:"โŒœ",ulcorner:"โŒœ",ulcrop:"โŒ",ultri:"โ—ธ",Umacr:"ลช",umacr:"ลซ",uml:"ยจ",UnderBar:"_",UnderBrace:"โŸ",UnderBracket:"โŽต",UnderParenthesis:"โ",Union:"โ‹ƒ",UnionPlus:"โŠŽ",Uogon:"ลฒ",uogon:"ลณ",Uopf:"๐•Œ",uopf:"๐•ฆ",UpArrowBar:"โค’",uparrow:"โ†‘",UpArrow:"โ†‘",Uparrow:"โ‡‘",UpArrowDownArrow:"โ‡…",updownarrow:"โ†•",UpDownArrow:"โ†•",Updownarrow:"โ‡•",UpEquilibrium:"โฅฎ",upharpoonleft:"โ†ฟ",upharpoonright:"โ†พ",uplus:"โŠŽ",UpperLeftArrow:"โ†–",UpperRightArrow:"โ†—",upsi:"ฯ…",Upsi:"ฯ’",upsih:"ฯ’",Upsilon:"ฮฅ",upsilon:"ฯ…",UpTeeArrow:"โ†ฅ",UpTee:"โŠฅ",upuparrows:"โ‡ˆ",urcorn:"โŒ",urcorner:"โŒ",urcrop:"โŒŽ",Uring:"ลฎ",uring:"ลฏ",urtri:"โ—น",Uscr:"๐’ฐ",uscr:"๐“Š",utdot:"โ‹ฐ",Utilde:"ลจ",utilde:"ลฉ",utri:"โ–ต",utrif:"โ–ด",uuarr:"โ‡ˆ",Uuml:"รœ",uuml:"รผ",uwangle:"โฆง",vangrt:"โฆœ",varepsilon:"ฯต",varkappa:"ฯฐ",varnothing:"โˆ…",varphi:"ฯ•",varpi:"ฯ–",varpropto:"โˆ",varr:"โ†•",vArr:"โ‡•",varrho:"ฯฑ",varsigma:"ฯ‚",varsubsetneq:"โŠŠ๏ธ€",varsubsetneqq:"โซ‹๏ธ€",varsupsetneq:"โŠ‹๏ธ€",varsupsetneqq:"โซŒ๏ธ€",vartheta:"ฯ‘",vartriangleleft:"โŠฒ",vartriangleright:"โŠณ",vBar:"โซจ",Vbar:"โซซ",vBarv:"โซฉ",Vcy:"ะ’",vcy:"ะฒ",vdash:"โŠข",vDash:"โŠจ",Vdash:"โŠฉ",VDash:"โŠซ",Vdashl:"โซฆ",veebar:"โŠป",vee:"โˆจ",Vee:"โ‹",veeeq:"โ‰š",vellip:"โ‹ฎ",verbar:"|",Verbar:"โ€–",vert:"|",Vert:"โ€–",VerticalBar:"โˆฃ",VerticalLine:"|",VerticalSeparator:"โ˜",VerticalTilde:"โ‰€",VeryThinSpace:"โ€Š",Vfr:"๐”™",vfr:"๐”ณ",vltri:"โŠฒ",vnsub:"โŠ‚โƒ’",vnsup:"โŠƒโƒ’",Vopf:"๐•",vopf:"๐•ง",vprop:"โˆ",vrtri:"โŠณ",Vscr:"๐’ฑ",vscr:"๐“‹",vsubnE:"โซ‹๏ธ€",vsubne:"โŠŠ๏ธ€",vsupnE:"โซŒ๏ธ€",vsupne:"โŠ‹๏ธ€",Vvdash:"โŠช",vzigzag:"โฆš",Wcirc:"ลด",wcirc:"ลต",wedbar:"โฉŸ",wedge:"โˆง",Wedge:"โ‹€",wedgeq:"โ‰™",weierp:"โ„˜",Wfr:"๐”š",wfr:"๐”ด",Wopf:"๐•Ž",wopf:"๐•จ",wp:"โ„˜",wr:"โ‰€",wreath:"โ‰€",Wscr:"๐’ฒ",wscr:"๐“Œ",xcap:"โ‹‚",xcirc:"โ—ฏ",xcup:"โ‹ƒ",xdtri:"โ–ฝ",Xfr:"๐”›",xfr:"๐”ต",xharr:"โŸท",xhArr:"โŸบ",Xi:"ฮž",xi:"ฮพ",xlarr:"โŸต",xlArr:"โŸธ",xmap:"โŸผ",xnis:"โ‹ป",xodot:"โจ€",Xopf:"๐•",xopf:"๐•ฉ",xoplus:"โจ",xotime:"โจ‚",xrarr:"โŸถ",xrArr:"โŸน",Xscr:"๐’ณ",xscr:"๐“",xsqcup:"โจ†",xuplus:"โจ„",xutri:"โ–ณ",xvee:"โ‹",xwedge:"โ‹€",Yacute:"ร",yacute:"รฝ",YAcy:"ะฏ",yacy:"ั",Ycirc:"ลถ",ycirc:"ลท",Ycy:"ะซ",ycy:"ั‹",yen:"ยฅ",Yfr:"๐”œ",yfr:"๐”ถ",YIcy:"ะ‡",yicy:"ั—",Yopf:"๐•",yopf:"๐•ช",Yscr:"๐’ด",yscr:"๐“Ž",YUcy:"ะฎ",yucy:"ัŽ",yuml:"รฟ",Yuml:"ลธ",Zacute:"ลน",zacute:"ลบ",Zcaron:"ลฝ",zcaron:"ลพ",Zcy:"ะ—",zcy:"ะท",Zdot:"ลป",zdot:"ลผ",zeetrf:"โ„จ",ZeroWidthSpace:"โ€‹",Zeta:"ฮ–",zeta:"ฮถ",zfr:"๐”ท",Zfr:"โ„จ",ZHcy:"ะ–",zhcy:"ะถ",zigrarr:"โ‡",zopf:"๐•ซ",Zopf:"โ„ค",Zscr:"๐’ต",zscr:"๐“",zwj:"โ€",zwnj:"โ€Œ"}},{}],23:[function(e,t,n){t.exports={Aacute:"ร",aacute:"รก",Acirc:"ร‚",acirc:"รข",acute:"ยด",AElig:"ร†",aelig:"รฆ",Agrave:"ร€",agrave:"ร ",amp:"&",AMP:"&",Aring:"ร…",aring:"รฅ",Atilde:"รƒ",atilde:"รฃ",Auml:"ร„",auml:"รค",brvbar:"ยฆ",Ccedil:"ร‡",ccedil:"รง",cedil:"ยธ",cent:"ยข",copy:"ยฉ",COPY:"ยฉ",curren:"ยค",deg:"ยฐ",divide:"รท",Eacute:"ร‰",eacute:"รฉ",Ecirc:"รŠ",ecirc:"รช",Egrave:"รˆ",egrave:"รจ",ETH:"ร",eth:"รฐ",Euml:"ร‹",euml:"รซ",frac12:"ยฝ",frac14:"ยผ",frac34:"ยพ",gt:">",GT:">",Iacute:"ร",iacute:"รญ",Icirc:"รŽ",icirc:"รฎ",iexcl:"ยก",Igrave:"รŒ",igrave:"รฌ",iquest:"ยฟ",Iuml:"ร",iuml:"รฏ",laquo:"ยซ",lt:"<",LT:"<",macr:"ยฏ",micro:"ยต",middot:"ยท",nbsp:"ย ",not:"ยฌ",Ntilde:"ร‘",ntilde:"รฑ",Oacute:"ร“",oacute:"รณ",Ocirc:"ร”",ocirc:"รด",Ograve:"ร’",ograve:"รฒ",ordf:"ยช",ordm:"ยบ",Oslash:"ร˜",oslash:"รธ",Otilde:"ร•",otilde:"รต",Ouml:"ร–",ouml:"รถ",para:"ยถ",plusmn:"ยฑ",pound:"ยฃ",quot:'"',QUOT:'"',raquo:"ยป",reg:"ยฎ",REG:"ยฎ",sect:"ยง",shy:"ยญ",sup1:"ยน",sup2:"ยฒ",sup3:"ยณ",szlig:"รŸ",THORN:"รž",thorn:"รพ",times:"ร—",Uacute:"รš",uacute:"รบ",Ucirc:"ร›",ucirc:"รป",Ugrave:"ร™",ugrave:"รน",uml:"ยจ",Uuml:"รœ",uuml:"รผ",Yacute:"ร",yacute:"รฝ",yen:"ยฅ",yuml:"รฟ"}},{}],24:[function(e,t,n){t.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],25:[function(e,t,n){var r=Object.create||function(e){var t=function(){};return t.prototype=e,new t},o=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return n},i=Function.prototype.bind||function(e){var t=this;return function(){return t.apply(e,arguments)}};function s(){this._events&&Object.prototype.hasOwnProperty.call(this,"_events")||(this._events=r(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0}t.exports=s,s.EventEmitter=s,s.prototype._events=void 0,s.prototype._maxListeners=void 0;var a,u=10;try{var l={};Object.defineProperty&&Object.defineProperty(l,"x",{value:0}),a=0===l.x}catch(e){a=!1}function f(e){return void 0===e._maxListeners?s.defaultMaxListeners:e._maxListeners}function p(e,t,n){if(t)e.call(n);else for(var r=e.length,o=O(e,r),i=0;i0&&a.length>i){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+' "'+String(t)+'" listeners added. Use emitter.setMaxListeners() to increase limit.');u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,"object"===("undefined"==typeof console?"undefined":c(console))&&console.warn&&console.warn("%s: %s",u.name,u.message)}}else a=s[t]=n,++e._eventsCount;return e}function v(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var e=new Array(arguments.length),t=0;t1&&(t=arguments[1]),t instanceof Error)throw t;var u=new Error('Unhandled "error" event. ('+t+")");throw u.context=t,u}if(!(n=s[e]))return!1;var c="function"==typeof n;switch(r=arguments.length){case 1:p(n,c,this);break;case 2:h(n,c,this,arguments[1]);break;case 3:d(n,c,this,arguments[1],arguments[2]);break;case 4:m(n,c,this,arguments[1],arguments[2],arguments[3]);break;default:for(o=new Array(r-1),i=1;i=0;s--)if(n[s]===t||n[s].listener===t){a=n[s].listener,i=s;break}if(i<0)return this;0===i?n.shift():function(e,t){for(var n=t,r=n+1,o=e.length;r=0;i--)this.removeListener(e,t[i]);return this},s.prototype.listeners=function(e){return _(this,e,!0)},s.prototype.rawListeners=function(e){return _(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):w.call(e,t)},s.prototype.listenerCount=w,s.prototype.eventNames=function(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]}},{}],26:[function(e,t,n){var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0});var s=function(e){function t(t){void 0===t&&(t={});var n=e.call(this,(function(e){for(var t,r=[],o=1;o0;this._cbs.onclosetag(this._stack[--e]));this._cbs.onend&&this._cbs.onend()},t.prototype.reset=function(){this._cbs.onreset&&this._cbs.onreset(),this._tokenizer.reset(),this._tagname="",this._attribname="",this._attribs=null,this._stack=[],this._cbs.onparserinit&&this._cbs.onparserinit(this)},t.prototype.parseComplete=function(e){this.reset(),this.end(e)},t.prototype.write=function(e){this._tokenizer.write(e)},t.prototype.end=function(e){this._tokenizer.end(e)},t.prototype.pause=function(){this._tokenizer.pause()},t.prototype.resume=function(){this._tokenizer.resume()},t}(a.EventEmitter);n.Parser=m},{"./Tokenizer":30,events:25}],30:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0});var o=r(e("entities/lib/decode_codepoint")),i=r(e("entities/lib/maps/entities.json")),s=r(e("entities/lib/maps/legacy.json")),a=r(e("entities/lib/maps/xml.json"));function u(e){return" "===e||"\n"===e||"\t"===e||"\f"===e||"\r"===e}function c(e,t,n){var r=e.toLowerCase();return e===r?function(e,o){o===r?e._state=t:(e._state=n,e._index--)}:function(o,i){i===r||i===e?o._state=t:(o._state=n,o._index--)}}function l(e,t){var n=e.toLowerCase();return function(r,o){o===n||o===e?r._state=t:(r._state=3,r._index--)}}var f=c("C",23,16),p=c("D",24,16),h=c("A",25,16),d=c("T",26,16),m=c("A",27,16),g=l("R",34),b=l("I",35),v=l("P",36),y=l("T",37),_=c("R",39,1),w=c("I",40,1),O=c("P",41,1),x=c("T",42,1),S=l("Y",44),C=l("L",45),j=l("E",46),k=c("Y",48,1),A=c("L",49,1),E=c("E",50,1),M=c("#",52,53),N=c("X",55,54),T=function(){function e(e,t){this._state=1,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=1,this._special=1,this._running=!0,this._ended=!1,this._cbs=t,this._xmlMode=!(!e||!e.xmlMode),this._decodeEntities=!(!e||!e.decodeEntities)}return e.prototype.reset=function(){this._state=1,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=1,this._special=1,this._running=!0,this._ended=!1},e.prototype._stateText=function(e){"<"===e?(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._state=2,this._sectionStart=this._index):this._decodeEntities&&1===this._special&&"&"===e&&(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._baseState=1,this._state=51,this._sectionStart=this._index)},e.prototype._stateBeforeTagName=function(e){"/"===e?this._state=5:"<"===e?(this._cbs.ontext(this._getSection()),this._sectionStart=this._index):">"===e||1!==this._special||u(e)?this._state=1:"!"===e?(this._state=15,this._sectionStart=this._index+1):"?"===e?(this._state=17,this._sectionStart=this._index+1):(this._state=this._xmlMode||"s"!==e&&"S"!==e?3:31,this._sectionStart=this._index)},e.prototype._stateInTagName=function(e){("/"===e||">"===e||u(e))&&(this._emitToken("onopentagname"),this._state=8,this._index--)},e.prototype._stateBeforeClosingTagName=function(e){u(e)||(">"===e?this._state=1:1!==this._special?"s"===e||"S"===e?this._state=32:(this._state=1,this._index--):(this._state=6,this._sectionStart=this._index))},e.prototype._stateInClosingTagName=function(e){(">"===e||u(e))&&(this._emitToken("onclosetag"),this._state=7,this._index--)},e.prototype._stateAfterClosingTagName=function(e){">"===e&&(this._state=1,this._sectionStart=this._index+1)},e.prototype._stateBeforeAttributeName=function(e){">"===e?(this._cbs.onopentagend(),this._state=1,this._sectionStart=this._index+1):"/"===e?this._state=4:u(e)||(this._state=9,this._sectionStart=this._index)},e.prototype._stateInSelfClosingTag=function(e){">"===e?(this._cbs.onselfclosingtag(),this._state=1,this._sectionStart=this._index+1):u(e)||(this._state=8,this._index--)},e.prototype._stateInAttributeName=function(e){("="===e||"/"===e||">"===e||u(e))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=10,this._index--)},e.prototype._stateAfterAttributeName=function(e){"="===e?this._state=11:"/"===e||">"===e?(this._cbs.onattribend(),this._state=8,this._index--):u(e)||(this._cbs.onattribend(),this._state=9,this._sectionStart=this._index)},e.prototype._stateBeforeAttributeValue=function(e){'"'===e?(this._state=12,this._sectionStart=this._index+1):"'"===e?(this._state=13,this._sectionStart=this._index+1):u(e)||(this._state=14,this._sectionStart=this._index,this._index--)},e.prototype._stateInAttributeValueDoubleQuotes=function(e){'"'===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=8):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=51,this._sectionStart=this._index)},e.prototype._stateInAttributeValueSingleQuotes=function(e){"'"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=8):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=51,this._sectionStart=this._index)},e.prototype._stateInAttributeValueNoQuotes=function(e){u(e)||">"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=8,this._index--):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=51,this._sectionStart=this._index)},e.prototype._stateBeforeDeclaration=function(e){this._state="["===e?22:"-"===e?18:16},e.prototype._stateInDeclaration=function(e){">"===e&&(this._cbs.ondeclaration(this._getSection()),this._state=1,this._sectionStart=this._index+1)},e.prototype._stateInProcessingInstruction=function(e){">"===e&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=1,this._sectionStart=this._index+1)},e.prototype._stateBeforeComment=function(e){"-"===e?(this._state=19,this._sectionStart=this._index+1):this._state=16},e.prototype._stateInComment=function(e){"-"===e&&(this._state=20)},e.prototype._stateAfterComment1=function(e){this._state="-"===e?21:19},e.prototype._stateAfterComment2=function(e){">"===e?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=1,this._sectionStart=this._index+1):"-"!==e&&(this._state=19)},e.prototype._stateBeforeCdata6=function(e){"["===e?(this._state=28,this._sectionStart=this._index+1):(this._state=16,this._index--)},e.prototype._stateInCdata=function(e){"]"===e&&(this._state=29)},e.prototype._stateAfterCdata1=function(e){this._state="]"===e?30:28},e.prototype._stateAfterCdata2=function(e){">"===e?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=1,this._sectionStart=this._index+1):"]"!==e&&(this._state=28)},e.prototype._stateBeforeSpecial=function(e){"c"===e||"C"===e?this._state=33:"t"===e||"T"===e?this._state=43:(this._state=3,this._index--)},e.prototype._stateBeforeSpecialEnd=function(e){2!==this._special||"c"!==e&&"C"!==e?3!==this._special||"t"!==e&&"T"!==e?this._state=1:this._state=47:this._state=38},e.prototype._stateBeforeScript5=function(e){("/"===e||">"===e||u(e))&&(this._special=2),this._state=3,this._index--},e.prototype._stateAfterScript5=function(e){">"===e||u(e)?(this._special=1,this._state=6,this._sectionStart=this._index-6,this._index--):this._state=1},e.prototype._stateBeforeStyle4=function(e){("/"===e||">"===e||u(e))&&(this._special=3),this._state=3,this._index--},e.prototype._stateAfterStyle4=function(e){">"===e||u(e)?(this._special=1,this._state=6,this._sectionStart=this._index-5,this._index--):this._state=1},e.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+16&&(t=6);t>=2;){var n=this._buffer.substr(e,t);if(Object.prototype.hasOwnProperty.call(s.default,n))return this._emitPartial(s.default[n]),void(this._sectionStart+=t+1);t--}},e.prototype._stateInNamedEntity=function(e){";"===e?(this._parseNamedEntityStrict(),this._sectionStart+1"z")&&(e<"A"||e>"Z")&&(e<"0"||e>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(1!==this._baseState?"="!==e&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},e.prototype._decodeNumericEntity=function(e,t){var n=this._sectionStart+e;if(n!==this._index){var r=this._buffer.substring(n,this._index),i=parseInt(r,t);this._emitPartial(o.default(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},e.prototype._stateInNumericEntity=function(e){";"===e?(this._decodeNumericEntity(2,10),this._sectionStart++):(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},e.prototype._stateInHexEntity=function(e){";"===e?(this._decodeNumericEntity(3,16),this._sectionStart++):(e<"a"||e>"f")&&(e<"A"||e>"F")&&(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},e.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._bufferOffset+=this._index,this._index=0):this._running&&(1===this._state?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._bufferOffset+=this._index,this._index=0):this._sectionStart===this._index?(this._buffer="",this._bufferOffset+=this._index,this._index=0):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},e.prototype.write=function(e){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=e,this._parse()},e.prototype._parse=function(){for(;this._index>1,l=-7,f=n?o-1:0,p=n?-1:1,h=e[t+f];for(f+=p,i=h&(1<<-l)-1,h>>=-l,l+=a;l>0;i=256*i+e[t+f],f+=p,l-=8);for(s=i&(1<<-l)-1,i>>=-l,l+=r;l>0;s=256*s+e[t+f],f+=p,l-=8);if(0===i)i=1-c;else{if(i===u)return s?NaN:1/0*(h?-1:1);s+=Math.pow(2,r),i-=c}return(h?-1:1)*s*Math.pow(2,i-r)},n.write=function(e,t,n,r,o,i){var s,a,u,c=8*i-o-1,l=(1<>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:i-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=l):(s=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-s))<1&&(s--,u*=2),(t+=s+f>=1?p/u:p*Math.pow(2,1-f))*u>=2&&(s++,u/=2),s+f>=l?(a=0,s=l):s+f>=1?(a=(t*u-1)*Math.pow(2,o),s+=f):(a=t*Math.pow(2,f-1)*Math.pow(2,o),s=0));o>=8;e[n+h]=255&a,h+=d,a/=256,o-=8);for(s=s<0;e[n+h]=255&s,h+=d,s/=256,c-=8);e[n+h-d]|=128*m}},{}],33:[function(e,t,n){var r=e("./_getNative")(e("./_root"),"DataView");t.exports=r},{"./_getNative":93,"./_root":130}],34:[function(e,t,n){var r=e("./_hashClear"),o=e("./_hashDelete"),i=e("./_hashGet"),s=e("./_hashHas"),a=e("./_hashSet");function u(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t1?n[i-1]:void 0,a=i>2?n[2]:void 0;for(s=e.length>3&&"function"==typeof s?(i--,s):void 0,a&&o(n[0],n[1],a)&&(s=i<3?void 0:s,i=1),t=Object(t);++r-1&&e%1==0&&e-1}},{"./_assocIndexOf":52}],117:[function(e,t,n){var r=e("./_assocIndexOf");t.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},{"./_assocIndexOf":52}],118:[function(e,t,n){var r=e("./_Hash"),o=e("./_ListCache"),i=e("./_Map");t.exports=function(){this.size=0,this.__data__={hash:new r,map:new(i||o),string:new r}}},{"./_Hash":34,"./_ListCache":35,"./_Map":36}],119:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},{"./_getMapData":92}],120:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e){return r(this,e).get(e)}},{"./_getMapData":92}],121:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e){return r(this,e).has(e)}},{"./_getMapData":92}],122:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},{"./_getMapData":92}],123:[function(e,t,n){var r=e("./_getNative")(Object,"create");t.exports=r},{"./_getNative":93}],124:[function(e,t,n){var r=e("./_overArg")(Object.keys,Object);t.exports=r},{"./_overArg":128}],125:[function(e,t,n){t.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},{}],126:[function(e,t,n){var r=e("./_freeGlobal"),o="object"==c(n)&&n&&!n.nodeType&&n,i=o&&"object"==c(t)&&t&&!t.nodeType&&t,s=i&&i.exports===o&&r.process,a=function(){try{var e=i&&i.require&&i.require("util").types;return e||s&&s.binding&&s.binding("util")}catch(e){}}();t.exports=a},{"./_freeGlobal":89}],127:[function(e,t,n){var r=Object.prototype.toString;t.exports=function(e){return r.call(e)}},{}],128:[function(e,t,n){t.exports=function(e,t){return function(n){return e(t(n))}}},{}],129:[function(e,t,n){var r=e("./_apply"),o=Math.max;t.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var i=arguments,s=-1,a=o(i.length-t,0),u=Array(a);++s0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}},{}],134:[function(e,t,n){var r=e("./_ListCache");t.exports=function(){this.__data__=new r,this.size=0}},{"./_ListCache":35}],135:[function(e,t,n){t.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},{}],136:[function(e,t,n){t.exports=function(e){return this.__data__.get(e)}},{}],137:[function(e,t,n){t.exports=function(e){return this.__data__.has(e)}},{}],138:[function(e,t,n){var r=e("./_ListCache"),o=e("./_Map"),i=e("./_MapCache");t.exports=function(e,t){var n=this.__data__;if(n instanceof r){var s=n.__data__;if(!o||s.length<199)return s.push([e,t]),this.size=++n.size,this;n=this.__data__=new i(s)}return n.set(e,t),this.size=n.size,this}},{"./_ListCache":35,"./_Map":36,"./_MapCache":37}],139:[function(e,t,n){var r=Function.prototype.toString;t.exports=function(e){if(null!=e){try{return r.call(e)}catch(e){}try{return e+""}catch(e){}}return""}},{}],140:[function(e,t,n){var r=e("./_baseClone");t.exports=function(e){return r(e,5)}},{"./_baseClone":56}],141:[function(e,t,n){t.exports=function(e){return function(){return e}}},{}],142:[function(e,t,n){t.exports=function(e,t){return e===t||e!=e&&t!=t}},{}],143:[function(e,t,n){var r=e("./toString"),o=/[\\^$.*+?()[\]{}|]/g,i=RegExp(o.source);t.exports=function(e){return(e=r(e))&&i.test(e)?e.replace(o,"\\$&"):e}},{"./toString":166}],144:[function(e,t,n){t.exports=function(e){return e}},{}],145:[function(e,t,n){var r=e("./_baseIsArguments"),o=e("./isObjectLike"),i=Object.prototype,s=i.hasOwnProperty,a=i.propertyIsEnumerable,u=r(function(){return arguments}())?r:function(e){return o(e)&&s.call(e,"callee")&&!a.call(e,"callee")};t.exports=u},{"./_baseIsArguments":61,"./isObjectLike":154}],146:[function(e,t,n){var r=Array.isArray;t.exports=r},{}],147:[function(e,t,n){var r=e("./isFunction"),o=e("./isLength");t.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},{"./isFunction":150,"./isLength":151}],148:[function(e,t,n){var r=e("./isArrayLike"),o=e("./isObjectLike");t.exports=function(e){return o(e)&&r(e)}},{"./isArrayLike":147,"./isObjectLike":154}],149:[function(e,t,n){var r=e("./_root"),o=e("./stubFalse"),i="object"==c(n)&&n&&!n.nodeType&&n,s=i&&"object"==c(t)&&t&&!t.nodeType&&t,a=s&&s.exports===i?r.Buffer:void 0,u=(a?a.isBuffer:void 0)||o;t.exports=u},{"./_root":130,"./stubFalse":164}],150:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./isObject");t.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},{"./_baseGetTag":60,"./isObject":153}],151:[function(e,t,n){t.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},{}],152:[function(e,t,n){var r=e("./_baseIsMap"),o=e("./_baseUnary"),i=e("./_nodeUtil"),s=i&&i.isMap,a=s?o(s):r;t.exports=a},{"./_baseIsMap":62,"./_baseUnary":74,"./_nodeUtil":126}],153:[function(e,t,n){t.exports=function(e){var t=c(e);return null!=e&&("object"==t||"function"==t)}},{}],154:[function(e,t,n){t.exports=function(e){return null!=e&&"object"==c(e)}},{}],155:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./_getPrototype"),i=e("./isObjectLike"),s=Function.prototype,a=Object.prototype,u=s.toString,c=a.hasOwnProperty,l=u.call(Object);t.exports=function(e){if(!i(e)||"[object Object]"!=r(e))return!1;var t=o(e);if(null===t)return!0;var n=c.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&u.call(n)==l}},{"./_baseGetTag":60,"./_getPrototype":94,"./isObjectLike":154}],156:[function(e,t,n){var r=e("./_baseIsSet"),o=e("./_baseUnary"),i=e("./_nodeUtil"),s=i&&i.isSet,a=s?o(s):r;t.exports=a},{"./_baseIsSet":64,"./_baseUnary":74,"./_nodeUtil":126}],157:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./isArray"),i=e("./isObjectLike");t.exports=function(e){return"string"==typeof e||!o(e)&&i(e)&&"[object String]"==r(e)}},{"./_baseGetTag":60,"./isArray":146,"./isObjectLike":154}],158:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./isObjectLike");t.exports=function(e){return"symbol"==c(e)||o(e)&&"[object Symbol]"==r(e)}},{"./_baseGetTag":60,"./isObjectLike":154}],159:[function(e,t,n){var r=e("./_baseIsTypedArray"),o=e("./_baseUnary"),i=e("./_nodeUtil"),s=i&&i.isTypedArray,a=s?o(s):r;t.exports=a},{"./_baseIsTypedArray":65,"./_baseUnary":74,"./_nodeUtil":126}],160:[function(e,t,n){var r=e("./_arrayLikeKeys"),o=e("./_baseKeys"),i=e("./isArrayLike");t.exports=function(e){return i(e)?r(e):o(e)}},{"./_arrayLikeKeys":47,"./_baseKeys":66,"./isArrayLike":147}],161:[function(e,t,n){var r=e("./_arrayLikeKeys"),o=e("./_baseKeysIn"),i=e("./isArrayLike");t.exports=function(e){return i(e)?r(e,!0):o(e)}},{"./_arrayLikeKeys":47,"./_baseKeysIn":67,"./isArrayLike":147}],162:[function(e,t,n){var r=e("./_baseMerge"),o=e("./_createAssigner")((function(e,t,n,o){r(e,t,n,o)}));t.exports=o},{"./_baseMerge":68,"./_createAssigner":86}],163:[function(e,t,n){t.exports=function(){return[]}},{}],164:[function(e,t,n){t.exports=function(){return!1}},{}],165:[function(e,t,n){var r=e("./_copyObject"),o=e("./keysIn");t.exports=function(e){return r(e,o(e))}},{"./_copyObject":82,"./keysIn":161}],166:[function(e,t,n){var r=e("./_baseToString");t.exports=function(e){return null==e?"":r(e)}},{"./_baseToString":73}],167:[function(e,t,n){var r,o;r=this,o=function(){return function(e){function t(e){return" "===e||"\t"===e||"\n"===e||"\f"===e||"\r"===e}function n(t){var n,r=t.exec(e.substring(m));if(r)return n=r[0],m+=n.length,n}for(var r,o,i,s,a,u=e.length,c=/^[ \t\n\r\u000c]+/,l=/^[, \t\n\r\u000c]+/,f=/^[^ \t\n\r\u000c]+/,p=/[,]+$/,h=/^\d+$/,d=/^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/,m=0,g=[];;){if(n(l),m>=u)return g;r=n(f),o=[],","===r.slice(-1)?(r=r.replace(p,""),v()):b()}function b(){for(n(c),i="",s="in descriptor";;){if(a=e.charAt(m),"in descriptor"===s)if(t(a))i&&(o.push(i),i="",s="after descriptor");else{if(","===a)return m+=1,i&&o.push(i),void v();if("("===a)i+=a,s="in parens";else{if(""===a)return i&&o.push(i),void v();i+=a}}else if("in parens"===s)if(")"===a)i+=a,s="in descriptor";else{if(""===a)return o.push(i),void v();i+=a}else if("after descriptor"===s)if(t(a));else{if(""===a)return void v();s="in descriptor",m-=1}m+=1}}function v(){var t,n,i,s,a,u,c,l,f,p=!1,m={};for(s=0;s=0;r--){var o=e[r];"."===o?e.splice(r,1):".."===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!o;i--){var s=i>=0?arguments[i]:e.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(n=s+"/"+n,o="/"===s.charAt(0))}return(o?"/":"")+(n=t(r(n.split("/"),(function(e){return!!e})),!o).join("/"))||"."},n.normalize=function(e){var i=n.isAbsolute(e),s="/"===o(e,-1);return(e=t(r(e.split("/"),(function(e){return!!e})),!i).join("/"))||i||(e="."),e&&s&&(e+="/"),(i?"/":"")+e},n.isAbsolute=function(e){return"/"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},n.relative=function(e,t){function r(e){for(var t=0;t=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var o=r(e.split("/")),i=r(t.split("/")),s=Math.min(o.length,i.length),a=s,u=0;u=1;--i)if(47===(t=e.charCodeAt(i))){if(!o){r=i;break}}else o=!1;return-1===r?n?"/":".":n&&1===r?"/":e.slice(0,r)},n.basename=function(e,t){var n=function(e){"string"!=typeof e&&(e+="");var t,n=0,r=-1,o=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!o){n=t+1;break}}else-1===r&&(o=!1,r=t+1);return-1===r?"":e.slice(n,r)}(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},n.extname=function(e){"string"!=typeof e&&(e+="");for(var t=-1,n=0,r=-1,o=!0,i=0,s=e.length-1;s>=0;--s){var a=e.charCodeAt(s);if(47!==a)-1===r&&(o=!1,r=s+1),46===a?-1===t?t=s:1!==i&&(i=1):-1!==t&&(i=-1);else if(!o){n=s+1;break}}return-1===t||-1===r||0===i||1===i&&t===r-1&&t===n+1?"":e.slice(t,r)};var o="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,e("_process"))},{_process:193}],169:[function(e,t,n){var r;n.__esModule=!0,n.default=void 0;var o=function(e){var t,n;function r(t){var n;return(n=e.call(this,t)||this).type="atrule",n}n=e,(t=r).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var o=r.prototype;return o.append=function(){var t;this.nodes||(this.nodes=[]);for(var n=arguments.length,r=new Array(n),o=0;o=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e&&(this.indexes[n]=t-1);return this},p.removeAll=function(){for(var e,t=s(this.nodes);!(e=t()).done;)e.value.parent=void 0;return this.nodes=[],this},p.replaceValues=function(e,t,n){return n||(n=t,t={}),this.walkDecls((function(r){t.props&&-1===t.props.indexOf(r.prop)||t.fast&&-1===r.value.indexOf(t.fast)||(r.value=r.value.replace(e,n))})),this},p.every=function(e){return this.nodes.every(e)},p.some=function(e){return this.nodes.some(e)},p.index=function(e){return"number"==typeof e?e:this.nodes.indexOf(e)},p.normalize=function(t,n){var i=this;if("string"==typeof t)t=function e(t){return t.map((function(t){return t.nodes&&(t.nodes=e(t.nodes)),delete t.source,t}))}(e("./parse")(t).nodes);else if(Array.isArray(t))for(var a,u=s(t=t.slice(0));!(a=u()).done;){var c=a.value;c.parent&&c.parent.removeChild(c,"ignore")}else if("root"===t.type)for(var l,f=s(t=t.nodes.slice(0));!(l=f()).done;){var p=l.value;p.parent&&p.parent.removeChild(p,"ignore")}else if(t.type)t=[t];else if(t.prop){if(void 0===t.value)throw new Error("Value field is missed in node creation");"string"!=typeof t.value&&(t.value=String(t.value)),t=[new r.default(t)]}else if(t.selector)t=[new(e("./rule"))(t)];else if(t.name)t=[new(e("./at-rule"))(t)];else{if(!t.text)throw new Error("Unknown node type in node creation");t=[new o.default(t)]}return t.map((function(e){return e.parent&&e.parent.removeChild(e),void 0===e.raws.before&&n&&void 0!==n.raws.before&&(e.raws.before=n.raws.before.replace(/[^\s]/g,"")),e.parent=i,e}))},c=a,(l=[{key:"first",get:function(){if(this.nodes)return this.nodes[0]}},{key:"last",get:function(){if(this.nodes)return this.nodes[this.nodes.length-1]}}])&&u(c.prototype,l),f&&u(c,f),a}(i(e("./node")).default);n.default=c,t.exports=n.default},{"./at-rule":169,"./comment":170,"./declaration":173,"./node":178,"./parse":179,"./rule":186}],172:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=s(e("supports-color")),o=s(e("chalk")),i=s(e("./terminal-highlight"));function s(e){return e&&e.__esModule?e:{default:e}}function a(e){var t="function"==typeof Map?new Map:void 0;return(a=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return u(e,arguments,f(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),l(r,e)})(e)}function u(e,t,n){return(u=c()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&l(o,n.prototype),o}).apply(null,arguments)}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function f(e){return(f=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}var p=function(e){var t,n;function s(t,n,r,o,i,a){var u;return(u=e.call(this,t)||this).name="CssSyntaxError",u.reason=t,i&&(u.file=i),o&&(u.source=o),a&&(u.plugin=a),void 0!==n&&void 0!==r&&(u.line=n,u.column=r),u.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(u),s),u}n=e,(t=s).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var a=s.prototype;return a.setMessage=function(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",void 0!==this.line&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason},a.showSourceCode=function(e){var t=this;if(!this.source)return"";var n=this.source;i.default&&(void 0===e&&(e=r.default.stdout),e&&(n=(0,i.default)(n)));var s=n.split(/\r?\n/),a=Math.max(this.line-3,0),u=Math.min(this.line+2,s.length),c=String(u).length;function l(t){return e&&o.default.red?o.default.red.bold(t):t}function f(t){return e&&o.default.gray?o.default.gray(t):t}return s.slice(a,u).map((function(e,n){var r=a+1+n,o=" "+(" "+r).slice(-c)+" | ";if(r===t.line){var i=f(o.replace(/\d/g," "))+e.slice(0,t.column-1).replace(/[^\t]/g," ");return l(">")+f(o)+e+"\n "+i+l("^")}return" "+f(o)+e})).join("\n")},a.toString=function(){var e=this.showSourceCode();return e&&(e="\n\n"+e+"\n"),this.name+": "+this.message+e},s}(a(Error));n.default=p,t.exports=n.default},{"./terminal-highlight":2,chalk:2,"supports-color":2}],173:[function(e,t,n){var r;n.__esModule=!0,n.default=void 0;var o=function(e){var t,n;function r(t){var n;return(n=e.call(this,t)||this).type="decl",n}return n=e,(t=r).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,r}(((r=e("./node"))&&r.__esModule?r:{default:r}).default);n.default=o,t.exports=n.default},{"./node":178}],174:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=s(e("path")),o=s(e("./css-syntax-error")),i=s(e("./previous-map"));function s(e){return e&&e.__esModule?e:{default:e}}function a(e,t){for(var n=0;n"),this.map&&(this.map.file=this.from)}var t,n,s,l=e.prototype;return l.error=function(e,t,n,r){var i;void 0===r&&(r={});var s=this.origin(t,n);return(i=s?new o.default(e,s.line,s.column,s.source,s.file,r.plugin):new o.default(e,t,n,this.css,this.file,r.plugin)).input={line:t,column:n,source:this.css},this.file&&(i.input.file=this.file),i},l.origin=function(e,t){if(!this.map)return!1;var n=this.map.consumer(),r=n.originalPositionFor({line:e,column:t});if(!r.source)return!1;var o={file:this.mapResolve(r.source),line:r.line,column:r.column},i=n.sourceContentFor(r.source);return i&&(o.source=i),o},l.mapResolve=function(e){return/^\w+:\/\//.test(e)?e:r.default.resolve(this.map.consumer().sourceRoot||".",e)},t=e,(n=[{key:"from",get:function(){return this.file||this.id}}])&&a(t.prototype,n),s&&a(t,s),e}();n.default=l,t.exports=n.default},{"./css-syntax-error":172,"./previous-map":182,path:168}],175:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o=l(e("./map-generator")),i=l(e("./stringify")),s=l(e("./warn-once")),a=l(e("./result")),u=l(e("./parse"));function l(e){return e&&e.__esModule?e:{default:e}}function f(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return p(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?p(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function p(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nparseInt(a[1]))&&console.error("Unknown error from PostCSS plugin. Your current PostCSS version is "+i+", but "+n+" uses "+o+". Perhaps this is the source of the error below.")}}else e.plugin=t.postcssPlugin,e.setMessage()}catch(e){console&&console.error&&console.error(e)}},p.asyncTick=function(e,t){var n=this;if(this.plugin>=this.processor.plugins.length)return this.processed=!0,e();try{var r=this.processor.plugins[this.plugin],o=this.run(r);this.plugin+=1,d(o)?o.then((function(){n.asyncTick(e,t)})).catch((function(e){n.handleError(e,r),n.processed=!0,t(e)})):this.asyncTick(e,t)}catch(e){this.processed=!0,t(e)}},p.async=function(){var e=this;return this.processed?new Promise((function(t,n){e.error?n(e.error):t(e.stringify())})):(this.processing||(this.processing=new Promise((function(t,n){if(e.error)return n(e.error);e.plugin=0,e.asyncTick(t,n)})).then((function(){return e.processed=!0,e.stringify()}))),this.processing)},p.sync=function(){if(this.processed)return this.result;if(this.processed=!0,this.processing)throw new Error("Use process(css).then(cb) to work with async plugins");if(this.error)throw this.error;for(var e,t=f(this.result.processor.plugins);!(e=t()).done;){var n=e.value;if(d(this.run(n)))throw new Error("Use process(css).then(cb) to work with async plugins")}return this.result},p.run=function(e){this.result.lastPlugin=e;try{return e(this.result.root,this.result)}catch(t){throw this.handleError(t,e),t}},p.stringify=function(){if(this.stringified)return this.result;this.stringified=!0,this.sync();var e=this.result.opts,t=i.default;e.syntax&&(t=e.syntax.stringify),e.stringifier&&(t=e.stringifier),t.stringify&&(t=t.stringify);var n=new o.default(t,this.result.root,this.result.opts).generate();return this.result.css=n[0],this.result.map=n[1],this.result},t=e,(n=[{key:"processor",get:function(){return this.result.processor}},{key:"opts",get:function(){return this.result.opts}},{key:"css",get:function(){return this.stringify().css}},{key:"content",get:function(){return this.stringify().content}},{key:"map",get:function(){return this.stringify().map}},{key:"root",get:function(){return this.sync().root}},{key:"messages",get:function(){return this.sync().messages}}])&&h(t.prototype,n),l&&h(t,l),e}();n.default=m,t.exports=n.default}).call(this,e("_process"))},{"./map-generator":177,"./parse":179,"./result":184,"./stringify":188,"./warn-once":191,_process:193}],176:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r={split:function(e,t,n){for(var r=[],o="",i=!1,s=0,a=!1,u=!1,c=0;c0&&(s-=1):0===s&&-1!==t.indexOf(l)&&(i=!0),i?(""!==o&&r.push(o.trim()),o="",i=!1):o+=l}return(n||""!==o)&&r.push(o.trim()),r},space:function(e){return r.split(e,[" ","\n","\t"])},comma:function(e){return r.split(e,[","],!0)}},o=r;n.default=o,t.exports=n.default},{}],177:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o=s(e("source-map")),i=s(e("path"));function s(e){return e&&e.__esModule?e:{default:e}}function a(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return u(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0},t.previous=function(){var e=this;return this.previousMaps||(this.previousMaps=[],this.root.walk((function(t){if(t.source&&t.source.input.map){var n=t.source.input.map;-1===e.previousMaps.indexOf(n)&&e.previousMaps.push(n)}}))),this.previousMaps},t.isInline=function(){if(void 0!==this.mapOpts.inline)return this.mapOpts.inline;var e=this.mapOpts.annotation;return(void 0===e||!0===e)&&(!this.previous().length||this.previous().some((function(e){return e.inline})))},t.isSourcesContent=function(){return void 0!==this.mapOpts.sourcesContent?this.mapOpts.sourcesContent:!this.previous().length||this.previous().some((function(e){return e.withContent()}))},t.clearAnnotation=function(){if(!1!==this.mapOpts.annotation)for(var e,t=this.root.nodes.length-1;t>=0;t--)"comment"===(e=this.root.nodes[t]).type&&0===e.text.indexOf("# sourceMappingURL=")&&this.root.removeChild(t)},t.setSourcesContent=function(){var e=this,t={};this.root.walk((function(n){if(n.source){var r=n.source.input.from;if(r&&!t[r]){t[r]=!0;var o=e.relative(r);e.map.setSourceContent(o,n.source.input.css)}}}))},t.applyPrevMaps=function(){for(var e,t=a(this.previous());!(e=t()).done;){var n=e.value,r=this.relative(n.file),s=n.root||i.default.dirname(n.file),u=void 0;!1===this.mapOpts.sourcesContent?(u=new o.default.SourceMapConsumer(n.text)).sourcesContent&&(u.sourcesContent=u.sourcesContent.map((function(){return null}))):u=n.consumer(),this.map.applySourceMap(u,r,this.relative(s))}},t.isAnnotation=function(){return!!this.isInline()||(void 0!==this.mapOpts.annotation?this.mapOpts.annotation:!this.previous().length||this.previous().some((function(e){return e.annotation})))},t.toBase64=function(e){return r?r.from(e).toString("base64"):window.btoa(unescape(encodeURIComponent(e)))},t.addAnnotation=function(){var e;e=this.isInline()?"data:application/json;base64,"+this.toBase64(this.map.toString()):"string"==typeof this.mapOpts.annotation?this.mapOpts.annotation:this.outputFile()+".map";var t="\n";-1!==this.css.indexOf("\r\n")&&(t="\r\n"),this.css+=t+"/*# sourceMappingURL="+e+" */"},t.outputFile=function(){return this.opts.to?this.relative(this.opts.to):this.opts.from?this.relative(this.opts.from):"to.css"},t.generateMap=function(){return this.generateString(),this.isSourcesContent()&&this.setSourcesContent(),this.previous().length>0&&this.applyPrevMaps(),this.isAnnotation()&&this.addAnnotation(),this.isInline()?[this.css]:[this.css,this.map]},t.relative=function(e){if(0===e.indexOf("<"))return e;if(/^\w+:\/\//.test(e))return e;var t=this.opts.to?i.default.dirname(this.opts.to):".";return"string"==typeof this.mapOpts.annotation&&(t=i.default.dirname(i.default.resolve(t,this.mapOpts.annotation))),e=i.default.relative(t,e),"\\"===i.default.sep?e.replace(/\\/g,"/"):e},t.sourcePath=function(e){return this.mapOpts.from?this.mapOpts.from:this.relative(e.source.input.from)},t.generateString=function(){var e=this;this.css="",this.map=new o.default.SourceMapGenerator({file:this.outputFile()});var t,n,r=1,i=1;this.stringify(this.root,(function(o,s,a){if(e.css+=o,s&&"end"!==a&&(s.source&&s.source.start?e.map.addMapping({source:e.sourcePath(s),generated:{line:r,column:i-1},original:{line:s.source.start.line,column:s.source.start.column-1}}):e.map.addMapping({source:"",original:{line:1,column:0},generated:{line:r,column:i-1}})),(t=o.match(/\n/g))?(r+=t.length,n=o.lastIndexOf("\n"),i=o.length-n):i+=o.length,s&&"start"!==a){var u=s.parent||{raws:{}};("decl"!==s.type||s!==u.last||u.raws.semicolon)&&(s.source&&s.source.end?e.map.addMapping({source:e.sourcePath(s),generated:{line:r,column:i-2},original:{line:s.source.end.line,column:s.source.end.column-1}}):e.map.addMapping({source:"",original:{line:1,column:0},generated:{line:r,column:i-1}}))}}))},t.generate=function(){if(this.clearAnnotation(),this.isMap())return this.generateMap();var e="";return this.stringify(this.root,(function(t){e+=t})),[e]},e}();n.default=c,t.exports=n.default}).call(this,e("buffer").Buffer)},{buffer:3,path:168,"source-map":208}],178:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o=a(e("./css-syntax-error")),i=a(e("./stringifier")),s=a(e("./stringify"));function a(e){return e&&e.__esModule?e:{default:e}}var u=function(){function e(e){if(void 0===e&&(e={}),this.raws={},"production"!==r.env.NODE_ENV&&"object"!==c(e)&&void 0!==e)throw new Error("PostCSS nodes constructor accepts object, not "+JSON.stringify(e));for(var t in e)this[t]=e[t]}var t=e.prototype;return t.error=function(e,t){if(void 0===t&&(t={}),this.source){var n=this.positionBy(t);return this.source.input.error(e,n.line,n.column,t)}return new o.default(e)},t.warn=function(e,t,n){var r={node:this};for(var o in n)r[o]=n[o];return e.warn(t,r)},t.remove=function(){return this.parent&&this.parent.removeChild(this),this.parent=void 0,this},t.toString=function(e){void 0===e&&(e=s.default),e.stringify&&(e=e.stringify);var t="";return e(this,(function(e){t+=e})),t},t.clone=function(e){void 0===e&&(e={});var t=function e(t,n){var r=new t.constructor;for(var o in t)if(t.hasOwnProperty(o)){var i=t[o],s=c(i);"parent"===o&&"object"===s?n&&(r[o]=n):"source"===o?r[o]=i:i instanceof Array?r[o]=i.map((function(t){return e(t,r)})):("object"===s&&null!==i&&(i=e(i)),r[o]=i)}return r}(this);for(var n in e)t[n]=e[n];return t},t.cloneBefore=function(e){void 0===e&&(e={});var t=this.clone(e);return this.parent.insertBefore(this,t),t},t.cloneAfter=function(e){void 0===e&&(e={});var t=this.clone(e);return this.parent.insertAfter(this,t),t},t.replaceWith=function(){if(this.parent){for(var e=arguments.length,t=new Array(e),n=0;n0&&this.unclosedBracket(o),t&&r){for(;s.length&&("space"===(a=s[s.length-1][0])||"comment"===a);)this.tokenizer.back(s.pop());this.decl(s)}else this.unknownWord(s)},t.rule=function(e){e.pop();var t=new u.default;this.init(t,e[0][2],e[0][3]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t},t.decl=function(e){var t=new r.default;this.init(t);var n,o=e[e.length-1];for(";"===o[0]&&(this.semicolon=!0,e.pop()),o[4]?t.source.end={line:o[4],column:o[5]}:t.source.end={line:o[2],column:o[3]};"word"!==e[0][0];)1===e.length&&this.unknownWord(e),t.raws.before+=e.shift()[1];for(t.source.start={line:e[0][2],column:e[0][3]},t.prop="";e.length;){var i=e[0][0];if(":"===i||"space"===i||"comment"===i)break;t.prop+=e.shift()[1]}for(t.raws.between="";e.length;){if(":"===(n=e.shift())[0]){t.raws.between+=n[1];break}"word"===n[0]&&/\w/.test(n[1])&&this.unknownWord([n]),t.raws.between+=n[1]}"_"!==t.prop[0]&&"*"!==t.prop[0]||(t.raws.before+=t.prop[0],t.prop=t.prop.slice(1)),t.raws.between+=this.spacesAndCommentsFromStart(e),this.precheckMissedSemicolon(e);for(var s=e.length-1;s>0;s--){if("!important"===(n=e[s])[1].toLowerCase()){t.important=!0;var a=this.stringFrom(e,s);" !important"!==(a=this.spacesFromEnd(e)+a)&&(t.raws.important=a);break}if("important"===n[1].toLowerCase()){for(var u=e.slice(0),c="",l=s;l>0;l--){var f=u[l][0];if(0===c.trim().indexOf("!")&&"space"!==f)break;c=u.pop()[1]+c}0===c.trim().indexOf("!")&&(t.important=!0,t.raws.important=c,e=u)}if("space"!==n[0]&&"comment"!==n[0])break}this.raw(t,"value",e),-1!==t.value.indexOf(":")&&this.checkMissedSemicolon(e)},t.atrule=function(e){var t,n,r=new s.default;r.name=e[1].slice(1),""===r.name&&this.unnamedAtrule(r,e),this.init(r,e[2],e[3]);for(var o=!1,i=!1,a=[];!this.tokenizer.endOfFile();){if(";"===(e=this.tokenizer.nextToken())[0]){r.source.end={line:e[2],column:e[3]},this.semicolon=!0;break}if("{"===e[0]){i=!0;break}if("}"===e[0]){if(a.length>0){for(t=a[n=a.length-1];t&&"space"===t[0];)t=a[--n];t&&(r.source.end={line:t[4],column:t[5]})}this.end(e);break}if(a.push(e),this.tokenizer.endOfFile()){o=!0;break}}r.raws.between=this.spacesAndCommentsFromEnd(a),a.length?(r.raws.afterName=this.spacesAndCommentsFromStart(a),this.raw(r,"params",a),o&&(e=a[a.length-1],r.source.end={line:e[4],column:e[5]},this.spaces=r.raws.between,r.raws.between="")):(r.raws.afterName="",r.params=""),i&&(r.nodes=[],this.current=r)},t.end=function(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end={line:e[2],column:e[3]},this.current=this.current.parent):this.unexpectedClose(e)},t.endFile=function(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces},t.freeSemicolon=function(e){if(this.spaces+=e[1],this.current.nodes){var t=this.current.nodes[this.current.nodes.length-1];t&&"rule"===t.type&&!t.raws.ownSemicolon&&(t.raws.ownSemicolon=this.spaces,this.spaces="")}},t.init=function(e,t,n){this.current.push(e),e.source={start:{line:t,column:n},input:this.input},e.raws.before=this.spaces,this.spaces="","comment"!==e.type&&(this.semicolon=!1)},t.raw=function(e,t,n){for(var r,o,i,s,a=n.length,u="",c=!0,l=/^([.|#])?([\w])+/i,f=0;f=0&&("space"===(n=e[o])[0]||2!==(r+=1));o--);throw this.input.error("Missed semicolon",n[2],n[3])}},e}();n.default=l,t.exports=n.default},{"./at-rule":169,"./comment":170,"./declaration":173,"./root":185,"./rule":186,"./tokenize":189}],181:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=h(e("./declaration")),o=h(e("./processor")),i=h(e("./stringify")),s=h(e("./comment")),a=h(e("./at-rule")),u=h(e("./vendor")),c=h(e("./parse")),l=h(e("./list")),f=h(e("./rule")),p=h(e("./root"));function h(e){return e&&e.__esModule?e:{default:e}}function d(){for(var e=arguments.length,t=new Array(e),n=0;n0)},t.startWith=function(e,t){return!!e&&e.substr(0,t.length)===t},t.getAnnotationURL=function(e){return e.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//)[1].trim()},t.loadAnnotation=function(e){var t=e.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//gm);if(t&&t.length>0){var n=t[t.length-1];n&&(this.annotation=this.getAnnotationURL(n))}},t.decodeInline=function(e){var t,n="data:application/json,";if(this.startWith(e,n))return decodeURIComponent(e.substr(n.length));if(/^data:application\/json;charset=utf-?8;base64,/.test(e)||/^data:application\/json;base64,/.test(e))return t=e.substr(RegExp.lastMatch.length),r?r.from(t,"base64").toString():window.atob(t);var o=e.match(/data:application\/json;([^,]+),/)[1];throw new Error("Unsupported source map encoding "+o)},t.loadMap=function(e,t){if(!1===t)return!1;if(t){if("string"==typeof t)return t;if("function"==typeof t){var n=t(e);if(n&&s.default.existsSync&&s.default.existsSync(n))return s.default.readFileSync(n,"utf-8").toString().trim();throw new Error("Unable to load previous source map: "+n.toString())}if(t instanceof o.default.SourceMapConsumer)return o.default.SourceMapGenerator.fromSourceMap(t).toString();if(t instanceof o.default.SourceMapGenerator)return t.toString();if(this.isMap(t))return JSON.stringify(t);throw new Error("Unsupported previous source map format: "+t.toString())}if(this.inline)return this.decodeInline(this.annotation);if(this.annotation){var r=this.annotation;return e&&(r=i.default.join(i.default.dirname(e),r)),this.root=i.default.dirname(r),!(!s.default.existsSync||!s.default.existsSync(r))&&s.default.readFileSync(r,"utf-8").toString().trim()}},t.isMap=function(e){return"object"===c(e)&&("string"==typeof e.mappings||"string"==typeof e._mappings)},e}();n.default=u,t.exports=n.default}).call(this,e("buffer").Buffer)},{buffer:3,fs:2,path:168,"source-map":208}],183:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o,i=(o=e("./lazy-result"))&&o.__esModule?o:{default:o};function s(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?a(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&(this.nodes[1].raws.before=this.nodes[r].raws.before),t.prototype.removeChild.call(this,e)},s.normalize=function(e,n,r){var i=t.prototype.normalize.call(this,e);if(n)if("prepend"===r)this.nodes.length>1?n.raws.before=this.nodes[1].raws.before:delete n.raws.before;else if(this.first!==n)for(var s,a=o(i);!(s=a()).done;)s.value.raws.before=n.raws.before;return i},s.toResult=function(t){return void 0===t&&(t={}),new(e("./lazy-result"))(new(e("./processor")),this,t).stringify()},i}(((r=e("./container"))&&r.__esModule?r:{default:r}).default);n.default=s,t.exports=n.default},{"./container":171,"./lazy-result":175,"./processor":183}],186:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=i(e("./container")),o=i(e("./list"));function i(e){return e&&e.__esModule?e:{default:e}}function s(e,t){for(var n=0;n0&&"comment"===e.nodes[t].type;)t-=1;for(var n=this.raw(e,"semicolon"),r=0;r0&&void 0!==e.raws.after)return-1!==(t=e.raws.after).indexOf("\n")&&(t=t.replace(/[^\n]+$/,"")),!1})),t&&(t=t.replace(/[^\s]/g,"")),t},t.rawBeforeOpen=function(e){var t;return e.walk((function(e){if("decl"!==e.type&&void 0!==(t=e.raws.between))return!1})),t},t.rawColon=function(e){var t;return e.walkDecls((function(e){if(void 0!==e.raws.between)return t=e.raws.between.replace(/[^\s:]/g,""),!1})),t},t.beforeAfter=function(e,t){var n;n="decl"===e.type?this.raw(e,null,"beforeDecl"):"comment"===e.type?this.raw(e,null,"beforeComment"):"before"===t?this.raw(e,null,"beforeRule"):this.raw(e,null,"beforeClose");for(var r=e.parent,o=0;r&&"root"!==r.type;)o+=1,r=r.parent;if(-1!==n.indexOf("\n")){var i=this.raw(e,null,"indent");if(i.length)for(var s=0;s=F)){var t=!!e&&e.ignoreUnclosed;switch(((n=B.charCodeAt(z))===a||n===c||n===f&&B.charCodeAt(z+1)!==a)&&(q=z,H+=1),n){case a:case u:case l:case f:case c:j=z;do{j+=1,(n=B.charCodeAt(j))===a&&(q=j,H+=1)}while(n===u||n===a||n===l||n===f||n===c);V=["space",B.slice(z,j)],z=j-1;break;case p:case h:case g:case b:case _:case v:case m:var Y=String.fromCharCode(n);V=[Y,Y,H,z-q];break;case d:if(I=G.length?G.pop()[1]:"",D=B.charCodeAt(z+1),"url"===I&&D!==r&&D!==o&&D!==u&&D!==a&&D!==l&&D!==c&&D!==f){j=z;do{if(L=!1,-1===(j=B.indexOf(")",j+1))){if(U||t){j=z;break}W("bracket")}for(R=j;B.charCodeAt(R-1)===i;)R-=1,L=!L}while(L);V=["brackets",B.slice(z,j+1),H,z-q,H,j-q],z=j}else j=B.indexOf(")",z+1),M=B.slice(z,j+1),-1===j||S.test(M)?V=["(","(",H,z-q]:(V=["brackets",M,H,z-q,H,j-q],z=j);break;case r:case o:k=n===r?"'":'"',j=z;do{if(L=!1,-1===(j=B.indexOf(k,j+1))){if(U||t){j=z+1;break}W("string")}for(R=j;B.charCodeAt(R-1)===i;)R-=1,L=!L}while(L);M=B.slice(z,j+1),A=M.split("\n"),(E=A.length-1)>0?(T=H+E,P=j-A[E].length):(T=H,P=q),V=["string",B.slice(z,j+1),H,z-q,T,j-P],q=P,H=T,z=j;break;case w:O.lastIndex=z+1,O.test(B),j=0===O.lastIndex?B.length-1:O.lastIndex-2,V=["at-word",B.slice(z,j+1),H,z-q,H,j-q],z=j;break;case i:for(j=z,N=!0;B.charCodeAt(j+1)===i;)j+=1,N=!N;if(n=B.charCodeAt(j+1),N&&n!==s&&n!==u&&n!==a&&n!==l&&n!==f&&n!==c&&(j+=1,C.test(B.charAt(j)))){for(;C.test(B.charAt(j+1));)j+=1;B.charCodeAt(j+1)===u&&(j+=1)}V=["word",B.slice(z,j+1),H,z-q,H,j-q],z=j;break;default:n===s&&B.charCodeAt(z+1)===y?(0===(j=B.indexOf("*/",z+2)+1)&&(U||t?j=B.length:W("comment")),M=B.slice(z,j+1),A=M.split("\n"),(E=A.length-1)>0?(T=H+E,P=j-A[E].length):(T=H,P=q),V=["comment",M,H,z-q,T,j-P],q=P,H=T,z=j):(x.lastIndex=z+1,x.test(B),j=0===x.lastIndex?B.length-1:x.lastIndex-2,V=["word",B.slice(z,j+1),H,z-q,H,j-q],G.push(V),z=j)}return z++,V}},endOfFile:function(){return 0===$.length&&z>=F},position:function(){return z}}};var r="'".charCodeAt(0),o='"'.charCodeAt(0),i="\\".charCodeAt(0),s="/".charCodeAt(0),a="\n".charCodeAt(0),u=" ".charCodeAt(0),c="\f".charCodeAt(0),l="\t".charCodeAt(0),f="\r".charCodeAt(0),p="[".charCodeAt(0),h="]".charCodeAt(0),d="(".charCodeAt(0),m=")".charCodeAt(0),g="{".charCodeAt(0),b="}".charCodeAt(0),v=";".charCodeAt(0),y="*".charCodeAt(0),_=":".charCodeAt(0),w="@".charCodeAt(0),O=/[ \n\t\r\f{}()'"\\;/[\]#]/g,x=/[ \n\t\r\f(){}:;@!'"\\\][#]|\/(?=\*)/g,S=/.[\\/("'\n]/,C=/[a-f0-9]/i;t.exports=n.default},{}],190:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r={prefix:function(e){var t=e.match(/^(-\w+-)/);return t?t[0]:""},unprefixed:function(e){return e.replace(/^-\w+-/,"")}};n.default=r,t.exports=n.default},{}],191:[function(e,t,n){n.__esModule=!0,n.default=function(e){r[e]||(r[e]=!0,"undefined"!=typeof console&&console.warn&&console.warn(e))};var r={};t.exports=n.default},{}],192:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=function(){function e(e,t){if(void 0===t&&(t={}),this.type="warning",this.text=e,t.node&&t.node.source){var n=t.node.positionBy(t);this.line=n.line,this.column=n.column}for(var r in t)this[r]=t[r]}return e.prototype.toString=function(){return this.node?this.node.error(this.text,{plugin:this.plugin,index:this.index,word:this.word}).message:this.plugin?this.plugin+": "+this.text:this.text},e}();n.default=r,t.exports=n.default},{}],193:[function(e,t,n){var r,o,i=t.exports={};function s(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function u(e){if(r===setTimeout)return setTimeout(e,0);if((r===s||!r)&&setTimeout)return r=setTimeout,setTimeout(e,0);try{return r(e,0)}catch(t){try{return r.call(null,e,0)}catch(t){return r.call(this,e,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:s}catch(e){r=s}try{o="function"==typeof clearTimeout?clearTimeout:a}catch(e){o=a}}();var c,l=[],f=!1,p=-1;function h(){f&&c&&(f=!1,c.length?l=c.concat(l):p=-1,l.length&&d())}function d(){if(!f){var e=u(h);f=!0;for(var t=l.length;t;){for(c=l,l=[];++p1)for(var n=1;n= 0x80 (not a basic code point)","invalid-input":"Invalid input"},m=Math.floor,g=String.fromCharCode;function b(e){throw new RangeError(d[e])}function v(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function y(e,t){var n=e.split("@"),r="";return n.length>1&&(r=n[0]+"@",e=n[1]),r+v((e=e.replace(h,".")).split("."),t).join(".")}function _(e){for(var t,n,r=[],o=0,i=e.length;o=55296&&t<=56319&&o65535&&(t+=g((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+=g(e)})).join("")}function O(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function x(e,t,n){var r=0;for(e=n?m(e/700):e>>1,e+=m(e/t);e>455;r+=36)e=m(e/35);return m(r+36*e/(e+38))}function S(e){var t,n,r,o,i,s,a,u,c,f,p,h=[],d=e.length,g=0,v=128,y=72;for((n=e.lastIndexOf("-"))<0&&(n=0),r=0;r=128&&b("not-basic"),h.push(e.charCodeAt(r));for(o=n>0?n+1:0;o=d&&b("invalid-input"),((u=(p=e.charCodeAt(o++))-48<10?p-22:p-65<26?p-65:p-97<26?p-97:36)>=36||u>m((l-g)/s))&&b("overflow"),g+=u*s,!(u<(c=a<=y?1:a>=y+26?26:a-y));a+=36)s>m(l/(f=36-c))&&b("overflow"),s*=f;y=x(g-i,t=h.length+1,0==i),m(g/t)>l-v&&b("overflow"),v+=m(g/t),g%=t,h.splice(g++,0,v)}return w(h)}function C(e){var t,n,r,o,i,s,a,u,c,f,p,h,d,v,y,w=[];for(h=(e=_(e)).length,t=128,n=0,i=72,s=0;s=t&&pm((l-n)/(d=r+1))&&b("overflow"),n+=(a-t)*d,t=a,s=0;sl&&b("overflow"),p==t){for(u=n,c=36;!(u<(f=c<=i?1:c>=i+26?26:c-i));c+=36)y=u-f,v=36-f,w.push(g(O(f+y%v,0))),u=m(y/v);w.push(g(O(u,0))),i=x(n,d,r==o),n=0,++r}++n,++t}return w.join("")}if(a={version:"1.4.1",ucs2:{decode:_,encode:w},decode:S,encode:C,toASCII:function(e){return y(e,(function(e){return p.test(e)?"xn--"+C(e):e}))},toUnicode:function(e){return y(e,(function(e){return f.test(e)?S(e.slice(4).toLowerCase()):e}))}},o&&i)if(t.exports==o)i.exports=a;else for(u in a)a.hasOwnProperty(u)&&(o[u]=a[u]);else n.punycode=a}(this)}).call(this,void 0!==n?n:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],195:[function(e,t,n){function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,n,i){t=t||"&",n=n||"=";var s={};if("string"!=typeof e||0===e.length)return s;var a=/\+/g;e=e.split(t);var u=1e3;i&&"number"==typeof i.maxKeys&&(u=i.maxKeys);var c=e.length;u>0&&c>u&&(c=u);for(var l=0;l=0?(f=m.substr(0,g),p=m.substr(g+1)):(f=m,p=""),h=decodeURIComponent(f),d=decodeURIComponent(p),r(s,h)?o(s[h])?s[h].push(d):s[h]=[s[h],d]:s[h]=d}return s};var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},{}],196:[function(e,t,n){var r=function(e){switch(c(e)){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};t.exports=function(e,t,n,a){return t=t||"&",n=n||"=",null===e&&(e=void 0),"object"===c(e)?i(s(e),(function(s){var a=encodeURIComponent(r(s))+n;return o(e[s])?i(e[s],(function(e){return a+encodeURIComponent(r(e))})).join(t):a+encodeURIComponent(r(e[s]))})).join(t):a?encodeURIComponent(r(a))+n+encodeURIComponent(r(e)):""};var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};function i(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r=0)return t}else{var n=r.toSetString(e);if(o.call(this._set,n))return this._set[n]}throw new Error('"'+e+'" is not in the set.')},s.prototype.at=function(e){if(e>=0&&e>>=5)>0&&(t|=32),n+=r.encode(t)}while(o>0);return n},n.decode=function(e,t,n){var o,i,s,a,u=e.length,c=0,l=0;do{if(t>=u)throw new Error("Expected more digits in base 64 VLQ value.");if(-1===(i=r.decode(e.charCodeAt(t++))))throw new Error("Invalid base64 digit: "+e.charAt(t-1));o=!!(32&i),c+=(i&=31)<>1,1==(1&s)?-a:a),n.rest=t}},{"./base64":200}],200:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");n.encode=function(e){if(0<=e&&e0?r-u>1?e(u,r,o,i,s,a):a==n.LEAST_UPPER_BOUND?r1?e(t,u,o,i,s,a):a==n.LEAST_UPPER_BOUND?u:t<0?-1:t}(-1,t.length,e,t,r,o||n.GREATEST_LOWER_BOUND);if(i<0)return-1;for(;i-1>=0&&0===r(t[i],t[i-1],!0);)--i;return i}},{}],202:[function(e,t,n){var r=e("./util");function o(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}o.prototype.unsortedForEach=function(e,t){this._array.forEach(e,t)},o.prototype.add=function(e){var t,n,o,i,s,a;t=this._last,n=e,o=t.generatedLine,i=n.generatedLine,s=t.generatedColumn,a=n.generatedColumn,i>o||i==o&&a>=s||r.compareByGeneratedPositionsInflated(t,n)<=0?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},o.prototype.toArray=function(){return this._sorted||(this._array.sort(r.compareByGeneratedPositionsInflated),this._sorted=!0),this._array},n.MappingList=o},{"./util":207}],203:[function(e,t,n){function r(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function o(e,t,n,i){if(n=0){var a=this._originalMappings[s];if(void 0===e.column)for(var u=a.originalLine;a&&a.originalLine===u;)i.push({line:r.getArg(a,"generatedLine",null),column:r.getArg(a,"generatedColumn",null),lastColumn:r.getArg(a,"lastGeneratedColumn",null)}),a=this._originalMappings[++s];else for(var c=a.originalColumn;a&&a.originalLine===t&&a.originalColumn==c;)i.push({line:r.getArg(a,"generatedLine",null),column:r.getArg(a,"generatedColumn",null),lastColumn:r.getArg(a,"lastGeneratedColumn",null)}),a=this._originalMappings[++s]}return i},n.SourceMapConsumer=u,c.prototype=Object.create(u.prototype),c.prototype.consumer=u,c.prototype._findSourceIndex=function(e){var t,n=e;if(null!=this.sourceRoot&&(n=r.relative(this.sourceRoot,n)),this._sources.has(n))return this._sources.indexOf(n);for(t=0;t1&&(n.source=m+i[1],m+=i[1],n.originalLine=h+i[2],h=n.originalLine,n.originalLine+=1,n.originalColumn=d+i[3],d=n.originalColumn,i.length>4&&(n.name=g+i[4],g+=i[4])),O.push(n),"number"==typeof n.originalLine&&w.push(n)}a(O,r.compareByGeneratedPositionsDeflated),this.__generatedMappings=O,a(w,r.compareByOriginalPositions),this.__originalMappings=w},c.prototype._findMapping=function(e,t,n,r,i,s){if(e[n]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[n]);if(e[r]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[r]);return o.search(e,t,i,s)},c.prototype.computeColumnSpans=function(){for(var e=0;e=0){var o=this._generatedMappings[n];if(o.generatedLine===t.generatedLine){var i=r.getArg(o,"source",null);null!==i&&(i=this._sources.at(i),i=r.computeSourceURL(this.sourceRoot,i,this._sourceMapURL));var s=r.getArg(o,"name",null);return null!==s&&(s=this._names.at(s)),{source:i,line:r.getArg(o,"originalLine",null),column:r.getArg(o,"originalColumn",null),name:s}}}return{source:null,line:null,column:null,name:null}},c.prototype.hasContentsOfAllSources=function(){return!!this.sourcesContent&&this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return null==e}))},c.prototype.sourceContentFor=function(e,t){if(!this.sourcesContent)return null;var n=this._findSourceIndex(e);if(n>=0)return this.sourcesContent[n];var o,i=e;if(null!=this.sourceRoot&&(i=r.relative(this.sourceRoot,i)),null!=this.sourceRoot&&(o=r.urlParse(this.sourceRoot))){var s=i.replace(/^file:\/\//,"");if("file"==o.scheme&&this._sources.has(s))return this.sourcesContent[this._sources.indexOf(s)];if((!o.path||"/"==o.path)&&this._sources.has("/"+i))return this.sourcesContent[this._sources.indexOf("/"+i)]}if(t)return null;throw new Error('"'+i+'" is not in the SourceMap.')},c.prototype.generatedPositionFor=function(e){var t=r.getArg(e,"source");if((t=this._findSourceIndex(t))<0)return{line:null,column:null,lastColumn:null};var n={source:t,originalLine:r.getArg(e,"line"),originalColumn:r.getArg(e,"column")},o=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",r.compareByOriginalPositions,r.getArg(e,"bias",u.GREATEST_LOWER_BOUND));if(o>=0){var i=this._originalMappings[o];if(i.source===n.source)return{line:r.getArg(i,"generatedLine",null),column:r.getArg(i,"generatedColumn",null),lastColumn:r.getArg(i,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},n.BasicSourceMapConsumer=c,f.prototype=Object.create(u.prototype),f.prototype.constructor=u,f.prototype._version=3,Object.defineProperty(f.prototype,"sources",{get:function(){for(var e=[],t=0;t0&&e.column>=0)||t||n||r)&&!(e&&"line"in e&&"column"in e&&t&&"line"in t&&"column"in t&&e.line>0&&e.column>=0&&t.line>0&&t.column>=0&&n))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:t,name:r}))},a.prototype._serializeMappings=function(){for(var e,t,n,i,s=0,a=1,u=0,c=0,l=0,f=0,p="",h=this._mappings.toArray(),d=0,m=h.length;d0){if(!o.compareByGeneratedPositionsInflated(t,h[d-1]))continue;e+=","}e+=r.encode(t.generatedColumn-s),s=t.generatedColumn,null!=t.source&&(i=this._sources.indexOf(t.source),e+=r.encode(i-f),f=i,e+=r.encode(t.originalLine-1-c),c=t.originalLine-1,e+=r.encode(t.originalColumn-u),u=t.originalColumn,null!=t.name&&(n=this._names.indexOf(t.name),e+=r.encode(n-l),l=n)),p+=e}return p},a.prototype._generateSourcesContent=function(e,t){return e.map((function(e){if(!this._sourcesContents)return null;null!=t&&(e=o.relative(t,e));var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)},a.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},a.prototype.toString=function(){return JSON.stringify(this.toJSON())},n.SourceMapGenerator=a},{"./array-set":198,"./base64-vlq":199,"./mapping-list":202,"./util":207}],206:[function(e,t,n){var r=e("./source-map-generator").SourceMapGenerator,o=e("./util"),i=/(\r?\n)/,s="$$$isSourceNode$$$";function a(e,t,n,r,o){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==t?null:t,this.source=null==n?null:n,this.name=null==o?null:o,this[s]=!0,null!=r&&this.add(r)}a.fromStringWithSourceMap=function(e,t,n){var r=new a,s=e.split(i),u=0,c=function(){return e()+(e()||"");function e(){return u=0;t--)this.prepend(e[t]);else{if(!e[s]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},a.prototype.walk=function(e){for(var t,n=0,r=this.children.length;n0){for(t=[],n=0;n=0;l--)"."===(o=u[l])?u.splice(l,1):".."===o?c++:c>0&&(""===o?(u.splice(l+1,c),c=0):(u.splice(l,2),c--));return""===(t=u.join("/"))&&(t=a?"/":"."),r?(r.path=t,s(r)):t}function u(e,t){""===e&&(e="."),""===t&&(t=".");var n=i(t),r=i(e);if(r&&(e=r.path||"/"),n&&!n.scheme)return r&&(n.scheme=r.scheme),s(n);if(n||t.match(o))return t;if(r&&!r.host&&!r.path)return r.host=t,s(r);var u="/"===t.charAt(0)?t:a(e.replace(/\/+$/,"")+"/"+t);return r?(r.path=u,s(r)):u}n.urlParse=i,n.urlGenerate=s,n.normalize=a,n.join=u,n.isAbsolute=function(e){return"/"===e.charAt(0)||r.test(e)},n.relative=function(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");for(var n=0;0!==t.indexOf(e+"/");){var r=e.lastIndexOf("/");if(r<0)return t;if((e=e.slice(0,r)).match(/^([^\/]+:\/)?\/*$/))return t;++n}return Array(n+1).join("../")+t.substr(e.length+1)};var c=!("__proto__"in Object.create(null));function l(e){return e}function f(e){if(!e)return!1;var t=e.length;if(t<9)return!1;if(95!==e.charCodeAt(t-1)||95!==e.charCodeAt(t-2)||111!==e.charCodeAt(t-3)||116!==e.charCodeAt(t-4)||111!==e.charCodeAt(t-5)||114!==e.charCodeAt(t-6)||112!==e.charCodeAt(t-7)||95!==e.charCodeAt(t-8)||95!==e.charCodeAt(t-9))return!1;for(var n=t-10;n>=0;n--)if(36!==e.charCodeAt(n))return!1;return!0}function p(e,t){return e===t?0:null===e?1:null===t?-1:e>t?1:-1}n.toSetString=c?l:function(e){return f(e)?"$"+e:e},n.fromSetString=c?l:function(e){return f(e)?e.slice(1):e},n.compareByOriginalPositions=function(e,t,n){var r=p(e.source,t.source);return 0!==r||0!=(r=e.originalLine-t.originalLine)||0!=(r=e.originalColumn-t.originalColumn)||n||0!=(r=e.generatedColumn-t.generatedColumn)||0!=(r=e.generatedLine-t.generatedLine)?r:p(e.name,t.name)},n.compareByGeneratedPositionsDeflated=function(e,t,n){var r=e.generatedLine-t.generatedLine;return 0!==r||0!=(r=e.generatedColumn-t.generatedColumn)||n||0!==(r=p(e.source,t.source))||0!=(r=e.originalLine-t.originalLine)||0!=(r=e.originalColumn-t.originalColumn)?r:p(e.name,t.name)},n.compareByGeneratedPositionsInflated=function(e,t){var n=e.generatedLine-t.generatedLine;return 0!==n||0!=(n=e.generatedColumn-t.generatedColumn)||0!==(n=p(e.source,t.source))||0!=(n=e.originalLine-t.originalLine)||0!=(n=e.originalColumn-t.originalColumn)?n:p(e.name,t.name)},n.parseSourceMapInput=function(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))},n.computeSourceURL=function(e,t,n){if(t=t||"",e&&("/"!==e[e.length-1]&&"/"!==t[0]&&(e+="/"),t=e+t),n){var r=i(n);if(!r)throw new Error("sourceMapURL could not be parsed");if(r.path){var o=r.path.lastIndexOf("/");o>=0&&(r.path=r.path.substring(0,o+1))}t=u(s(r),t)}return a(t)}},{}],208:[function(e,t,n){n.SourceMapGenerator=e("./lib/source-map-generator").SourceMapGenerator,n.SourceMapConsumer=e("./lib/source-map-consumer").SourceMapConsumer,n.SourceNode=e("./lib/source-node").SourceNode},{"./lib/source-map-consumer":204,"./lib/source-map-generator":205,"./lib/source-node":206}],209:[function(e,t,n){var r=e("punycode"),o=e("./util");function i(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}n.parse=_,n.resolve=function(e,t){return _(e,!1,!0).resolve(t)},n.resolveObject=function(e,t){return e?_(e,!1,!0).resolveObject(t):t},n.format=function(e){return o.isString(e)&&(e=_(e)),e instanceof i?e.format():i.prototype.format.call(e)},n.Url=i;var s=/^([a-z0-9.+-]+:)/i,a=/:[0-9]*$/,u=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,l=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),f=["'"].concat(l),p=["%","/","?",";","#"].concat(f),h=["/","?","#"],d=/^[+a-z0-9A-Z_-]{0,63}$/,m=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,g={javascript:!0,"javascript:":!0},b={javascript:!0,"javascript:":!0},v={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},y=e("querystring");function _(e,t,n){if(e&&o.isObject(e)&&e instanceof i)return e;var r=new i;return r.parse(e,t,n),r}i.prototype.parse=function(e,t,n){if(!o.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+c(e));var i=e.indexOf("?"),a=-1!==i&&i127?L+="x":L+=P[R];if(!L.match(d)){var D=N.slice(0,A),V=N.slice(A+1),B=P.match(m);B&&(D.push(B[1]),V.unshift(B[2])),V.length&&(_="/"+V.join(".")+_),this.hostname=D.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),M||(this.hostname=r.toASCII(this.hostname));var U=this.port?":"+this.port:"",F=this.hostname||"";this.host=F+U,this.href+=this.host,M&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==_[0]&&(_="/"+_))}if(!g[x])for(A=0,T=f.length;A0)&&n.host.split("@"))&&(n.auth=E.shift(),n.host=n.hostname=E.shift())),n.search=e.search,n.query=e.query,o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.href=n.format(),n;if(!x.length)return n.pathname=null,n.search?n.path="/"+n.search:n.path=null,n.href=n.format(),n;for(var C=x.slice(-1)[0],j=(n.host||e.host||x.length>1)&&("."===C||".."===C)||""===C,k=0,A=x.length;A>=0;A--)"."===(C=x[A])?x.splice(A,1):".."===C?(x.splice(A,1),k++):k&&(x.splice(A,1),k--);if(!w&&!O)for(;k--;k)x.unshift("..");!w||""===x[0]||x[0]&&"/"===x[0].charAt(0)||x.unshift(""),j&&"/"!==x.join("/").substr(-1)&&x.push("");var E,M=""===x[0]||x[0]&&"/"===x[0].charAt(0);return S&&(n.hostname=n.host=M?"":x.length?x.shift():"",(E=!!(n.host&&n.host.indexOf("@")>0)&&n.host.split("@"))&&(n.auth=E.shift(),n.host=n.hostname=E.shift())),(w=w||n.host&&x.length)&&!M&&x.unshift(""),x.length?n.pathname=x.join("/"):(n.pathname=null,n.path=null),o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},i.prototype.parseHost=function(){var e=this.host,t=a.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{"./util":210,punycode:194,querystring:197}],210:[function(e,t,n){t.exports={isString:function(e){return"string"==typeof e},isObject:function(e){return"object"===c(e)&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],211:[function(e,t,n){var r=e("htmlparser2"),o=e("lodash/escapeRegExp"),i=e("lodash/cloneDeep"),s=e("lodash/mergeWith"),u=e("lodash/isString"),c=e("lodash/isPlainObject"),l=e("parse-srcset"),f=e("postcss"),p=e("url"),h=["img","audio","video","picture","svg","object","map","iframe","embed"],d=["script","style"];function m(e,t){e&&Object.keys(e).forEach((function(n){t(e[n],n)}))}function g(e,t){return{}.hasOwnProperty.call(e,t)}function b(e,t){var n=[];return m(e,(function(e){t(e)&&n.push(e)})),n}t.exports=y;var v=/^[^\0\t\n\f\r /<=>]+$/;function y(e,t,n){var w="",O="";function x(e,t){var n=this;this.tag=e,this.attribs=t||{},this.tagPosition=w.length,this.text="",this.mediaChildren=[],this.updateParentNodeText=function(){M.length&&(M[M.length-1].text+=n.text)},this.updateParentNodeMediaChildren=function(){M.length&&h.indexOf(this.tag)>-1&&M[M.length-1].mediaChildren.push(this.tag)}}t?(t=Object.assign({},y.defaults,t)).parser?t.parser=Object.assign({},_,t.parser):t.parser=_:(t=y.defaults).parser=_,d.forEach((function(e){t.allowedTags&&t.allowedTags.indexOf(e)>-1&&!t.allowVulnerableTags&&console.warn("\n\nโš ๏ธ Your `allowedTags` option includes, `".concat(e,"`, which is inherently\nvulnerable to XSS attacks. Please remove it from `allowedTags`.\nOr, to disable this warning, add the `allowVulnerableTags` option\nand ensure you are accounting for this risk.\n\n"))}));var S,C,j=t.nonTextTags||["script","style","textarea","option"];t.allowedAttributes&&(S={},C={},m(t.allowedAttributes,(function(e,t){S[t]=[];var n=[];e.forEach((function(e){u(e)&&e.indexOf("*")>=0?n.push(o(e).replace(/\\\*/g,".*")):S[t].push(e)})),C[t]=new RegExp("^("+n.join("|")+")$")})));var k={};m(t.allowedClasses,(function(e,t){S&&(g(S,t)||(S[t]=[]),S[t].push("class")),k[t]=e}));var A,E,M,N,T,P,L,R={};m(t.transformTags,(function(e,t){var n;"function"==typeof e?n=e:"string"==typeof e&&(n=y.simpleTransform(e)),"*"===t?A=n:R[t]=n}));var I=!1;V();var D=new r.Parser({onopentag:function(e,n){if(t.enforceHtmlBoundary&&"html"===e&&V(),P)L++;else{var r=new x(e,n);M.push(r);var o,u=!1,h=!!r.text;if(g(R,e)&&(o=R[e](e,n),r.attribs=n=o.attribs,void 0!==o.text&&(r.innerText=o.text),e!==o.tagName&&(r.name=e=o.tagName,T[E]=o.tagName)),A&&(o=A(e,n),r.attribs=n=o.attribs,e!==o.tagName&&(r.name=e=o.tagName,T[E]=o.tagName)),(t.allowedTags&&-1===t.allowedTags.indexOf(e)||"recursiveEscape"===t.disallowedTagsMode&&!function(e){for(var t in e)if(g(e,t))return!1;return!0}(N))&&(u=!0,N[E]=!0,"discard"===t.disallowedTagsMode&&-1!==j.indexOf(e)&&(P=!0,L=1),N[E]=!0),E++,u){if("discard"===t.disallowedTagsMode)return;O=w,w=""}w+="<"+e,(!S||g(S,e)||S["*"])&&m(n,(function(n,o){if(v.test(o)){var u,h=!1;if(!S||g(S,e)&&-1!==S[e].indexOf(o)||S["*"]&&-1!==S["*"].indexOf(o)||g(C,e)&&C[e].test(o)||C["*"]&&C["*"].test(o))h=!0;else if(S&&S[e]){var d,y=a(S[e]);try{for(y.s();!(d=y.n()).done;){var _=d.value;if(c(_)&&_.name&&_.name===o){h=!0;var O="";if(!0===_.multiple){var x,j=a(n.split(" "));try{for(j.s();!(x=j.n()).done;){var A=x.value;-1!==_.values.indexOf(A)&&(""===O?O=A:O+=" "+A)}}catch(e){j.e(e)}finally{j.f()}}else _.values.indexOf(n)>=0&&(O=n);n=O}}}catch(e){y.e(e)}finally{y.f()}}if(h){if(-1!==t.allowedSchemesAppliedToAttributes.indexOf(o)&&U(e,n))return void delete r.attribs[o];if("iframe"===e&&"src"===o){var E=!0;try{if((u=p.parse(n,!1,!0))&&null===u.host&&null===u.protocol)E=g(t,"allowIframeRelativeUrls")?t.allowIframeRelativeUrls:!t.allowedIframeHostnames&&!t.allowedIframeDomains;else if(t.allowedIframeHostnames||t.allowedIframeDomains){var M=(t.allowedIframeHostnames||[]).find((function(e){return e===u.hostname})),N=(t.allowedIframeDomains||[]).find((function(e){return u.hostname===e||u.hostname.endsWith(".".concat(e))}));E=M||N}}catch(e){E=!1}if(!E)return void delete r.attribs[o]}if("srcset"===o)try{if(m(u=l(n),(function(e){U("srcset",e.url)&&(e.evil=!0)})),!(u=b(u,(function(e){return!e.evil}))).length)return void delete r.attribs[o];n=b(u,(function(e){return!e.evil})).map((function(e){if(!e.url)throw new Error("URL missing");return e.url+(e.w?" ".concat(e.w,"w"):"")+(e.h?" ".concat(e.h,"h"):"")+(e.d?" ".concat(e.d,"x"):"")})).join(", "),r.attribs[o]=n}catch(e){return void delete r.attribs[o]}if("class"===o&&!(n=function(e,t){return t?(e=e.split(/\s+/)).filter((function(e){return-1!==t.indexOf(e)})).join(" "):e}(n,k[e])).length)return void delete r.attribs[o];if("style"===o)try{if(0===(n=function(e){return e.nodes[0].nodes.reduce((function(e,t){return e.push(t.prop+":"+t.value),e}),[]).join(";")}(function(e,t){if(!t)return e;var n,r=i(e),o=e.nodes[0];return(n=t[o.selector]&&t["*"]?s(i(t[o.selector]),t["*"],(function(e,t){if(Array.isArray(e))return e.concat(t)})):t[o.selector]||t["*"])&&(r.nodes[0].nodes=o.nodes.reduce(function(e){return function(t,n){return g(e,n.prop)&&e[n.prop].some((function(e){return e.test(n.value)}))&&t.push(n),t}}(n),[])),r}(f.parse(e+" {"+n+"}"),t.allowedStyles))).length)return void delete r.attribs[o]}catch(e){return void delete r.attribs[o]}w+=" "+o,n&&n.length&&(w+='="'+B(n,!0)+'"')}else delete r.attribs[o]}else delete r.attribs[o]})),-1!==t.selfClosing.indexOf(e)?w+=" />":(w+=">",!r.innerText||h||t.textFilter||(w+=r.innerText,I=!0)),u&&(w=O+B(w),O="")}},ontext:function(e){if(!P){var n,r=M[M.length-1];if(r&&(n=r.tag,e=void 0!==r.innerText?r.innerText:e),"discard"!==t.disallowedTagsMode||"script"!==n&&"style"!==n){var o=B(e,!1);t.textFilter&&!I?w+=t.textFilter(o,n):I||(w+=o)}else w+=e;M.length&&(M[M.length-1].text+=e)}},onclosetag:function(e){if(P){if(--L)return;P=!1}var n=M.pop();if(n){P=!!t.enforceHtmlBoundary&&"html"===e,E--;var r=N[E];if(r){if(delete N[E],"discard"===t.disallowedTagsMode)return void n.updateParentNodeText();O=w,w=""}T[E]&&(e=T[E],delete T[E]),t.exclusiveFilter&&t.exclusiveFilter(n)?w=w.substr(0,n.tagPosition):(n.updateParentNodeMediaChildren(),n.updateParentNodeText(),-1===t.selfClosing.indexOf(e)?(w+="",r&&(w=O+B(w),O="")):r&&(w=O,O=""))}}},t.parser);return D.write(e),D.end(),w;function V(){w="",E=0,M=[],N={},T={},P=!1,L=0}function B(e,n){return"string"!=typeof e&&(e+=""),t.parser.decodeEntities&&(e=e.replace(/&/g,"&").replace(//g,">"),n&&(e=e.replace(/\"/g,"""))),e=e.replace(/&(?![a-zA-Z0-9#]{1,20};)/g,"&").replace(//g,">"),n&&(e=e.replace(/\"/g,""")),e}function U(e,n){var r=(n=(n=n.replace(/[\x00-\x20]+/g,"")).replace(/<\!\-\-.*?\-\-\>/g,"")).match(/^([a-zA-Z]+)\:/);if(!r)return!!n.match(/^[\/\\]{2}/)&&!t.allowProtocolRelative;var o=r[1].toLowerCase();return g(t.allowedSchemesByTag,e)?-1===t.allowedSchemesByTag[e].indexOf(o):!t.allowedSchemes||-1===t.allowedSchemes.indexOf(o)}}var _={decodeEntities:!0};y.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","abbr","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre","iframe"],disallowedTagsMode:"discard",allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{},allowedSchemesAppliedToAttributes:["href","src","cite"],allowProtocolRelative:!0,enforceHtmlBoundary:!1},y.simpleTransform=function(e,t,n){return n=void 0===n||n,t=t||{},function(r,o){var i;if(n)for(i in t)o[i]=t[i];else o=t;return{tagName:e,attribs:o}}}},{htmlparser2:31,"lodash/cloneDeep":140,"lodash/escapeRegExp":143,"lodash/isPlainObject":155,"lodash/isString":157,"lodash/mergeWith":162,"parse-srcset":167,postcss:181,url:209}]},{},[211])(211)},"object"===c(t)&&void 0!==e?e.exports=s():(o=[],void 0===(i="function"==typeof(r=s)?r.apply(t,o):r)||(e.exports=i))}).call(this,n(42))},function(e,t,n){"use strict";n.d(t,"b",(function(){return r})),n.d(t,"c",(function(){return o})),n.d(t,"d",(function(){return i})),n.d(t,"a",(function(){return s}));var r={allowedTags:["blockquote","caption","div","figcaption","figure","h1","h2","h3","h4","h5","h6","hr","li","ol","p","pre","section","table","tbody","td","th","thead","tr","ul","a","abbr","acronym","audio","b","bdi","bdo","big","br","button","canvas","cite","code","data","datalist","del","dfn","em","embed","i","iframe","img","input","ins","kbd","label","map","mark","meter","noscript","object","output","picture","progress","q","ruby","s","samp","select","slot","small","span","strong","sub","sup","svg","template","textarea","time","u","tt","var","video","wbr"],allowedAttributes:{"*":["class","id","data-*","style"],iframe:["*"],a:["href","name","target"],img:["src","srcset","sizes","alt","width","height"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{},allowProtocolRelative:!0},o={allowedTags:["a","abbr","acronym","audio","b","bdi","bdo","big","br","button","canvas","cite","code","data","datalist","del","dfn","em","embed","i","iframe","img","input","ins","kbd","label","map","mark","meter","noscript","object","output","picture","progress","q","ruby","s","samp","select","slot","small","span","strong","sub","sup","svg","template","textarea","time","u","tt","var","video","wbr"],allowedAttributes:{"*":["class","id","data-*","style"],a:["href","name","target"],img:["src","srcset","sizes","alt","width","height"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{},allowProtocolRelative:!0},i={allowedTags:["h1","h2","h3","h4","h5","h6","blockquote","p","ul","ol","nl","li","b","i","strong","em","strike","code","cite","hr","br","div","table","thead","caption","tbody","tr","th","td","pre","img","figure","figcaption","iframe","section"],allowedAttributes:{"*":["class","id","data-*","style"],iframe:["*"],img:["src","srcset","sizes","alt","width","height"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"]},s={allowedTags:[],allowedAttributes:{}}},function(e,t,n){"use strict";n.d(t,"a",(function(){return r})),n.d(t,"b",(function(){return o}));function r(e,t,n){var r="";return n.split(" ").forEach((function(n){void 0!==e[n]?t.push(e[n]+";"):r+=n+" "})),r}var o=function(e,t,n){var r=e.key+"-"+t.name;if(!1===n&&void 0===e.registered[r]&&(e.registered[r]=t.styles),void 0===e.inserted[t.name]){var o=t;do{e.insert(t===o?"."+r:"",o,e.sheet,!0);o=o.next}while(void 0!==o)}}},function(e,t){!function(){e.exports=this.wp.element}()},function(e,t,n){"use strict";n.d(t,"a",(function(){return m}));var r=function(e){for(var t,n=0,r=0,o=e.length;o>=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)},o={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},i=n(34),s=/[A-Z]|^ms/g,a=/_EMO_([^_]+?)_([^]*?)_EMO_/g,u=function(e){return 45===e.charCodeAt(1)},c=function(e){return null!=e&&"boolean"!=typeof e},l=Object(i.a)((function(e){return u(e)?e:e.replace(s,"-$&").toLowerCase()})),f=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(a,(function(e,t,n){return h={name:t,styles:n,next:h},t}))}return 1===o[e]||u(e)||"number"!=typeof t||0===t?t:t+"px"};function p(e,t,n){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return h={name:n.name,styles:n.styles,next:h},n.name;if(void 0!==n.styles){var r=n.next;if(void 0!==r)for(;void 0!==r;)h={name:r.name,styles:r.styles,next:h},r=r.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;oe.length)&&(t=e.length);for(var n=0,r=new Array(t);n0,m=l-p-c,g=!1;m>t&&a.current&&(r&&r(e),a.current=!1),d&&u.current&&(s&&s(e),u.current=!1),d&&t>m?(n&&!a.current&&n(e),h.scrollTop=l,g=!0,a.current=!0):!d&&-t>c&&(i&&!u.current&&i(e),h.scrollTop=0,g=!0,u.current=!0),g&&function(e){e.preventDefault(),e.stopPropagation()}(e)}}),[]),h=Object(l.useCallback)((function(e){p(e,e.deltaY)}),[p]),d=Object(l.useCallback)((function(e){c.current=e.changedTouches[0].clientY}),[]),m=Object(l.useCallback)((function(e){var t=c.current-e.changedTouches[0].clientY;p(e,t)}),[p]),g=Object(l.useCallback)((function(e){if(e){var t=!!o.B&&{passive:!1};"function"==typeof e.addEventListener&&e.addEventListener("wheel",h,t),"function"==typeof e.addEventListener&&e.addEventListener("touchstart",d,t),"function"==typeof e.addEventListener&&e.addEventListener("touchmove",m,t)}}),[m,d,h]),b=Object(l.useCallback)((function(e){e&&("function"==typeof e.removeEventListener&&e.removeEventListener("wheel",h,!1),"function"==typeof e.removeEventListener&&e.removeEventListener("touchstart",d,!1),"function"==typeof e.removeEventListener&&e.removeEventListener("touchmove",m,!1))}),[m,d,h]);return Object(l.useEffect)((function(){if(t){var e=f.current;return g(e),function(){b(e)}}}),[t,g,b]),function(e){f.current=e}}({isEnabled:void 0===r||r,onBottomArrive:e.onBottomArrive,onBottomLeave:e.onBottomLeave,onTopArrive:e.onTopArrive,onTopLeave:e.onTopLeave}),s=function(e){var t=e.isEnabled,n=e.accountForScrollbars,r=void 0===n||n,o=Object(l.useRef)({}),i=Object(l.useRef)(null),s=Object(l.useCallback)((function(e){if(I){var t=document.body,n=t&&t.style;if(r&&M.forEach((function(e){var t=n&&n[e];o.current[e]=t})),r&&D<1){var i=parseInt(o.current.paddingRight,10)||0,s=document.body?document.body.clientWidth:0,a=window.innerWidth-s+i||0;Object.keys(N).forEach((function(e){var t=N[e];n&&(n[e]=t)})),n&&(n.paddingRight="".concat(a,"px"))}t&&R()&&(t.addEventListener("touchmove",T,V),e&&(e.addEventListener("touchstart",L,V),e.addEventListener("touchmove",P,V))),D+=1}}),[]),a=Object(l.useCallback)((function(e){if(I){var t=document.body,n=t&&t.style;D=Math.max(D-1,0),r&&D<1&&M.forEach((function(e){var t=o.current[e];n&&(n[e]=t)})),t&&R()&&(t.removeEventListener("touchmove",T,V),e&&(e.removeEventListener("touchstart",L,V),e.removeEventListener("touchmove",P,V)))}}),[]);return Object(l.useEffect)((function(){if(t){var e=i.current;return s(e),function(){a(e)}}}),[t,s,a]),function(e){i.current=e}}({isEnabled:n});return Object(p.c)(f.a.Fragment,null,n&&Object(p.c)("div",{onClick:B,css:U}),t((function(e){i(e),s(e)})))}var q={clearIndicator:o.l,container:o.m,control:o.n,dropdownIndicator:o.o,group:o.p,groupHeading:o.q,indicatorsContainer:o.r,indicatorSeparator:o.s,input:o.t,loadingIndicator:o.u,loadingMessage:o.v,menu:o.w,menuList:o.x,menuPortal:o.y,multiValue:o.z,multiValueLabel:o.A,multiValueRemove:o.C,noOptionsMessage:o.D,option:o.E,placeholder:o.F,singleValue:o.G,valueContainer:o.H};var H,z={borderRadius:4,colors:{primary:"#2684FF",primary75:"#4C9AFF",primary50:"#B2D4FF",primary25:"#DEEBFF",danger:"#DE350B",dangerLight:"#FFBDAD",neutral0:"hsl(0, 0%, 100%)",neutral5:"hsl(0, 0%, 95%)",neutral10:"hsl(0, 0%, 90%)",neutral20:"hsl(0, 0%, 80%)",neutral30:"hsl(0, 0%, 70%)",neutral40:"hsl(0, 0%, 60%)",neutral50:"hsl(0, 0%, 50%)",neutral60:"hsl(0, 0%, 40%)",neutral70:"hsl(0, 0%, 30%)",neutral80:"hsl(0, 0%, 20%)",neutral90:"hsl(0, 0%, 10%)"},spacing:{baseUnit:4,controlHeight:38,menuGutter:8}},G={"aria-live":"polite",backspaceRemovesValue:!0,blurInputOnSelect:Object(o.I)(),captureMenuScroll:!Object(o.I)(),closeMenuOnSelect:!0,closeMenuOnScroll:!1,components:{},controlShouldRenderValue:!0,escapeClearsValue:!1,filterOption:function(e,t){var n=Object(o.k)({ignoreCase:!0,ignoreAccents:!0,stringify:A,trim:!0,matchFrom:"any"},H),r=n.ignoreCase,i=n.ignoreAccents,s=n.stringify,a=n.trim,u=n.matchFrom,c=a?k(t):t,l=a?k(s(e)):s(e);return r&&(c=c.toLowerCase(),l=l.toLowerCase()),i&&(c=j(c),l=C(l)),"start"===u?l.substr(0,c.length)===c:l.indexOf(c)>-1},formatGroupLabel:function(e){return e.label},getOptionLabel:function(e){return e.label},getOptionValue:function(e){return e.value},isDisabled:!1,isLoading:!1,isMulti:!1,isRtl:!1,isSearchable:!0,isOptionDisabled:function(e){return!!e.isDisabled},loadingMessage:function(){return"Loading..."},maxMenuHeight:300,minMenuHeight:140,menuIsOpen:!1,menuPlacement:"bottom",menuPosition:"absolute",menuShouldBlockScroll:!1,menuShouldScrollIntoView:!Object(o.a)(),noOptionsMessage:function(){return"No options"},openMenuOnFocus:!1,openMenuOnClick:!0,options:[],pageSize:5,placeholder:"Select...",screenReaderStatus:function(e){var t=e.count;return"".concat(t," result").concat(1!==t?"s":""," available")},styles:{},tabIndex:"0",tabSelectsValue:!0};function $(e,t,n,r){return{type:"option",data:t,isDisabled:J(e,t,n),isSelected:Q(e,t,n),label:X(e,t),value:K(e,t),index:r}}function W(e,t){return e.options.map((function(n,r){if(n.options){var o=n.options.map((function(n,r){return $(e,n,t,r)})).filter((function(t){return Z(e,t)}));return o.length>0?{type:"group",data:n,options:o,index:r}:void 0}var i=$(e,n,t,r);return Z(e,i)?i:void 0})).filter((function(e){return!!e}))}function Y(e){return e.reduce((function(e,t){return"group"===t.type?e.push.apply(e,c(t.options.map((function(e){return e.data})))):e.push(t.data),e}),[])}function Z(e,t){var n=e.inputValue,r=void 0===n?"":n,o=t.data,i=t.isSelected,s=t.label,a=t.value;return(!te(e)||!i)&&ee(e,{label:s,value:a,data:o},r)}var X=function(e,t){return e.getOptionLabel(t)},K=function(e,t){return e.getOptionValue(t)};function J(e,t,n){return"function"==typeof e.isOptionDisabled&&e.isOptionDisabled(t,n)}function Q(e,t,n){if(n.indexOf(t)>-1)return!0;if("function"==typeof e.isOptionSelected)return e.isOptionSelected(t,n);var r=K(e,t);return n.some((function(t){return K(e,t)===r}))}function ee(e,t,n){return!e.filterOption||e.filterOption(t,n)}var te=function(e){var t=e.hideSelectedOptions,n=e.isMulti;return void 0===t?n:t},ne=1,re=function(e){Object(a.a)(n,e);var t=Object(o.j)(n);function n(e){var r;return Object(i.a)(this,n),(r=t.call(this,e)).state={ariaSelection:null,focusedOption:null,focusedValue:null,inputIsHidden:!1,isFocused:!1,selectValue:[],clearFocusValueOnUpdate:!1,inputIsHiddenAfterUpdate:void 0,prevProps:void 0},r.blockOptionHover=!1,r.isComposing=!1,r.commonProps=void 0,r.initialTouchX=0,r.initialTouchY=0,r.instancePrefix="",r.openAfterFocus=!1,r.scrollToFocusedOptionOnUpdate=!1,r.userIsDragging=void 0,r.controlRef=null,r.getControlRef=function(e){r.controlRef=e},r.focusedOptionRef=null,r.getFocusedOptionRef=function(e){r.focusedOptionRef=e},r.menuListRef=null,r.getMenuListRef=function(e){r.menuListRef=e},r.inputRef=null,r.getInputRef=function(e){r.inputRef=e},r.focus=r.focusInput,r.blur=r.blurInput,r.onChange=function(e,t){var n=r.props,o=n.onChange,i=n.name;t.name=i,r.ariaOnChange(e,t),o(e,t)},r.setValue=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"set-value",n=arguments.length>2?arguments[2]:void 0,o=r.props,i=o.closeMenuOnSelect,s=o.isMulti;r.onInputChange("",{action:"set-value"}),i&&(r.setState({inputIsHiddenAfterUpdate:!s}),r.onMenuClose()),r.setState({clearFocusValueOnUpdate:!0}),r.onChange(e,{action:t,option:n})},r.selectOption=function(e){var t=r.props,n=t.blurInputOnSelect,o=t.isMulti,i=t.name,s=r.state.selectValue,a=o&&r.isOptionSelected(e,s),u=r.isOptionDisabled(e,s);if(a){var l=r.getOptionValue(e);r.setValue(s.filter((function(e){return r.getOptionValue(e)!==l})),"deselect-option",e)}else{if(u)return void r.ariaOnChange(e,{action:"select-option",name:i});o?r.setValue([].concat(c(s),[e]),"select-option",e):r.setValue(e,"select-option")}n&&r.blurInput()},r.removeValue=function(e){var t=r.props.isMulti,n=r.state.selectValue,o=r.getOptionValue(e),i=n.filter((function(e){return r.getOptionValue(e)!==o})),s=t?i:i[0]||null;r.onChange(s,{action:"remove-value",removedValue:e}),r.focusInput()},r.clearValue=function(){var e=r.state.selectValue;r.onChange(r.props.isMulti?[]:null,{action:"clear",removedValues:e})},r.popValue=function(){var e=r.props.isMulti,t=r.state.selectValue,n=t[t.length-1],o=t.slice(0,t.length-1),i=e?o:o[0]||null;r.onChange(i,{action:"pop-value",removedValue:n})},r.getValue=function(){return r.state.selectValue},r.cx=function(){for(var e=arguments.length,t=new Array(e),n=0;n5||i>5}},r.onTouchEnd=function(e){r.userIsDragging||(r.controlRef&&!r.controlRef.contains(e.target)&&r.menuListRef&&!r.menuListRef.contains(e.target)&&r.blurInput(),r.initialTouchX=0,r.initialTouchY=0)},r.onControlTouchEnd=function(e){r.userIsDragging||r.onControlMouseDown(e)},r.onClearIndicatorTouchEnd=function(e){r.userIsDragging||r.onClearIndicatorMouseDown(e)},r.onDropdownIndicatorTouchEnd=function(e){r.userIsDragging||r.onDropdownIndicatorMouseDown(e)},r.handleInputChange=function(e){var t=e.currentTarget.value;r.setState({inputIsHiddenAfterUpdate:!1}),r.onInputChange(t,{action:"input-change"}),r.props.menuIsOpen||r.onMenuOpen()},r.onInputFocus=function(e){r.props.onFocus&&r.props.onFocus(e),r.setState({inputIsHiddenAfterUpdate:!1,isFocused:!0}),(r.openAfterFocus||r.props.openMenuOnFocus)&&r.openMenu("first"),r.openAfterFocus=!1},r.onInputBlur=function(e){r.menuListRef&&r.menuListRef.contains(document.activeElement)?r.inputRef.focus():(r.props.onBlur&&r.props.onBlur(e),r.onInputChange("",{action:"input-blur"}),r.onMenuClose(),r.setState({focusedValue:null,isFocused:!1}))},r.onOptionHover=function(e){r.blockOptionHover||r.state.focusedOption===e||r.setState({focusedOption:e})},r.shouldHideSelectedOptions=function(){return te(r.props)},r.onKeyDown=function(e){var t=r.props,n=t.isMulti,o=t.backspaceRemovesValue,i=t.escapeClearsValue,s=t.inputValue,a=t.isClearable,u=t.isDisabled,c=t.menuIsOpen,l=t.onKeyDown,f=t.tabSelectsValue,p=t.openMenuOnFocus,h=r.state,d=h.focusedOption,m=h.focusedValue,g=h.selectValue;if(!(u||"function"==typeof l&&(l(e),e.defaultPrevented))){switch(r.blockOptionHover=!0,e.key){case"ArrowLeft":if(!n||s)return;r.focusValue("previous");break;case"ArrowRight":if(!n||s)return;r.focusValue("next");break;case"Delete":case"Backspace":if(s)return;if(m)r.removeValue(m);else{if(!o)return;n?r.popValue():a&&r.clearValue()}break;case"Tab":if(r.isComposing)return;if(e.shiftKey||!c||!f||!d||p&&r.isOptionSelected(d,g))return;r.selectOption(d);break;case"Enter":if(229===e.keyCode)break;if(c){if(!d)return;if(r.isComposing)return;r.selectOption(d);break}return;case"Escape":c?(r.setState({inputIsHiddenAfterUpdate:!1}),r.onInputChange("",{action:"menu-close"}),r.onMenuClose()):a&&i&&r.clearValue();break;case" ":if(s)return;if(!c){r.openMenu("first");break}if(!d)return;r.selectOption(d);break;case"ArrowUp":c?r.focusOption("up"):r.openMenu("last");break;case"ArrowDown":c?r.focusOption("down"):r.openMenu("first");break;case"PageUp":if(!c)return;r.focusOption("pageup");break;case"PageDown":if(!c)return;r.focusOption("pagedown");break;case"Home":if(!c)return;r.focusOption("first");break;case"End":if(!c)return;r.focusOption("last");break;default:return}e.preventDefault()}},r.instancePrefix="react-select-"+(r.props.instanceId||++ne),r.state.selectValue=Object(o.e)(e.value),r}return Object(s.a)(n,[{key:"componentDidMount",value:function(){this.startListeningComposition(),this.startListeningToTouch(),this.props.closeMenuOnScroll&&document&&document.addEventListener&&document.addEventListener("scroll",this.onScroll,!0),this.props.autoFocus&&this.focusInput()}},{key:"componentDidUpdate",value:function(e){var t=this.props,n=t.isDisabled,r=t.menuIsOpen,i=this.state.isFocused;(i&&!n&&e.isDisabled||i&&r&&!e.menuIsOpen)&&this.focusInput(),i&&n&&!e.isDisabled&&this.setState({isFocused:!1},this.onMenuClose),this.menuListRef&&this.focusedOptionRef&&this.scrollToFocusedOptionOnUpdate&&(Object(o.f)(this.menuListRef,this.focusedOptionRef),this.scrollToFocusedOptionOnUpdate=!1)}},{key:"componentWillUnmount",value:function(){this.stopListeningComposition(),this.stopListeningToTouch(),document.removeEventListener("scroll",this.onScroll,!0)}},{key:"onMenuOpen",value:function(){this.props.onMenuOpen()}},{key:"onMenuClose",value:function(){this.onInputChange("",{action:"menu-close"}),this.props.onMenuClose()}},{key:"onInputChange",value:function(e,t){this.props.onInputChange(e,t)}},{key:"focusInput",value:function(){this.inputRef&&this.inputRef.focus()}},{key:"blurInput",value:function(){this.inputRef&&this.inputRef.blur()}},{key:"openMenu",value:function(e){var t=this,n=this.state,r=n.selectValue,o=n.isFocused,i=this.buildFocusableOptions(),s="first"===e?0:i.length-1;if(!this.props.isMulti){var a=i.indexOf(r[0]);a>-1&&(s=a)}this.scrollToFocusedOptionOnUpdate=!(o&&this.menuListRef),this.setState({inputIsHiddenAfterUpdate:!1,focusedValue:null,focusedOption:i[s]},(function(){return t.onMenuOpen()}))}},{key:"focusValue",value:function(e){var t=this.state,n=t.selectValue,r=t.focusedValue;if(this.props.isMulti){this.setState({focusedOption:null});var o=n.indexOf(r);r||(o=-1);var i=n.length-1,s=-1;if(n.length){switch(e){case"previous":s=0===o?0:-1===o?i:o-1;break;case"next":o>-1&&o0&&void 0!==arguments[0]?arguments[0]:"first",t=this.props.pageSize,n=this.state.focusedOption,r=this.getFocusableOptions();if(r.length){var o=0,i=r.indexOf(n);n||(i=-1),"up"===e?o=i>0?i-1:r.length-1:"down"===e?o=(i+1)%r.length:"pageup"===e?(o=i-t)<0&&(o=0):"pagedown"===e?(o=i+t)>r.length-1&&(o=r.length-1):"last"===e&&(o=r.length-1),this.scrollToFocusedOptionOnUpdate=!0,this.setState({focusedOption:r[o],focusedValue:null})}}},{key:"getTheme",value:function(){return this.props.theme?"function"==typeof this.props.theme?this.props.theme(z):Object(o.k)(Object(o.k)({},z),this.props.theme):z}},{key:"getCommonProps",value:function(){var e=this.clearValue,t=this.cx,n=this.getStyles,r=this.getValue,o=this.selectOption,i=this.setValue,s=this.props,a=s.isMulti,u=s.isRtl,c=s.options;return{clearValue:e,cx:t,getStyles:n,getValue:r,hasValue:this.hasValue(),isMulti:a,isRtl:u,options:c,selectOption:o,selectProps:s,setValue:i,theme:this.getTheme()}}},{key:"hasValue",value:function(){return this.state.selectValue.length>0}},{key:"hasOptions",value:function(){return!!this.getFocusableOptions().length}},{key:"isClearable",value:function(){var e=this.props,t=e.isClearable,n=e.isMulti;return void 0===t?n:t}},{key:"isOptionDisabled",value:function(e,t){return J(this.props,e,t)}},{key:"isOptionSelected",value:function(e,t){return Q(this.props,e,t)}},{key:"filterOption",value:function(e,t){return ee(this.props,e,t)}},{key:"formatOptionLabel",value:function(e,t){if("function"==typeof this.props.formatOptionLabel){var n=this.props.inputValue,r=this.state.selectValue;return this.props.formatOptionLabel(e,{context:t,inputValue:n,selectValue:r})}return this.getOptionLabel(e)}},{key:"formatGroupLabel",value:function(e){return this.props.formatGroupLabel(e)}},{key:"startListeningComposition",value:function(){document&&document.addEventListener&&(document.addEventListener("compositionstart",this.onCompositionStart,!1),document.addEventListener("compositionend",this.onCompositionEnd,!1))}},{key:"stopListeningComposition",value:function(){document&&document.removeEventListener&&(document.removeEventListener("compositionstart",this.onCompositionStart),document.removeEventListener("compositionend",this.onCompositionEnd))}},{key:"startListeningToTouch",value:function(){document&&document.addEventListener&&(document.addEventListener("touchstart",this.onTouchStart,!1),document.addEventListener("touchmove",this.onTouchMove,!1),document.addEventListener("touchend",this.onTouchEnd,!1))}},{key:"stopListeningToTouch",value:function(){document&&document.removeEventListener&&(document.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd))}},{key:"renderInput",value:function(){var e=this.props,t=e.isDisabled,n=e.isSearchable,i=e.inputId,s=e.inputValue,a=e.tabIndex,u=e.form,c=this.getComponents().Input,l=this.state.inputIsHidden,p=this.commonProps,h=i||this.getElementId("input"),d={"aria-autocomplete":"list","aria-label":this.props["aria-label"],"aria-labelledby":this.props["aria-labelledby"]};return n?f.a.createElement(c,Object(r.a)({},p,{autoCapitalize:"none",autoComplete:"off",autoCorrect:"off",id:h,innerRef:this.getInputRef,isDisabled:t,isHidden:l,onBlur:this.onInputBlur,onChange:this.handleInputChange,onFocus:this.onInputFocus,spellCheck:"false",tabIndex:a,form:u,type:"text",value:s},d)):f.a.createElement(E,Object(r.a)({id:h,innerRef:this.getInputRef,onBlur:this.onInputBlur,onChange:o.g,onFocus:this.onInputFocus,readOnly:!0,disabled:t,tabIndex:a,form:u,value:""},d))}},{key:"renderPlaceholderOrValue",value:function(){var e=this,t=this.getComponents(),n=t.MultiValue,o=t.MultiValueContainer,i=t.MultiValueLabel,s=t.MultiValueRemove,a=t.SingleValue,u=t.Placeholder,c=this.commonProps,l=this.props,p=l.controlShouldRenderValue,h=l.isDisabled,d=l.isMulti,m=l.inputValue,g=l.placeholder,b=this.state,v=b.selectValue,y=b.focusedValue,_=b.isFocused;if(!this.hasValue()||!p)return m?null:f.a.createElement(u,Object(r.a)({},c,{key:"placeholder",isDisabled:h,isFocused:_}),g);if(d)return v.map((function(t,a){var u=t===y;return f.a.createElement(n,Object(r.a)({},c,{components:{Container:o,Label:i,Remove:s},isFocused:u,isDisabled:h,key:"".concat(e.getOptionValue(t)).concat(a),index:a,removeProps:{onClick:function(){return e.removeValue(t)},onTouchEnd:function(){return e.removeValue(t)},onMouseDown:function(e){e.preventDefault(),e.stopPropagation()}},data:t}),e.formatOptionLabel(t,"value"))}));if(m)return null;var w=v[0];return f.a.createElement(a,Object(r.a)({},c,{data:w,isDisabled:h}),this.formatOptionLabel(w,"value"))}},{key:"renderClearIndicator",value:function(){var e=this.getComponents().ClearIndicator,t=this.commonProps,n=this.props,o=n.isDisabled,i=n.isLoading,s=this.state.isFocused;if(!this.isClearable()||!e||o||!this.hasValue()||i)return null;var a={onMouseDown:this.onClearIndicatorMouseDown,onTouchEnd:this.onClearIndicatorTouchEnd,"aria-hidden":"true"};return f.a.createElement(e,Object(r.a)({},t,{innerProps:a,isFocused:s}))}},{key:"renderLoadingIndicator",value:function(){var e=this.getComponents().LoadingIndicator,t=this.commonProps,n=this.props,o=n.isDisabled,i=n.isLoading,s=this.state.isFocused;if(!e||!i)return null;return f.a.createElement(e,Object(r.a)({},t,{innerProps:{"aria-hidden":"true"},isDisabled:o,isFocused:s}))}},{key:"renderIndicatorSeparator",value:function(){var e=this.getComponents(),t=e.DropdownIndicator,n=e.IndicatorSeparator;if(!t||!n)return null;var o=this.commonProps,i=this.props.isDisabled,s=this.state.isFocused;return f.a.createElement(n,Object(r.a)({},o,{isDisabled:i,isFocused:s}))}},{key:"renderDropdownIndicator",value:function(){var e=this.getComponents().DropdownIndicator;if(!e)return null;var t=this.commonProps,n=this.props.isDisabled,o=this.state.isFocused,i={onMouseDown:this.onDropdownIndicatorMouseDown,onTouchEnd:this.onDropdownIndicatorTouchEnd,"aria-hidden":"true"};return f.a.createElement(e,Object(r.a)({},t,{innerProps:i,isDisabled:n,isFocused:o}))}},{key:"renderMenu",value:function(){var e=this,t=this.getComponents(),n=t.Group,i=t.GroupHeading,s=t.Menu,a=t.MenuList,u=t.MenuPortal,c=t.LoadingMessage,l=t.NoOptionsMessage,p=t.Option,h=this.commonProps,d=this.state.focusedOption,m=this.props,g=m.captureMenuScroll,b=m.inputValue,v=m.isLoading,y=m.loadingMessage,_=m.minMenuHeight,w=m.maxMenuHeight,O=m.menuIsOpen,x=m.menuPlacement,S=m.menuPosition,C=m.menuPortalTarget,j=m.menuShouldBlockScroll,k=m.menuShouldScrollIntoView,A=m.noOptionsMessage,E=m.onMenuScrollToTop,M=m.onMenuScrollToBottom;if(!O)return null;var N,T=function(t,n){var o=t.type,i=t.data,s=t.isDisabled,a=t.isSelected,u=t.label,c=t.value,l=d===i,m=s?void 0:function(){return e.onOptionHover(i)},g=s?void 0:function(){return e.selectOption(i)},b="".concat(e.getElementId("option"),"-").concat(n),v={id:b,onClick:g,onMouseMove:m,onMouseOver:m,tabIndex:-1};return f.a.createElement(p,Object(r.a)({},h,{innerProps:v,data:i,isDisabled:s,isSelected:a,key:b,label:u,type:o,value:c,isFocused:l,innerRef:l?e.getFocusedOptionRef:void 0}),e.formatOptionLabel(t.data,"menu"))};if(this.hasOptions())N=this.getCategorizedOptions().map((function(t){if("group"===t.type){var o=t.data,s=t.options,a=t.index,u="".concat(e.getElementId("group"),"-").concat(a),c="".concat(u,"-heading");return f.a.createElement(n,Object(r.a)({},h,{key:u,data:o,options:s,Heading:i,headingProps:{id:c,data:t.data},label:e.formatGroupLabel(t.data)}),t.options.map((function(e){return T(e,"".concat(a,"-").concat(e.index))})))}if("option"===t.type)return T(t,"".concat(t.index))}));else if(v){var P=y({inputValue:b});if(null===P)return null;N=f.a.createElement(c,h,P)}else{var L=A({inputValue:b});if(null===L)return null;N=f.a.createElement(l,h,L)}var R={minMenuHeight:_,maxMenuHeight:w,menuPlacement:x,menuPosition:S,menuShouldScrollIntoView:k},I=f.a.createElement(o.i,Object(r.a)({},h,R),(function(t){var n=t.ref,o=t.placerProps,i=o.placement,u=o.maxHeight;return f.a.createElement(s,Object(r.a)({},h,R,{innerRef:n,innerProps:{onMouseDown:e.onMenuMouseDown,onMouseMove:e.onMenuMouseMove},isLoading:v,placement:i}),f.a.createElement(F,{captureEnabled:g,onTopArrive:E,onBottomArrive:M,lockEnabled:j},(function(t){return f.a.createElement(a,Object(r.a)({},h,{innerRef:function(n){e.getMenuListRef(n),t(n)},isLoading:v,maxHeight:u,focusedOption:d}),N)})))}));return C||"fixed"===S?f.a.createElement(u,Object(r.a)({},h,{appendTo:C,controlElement:this.controlRef,menuPlacement:x,menuPosition:S}),I):I}},{key:"renderFormField",value:function(){var e=this,t=this.props,n=t.delimiter,r=t.isDisabled,o=t.isMulti,i=t.name,s=this.state.selectValue;if(i&&!r){if(o){if(n){var a=s.map((function(t){return e.getOptionValue(t)})).join(n);return f.a.createElement("input",{name:i,type:"hidden",value:a})}var u=s.length>0?s.map((function(t,n){return f.a.createElement("input",{key:"i-".concat(n),name:i,type:"hidden",value:e.getOptionValue(t)})})):f.a.createElement("input",{name:i,type:"hidden"});return f.a.createElement("div",null,u)}var c=s[0]?this.getOptionValue(s[0]):"";return f.a.createElement("input",{name:i,type:"hidden",value:c})}}},{key:"renderLiveRegion",value:function(){var e=this.commonProps,t=this.state,n=t.ariaSelection,o=t.focusedOption,i=t.focusedValue,s=t.isFocused,a=t.selectValue,u=this.getFocusableOptions();return f.a.createElement(v,Object(r.a)({},e,{ariaSelection:n,focusedOption:o,focusedValue:i,isFocused:s,selectValue:a,focusableOptions:u}))}},{key:"render",value:function(){var e=this.getComponents(),t=e.Control,n=e.IndicatorsContainer,o=e.SelectContainer,i=e.ValueContainer,s=this.props,a=s.className,u=s.id,c=s.isDisabled,l=s.menuIsOpen,p=this.state.isFocused,h=this.commonProps=this.getCommonProps();return f.a.createElement(o,Object(r.a)({},h,{className:a,innerProps:{id:u,onKeyDown:this.onKeyDown},isDisabled:c,isFocused:p}),this.renderLiveRegion(),f.a.createElement(t,Object(r.a)({},h,{innerRef:this.getControlRef,innerProps:{onMouseDown:this.onControlMouseDown,onTouchEnd:this.onControlTouchEnd},isDisabled:c,isFocused:p,menuIsOpen:l}),f.a.createElement(i,Object(r.a)({},h,{isDisabled:c}),this.renderPlaceholderOrValue(),this.renderInput()),f.a.createElement(n,Object(r.a)({},h,{isDisabled:c}),this.renderClearIndicator(),this.renderLoadingIndicator(),this.renderIndicatorSeparator(),this.renderDropdownIndicator())),this.renderMenu(),this.renderFormField())}}],[{key:"getDerivedStateFromProps",value:function(e,t){var n=t.prevProps,r=t.clearFocusValueOnUpdate,i=t.inputIsHiddenAfterUpdate,s=e.options,a=e.value,u=e.menuIsOpen,c=e.inputValue,l={};if(n&&(a!==n.value||s!==n.options||u!==n.menuIsOpen||c!==n.inputValue)){var f=Object(o.e)(a),p=u?function(e,t){return Y(W(e,t))}(e,f):[],h=r?function(e,t){var n=e.focusedValue,r=e.selectValue.indexOf(n);if(r>-1){if(t.indexOf(n)>-1)return n;if(r-1?n:t[0]}(t,p),focusedValue:h,clearFocusValueOnUpdate:!1}}var d=null!=i&&e!==n?{inputIsHidden:i,inputIsHiddenAfterUpdate:void 0}:{};return Object(o.k)(Object(o.k)(Object(o.k)({},l),d),{},{prevProps:e})}}]),n}(l.Component);re.defaultProps=G},function(e,t,n){"use strict";n.d(t,"a",(function(){return r}));var r=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(this.props,[]);return function(e){l.forEach((function(t){return delete e[t]}))}(o),o.className=this.props.inputClassName,o.id=this.state.inputId,o.style=n,s.default.createElement("div",{className:this.props.className,style:t},this.renderStyles(),s.default.createElement("input",r({},o,{ref:this.inputRef})),s.default.createElement("div",{ref:this.sizerRef,style:c},e),this.props.placeholder?s.default.createElement("div",{ref:this.placeHolderSizerRef,style:c},this.props.placeholder):null)}}]),t}(i.Component);d.propTypes={className:a.default.string,defaultValue:a.default.any,extraWidth:a.default.oneOfType([a.default.number,a.default.string]),id:a.default.string,injectStyles:a.default.bool,inputClassName:a.default.string,inputRef:a.default.func,inputStyle:a.default.object,minWidth:a.default.oneOfType([a.default.number,a.default.string]),onAutosize:a.default.func,onChange:a.default.func,placeholder:a.default.string,placeholderIsMinWidth:a.default.bool,style:a.default.object,value:a.default.any},d.defaultProps={minWidth:1,injectStyles:!0},t.default=d},function(e,t,n){"use strict";var r=n(33),o=n(7),i=(n(27),n(34),function(e,t){return Object(o.c)(function(e,t){var n=-1,r=44;do{switch(Object(o.o)(r)){case 0:38===r&&12===Object(o.i)()&&(t[n]=1),e[n]+=Object(o.f)(o.j-1);break;case 2:e[n]+=Object(o.d)(r);break;case 4:if(44===r){e[++n]=58===Object(o.i)()?"&\f":"",t[n]=e[n].length;break}default:e[n]+=Object(o.e)(r)}}while(r=Object(o.h)());return e}(Object(o.a)(e),t))}),s=new WeakMap,a=function(e){if("rule"===e.type&&e.parent&&e.length){for(var t=e.value,n=e.parent,r=e.column===n.column&&e.line===n.line;"rule"!==n.type;)if(!(n=n.parent))return;if((1!==e.props.length||58===t.charCodeAt(0)||s.get(n))&&!r){s.set(e,!0);for(var o=[],a=i(t,o),u=n.props,c=0,l=0;ce.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?n-1:0),o=1;o=16;e.exports={PRESERVE_CUSTOM_ATTRIBUTES:s,camelCase:function(e){if("string"!=typeof e)throw new TypeError("First argument must be a string");return i.test(e)?e:e.toLowerCase().replace(o,(function(e,t){return t.toUpperCase()}))},invertObject:function(e,t){if(!e||"object"!=typeof e)throw new TypeError("First argument must be an object");var n,r,o="function"==typeof t,i={},s={};for(n in e)r=e[n],o&&(i=t(n,r))&&2===i.length?s[i[0]]=i[1]:"string"==typeof r&&(s[r]=n);return s},isCustomComponent:function(e,t){if(-1===e.indexOf("-"))return t&&"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}}},function(e,t,n){for(var r,o=n(236).CASE_SENSITIVE_TAG_NAMES,i={},s=0,a=o.length;s1&&(a=f(a,{key:a.key||b})),d.push(a);else if("text"!==s.type){switch(u=s.attribs,i(s)||(u=r(s.attribs)),c=null,s.type){case"script":case"style":s.children[0]&&(u.dangerouslySetInnerHTML={__html:s.children[0].data});break;case"tag":"textarea"===s.name&&s.children[0]?u.defaultValue=s.children[0].data:s.children&&s.children.length&&(c=e(s.children,o));break;default:continue}v>1&&(u.key=b),d.push(p(s.name,u,c))}else g?s.data.trim()&&d.push(s.data):d.push(s.data);return 1===d.length?d[0]:d}},function(e,t,n){var r=n(228),o=n(232),i=n(83),s=i.camelCase,a=r.html,u=r.svg,c=r.isCustomAttribute,l=Object.prototype.hasOwnProperty;e.exports=function(e){var t,n,r,f;e=e||{};var p={};for(t in e)r=e[t],c(t)?p[t]=r:(n=t.toLowerCase(),l.call(a,n)?p[(f=a[n]).propertyName]=!!(f.hasBooleanValue||f.hasOverloadedBooleanValue&&!r)||r:l.call(u,t)?p[(f=u[t]).propertyName]=r:i.PRESERVE_CUSTOM_ATTRIBUTES&&(p[t]=r));return null!=e.style&&(p.style=function(e){var t={};e&&o(e,(function(e,n){e&&n&&(t[s(e)]=n)}));return t}(e.style)),p}},function(e,t,n){var r=n(229),o=n(230),i=n(231),s=i.MUST_USE_PROPERTY,a=i.HAS_BOOLEAN_VALUE,u=i.HAS_NUMERIC_VALUE,c=i.HAS_POSITIVE_NUMERIC_VALUE,l=i.HAS_OVERLOADED_BOOLEAN_VALUE;function f(e,t){return(e&t)===t}function p(e,t,n){var r,o,i,p=e.Properties,h=e.DOMAttributeNames;for(o in p)r=h[o]||(n?o:o.toLowerCase()),i=p[o],t[r]={attributeName:r,propertyName:o,mustUseProperty:f(i,s),hasBooleanValue:f(i,a),hasNumericValue:f(i,u),hasPositiveNumericValue:f(i,c),hasOverloadedBooleanValue:f(i,l)}}var h={};p(r,h);var d={};p(o,d,!0);var m={};p(r,m),p(o,m,!0);e.exports={html:h,svg:d,properties:m,isCustomAttribute:RegExp.prototype.test.bind(new RegExp("^(data|aria)-[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"))}},function(e,t){e.exports={Properties:{autoFocus:4,accept:0,acceptCharset:0,accessKey:0,action:0,allowFullScreen:4,allowTransparency:0,alt:0,as:0,async:4,autoComplete:0,autoPlay:4,capture:4,cellPadding:0,cellSpacing:0,charSet:0,challenge:0,checked:5,cite:0,classID:0,className:0,cols:24,colSpan:0,content:0,contentEditable:0,contextMenu:0,controls:4,controlsList:0,coords:0,crossOrigin:0,data:0,dateTime:0,default:4,defer:4,dir:0,disabled:4,download:32,draggable:0,encType:0,form:0,formAction:0,formEncType:0,formMethod:0,formNoValidate:4,formTarget:0,frameBorder:0,headers:0,height:0,hidden:4,high:0,href:0,hrefLang:0,htmlFor:0,httpEquiv:0,icon:0,id:0,inputMode:0,integrity:0,is:0,keyParams:0,keyType:0,kind:0,label:0,lang:0,list:0,loop:4,low:0,manifest:0,marginHeight:0,marginWidth:0,max:0,maxLength:0,media:0,mediaGroup:0,method:0,min:0,minLength:0,multiple:5,muted:5,name:0,nonce:0,noValidate:4,open:4,optimum:0,pattern:0,placeholder:0,playsInline:4,poster:0,preload:0,profile:0,radioGroup:0,readOnly:4,referrerPolicy:0,rel:0,required:4,reversed:4,role:0,rows:24,rowSpan:8,sandbox:0,scope:0,scoped:4,scrolling:0,seamless:4,selected:5,shape:0,size:24,sizes:0,span:24,spellCheck:0,src:0,srcDoc:0,srcLang:0,srcSet:0,start:8,step:0,style:0,summary:0,tabIndex:0,target:0,title:0,type:0,useMap:0,value:0,width:0,wmode:0,wrap:0,about:0,datatype:0,inlist:0,prefix:0,property:0,resource:0,typeof:0,vocab:0,autoCapitalize:0,autoCorrect:0,autoSave:0,color:0,itemProp:0,itemScope:4,itemType:0,itemID:0,itemRef:0,results:0,security:0,unselectable:0},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"}}},function(e,t){e.exports={Properties:{accentHeight:0,accumulate:0,additive:0,alignmentBaseline:0,allowReorder:0,alphabetic:0,amplitude:0,arabicForm:0,ascent:0,attributeName:0,attributeType:0,autoReverse:0,azimuth:0,baseFrequency:0,baseProfile:0,baselineShift:0,bbox:0,begin:0,bias:0,by:0,calcMode:0,capHeight:0,clip:0,clipPath:0,clipRule:0,clipPathUnits:0,colorInterpolation:0,colorInterpolationFilters:0,colorProfile:0,colorRendering:0,contentScriptType:0,contentStyleType:0,cursor:0,cx:0,cy:0,d:0,decelerate:0,descent:0,diffuseConstant:0,direction:0,display:0,divisor:0,dominantBaseline:0,dur:0,dx:0,dy:0,edgeMode:0,elevation:0,enableBackground:0,end:0,exponent:0,externalResourcesRequired:0,fill:0,fillOpacity:0,fillRule:0,filter:0,filterRes:0,filterUnits:0,floodColor:0,floodOpacity:0,focusable:0,fontFamily:0,fontSize:0,fontSizeAdjust:0,fontStretch:0,fontStyle:0,fontVariant:0,fontWeight:0,format:0,from:0,fx:0,fy:0,g1:0,g2:0,glyphName:0,glyphOrientationHorizontal:0,glyphOrientationVertical:0,glyphRef:0,gradientTransform:0,gradientUnits:0,hanging:0,horizAdvX:0,horizOriginX:0,ideographic:0,imageRendering:0,in:0,in2:0,intercept:0,k:0,k1:0,k2:0,k3:0,k4:0,kernelMatrix:0,kernelUnitLength:0,kerning:0,keyPoints:0,keySplines:0,keyTimes:0,lengthAdjust:0,letterSpacing:0,lightingColor:0,limitingConeAngle:0,local:0,markerEnd:0,markerMid:0,markerStart:0,markerHeight:0,markerUnits:0,markerWidth:0,mask:0,maskContentUnits:0,maskUnits:0,mathematical:0,mode:0,numOctaves:0,offset:0,opacity:0,operator:0,order:0,orient:0,orientation:0,origin:0,overflow:0,overlinePosition:0,overlineThickness:0,paintOrder:0,panose1:0,pathLength:0,patternContentUnits:0,patternTransform:0,patternUnits:0,pointerEvents:0,points:0,pointsAtX:0,pointsAtY:0,pointsAtZ:0,preserveAlpha:0,preserveAspectRatio:0,primitiveUnits:0,r:0,radius:0,refX:0,refY:0,renderingIntent:0,repeatCount:0,repeatDur:0,requiredExtensions:0,requiredFeatures:0,restart:0,result:0,rotate:0,rx:0,ry:0,scale:0,seed:0,shapeRendering:0,slope:0,spacing:0,specularConstant:0,specularExponent:0,speed:0,spreadMethod:0,startOffset:0,stdDeviation:0,stemh:0,stemv:0,stitchTiles:0,stopColor:0,stopOpacity:0,strikethroughPosition:0,strikethroughThickness:0,string:0,stroke:0,strokeDasharray:0,strokeDashoffset:0,strokeLinecap:0,strokeLinejoin:0,strokeMiterlimit:0,strokeOpacity:0,strokeWidth:0,surfaceScale:0,systemLanguage:0,tableValues:0,targetX:0,targetY:0,textAnchor:0,textDecoration:0,textRendering:0,textLength:0,to:0,transform:0,u1:0,u2:0,underlinePosition:0,underlineThickness:0,unicode:0,unicodeBidi:0,unicodeRange:0,unitsPerEm:0,vAlphabetic:0,vHanging:0,vIdeographic:0,vMathematical:0,values:0,vectorEffect:0,version:0,vertAdvY:0,vertOriginX:0,vertOriginY:0,viewBox:0,viewTarget:0,visibility:0,widths:0,wordSpacing:0,writingMode:0,x:0,xHeight:0,x1:0,x2:0,xChannelSelector:0,xlinkActuate:0,xlinkArcrole:0,xlinkHref:0,xlinkRole:0,xlinkShow:0,xlinkTitle:0,xlinkType:0,xmlBase:0,xmlns:0,xmlnsXlink:0,xmlLang:0,xmlSpace:0,y:0,y1:0,y2:0,yChannelSelector:0,z:0,zoomAndPan:0},DOMAttributeNames:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",xlinkActuate:"xlink:actuate",xlinkArcrole:"xlink:arcrole",xlinkHref:"xlink:href",xlinkRole:"xlink:role",xlinkShow:"xlink:show",xlinkTitle:"xlink:title",xlinkType:"xlink:type",xmlBase:"xml:base",xmlnsXlink:"xmlns:xlink",xmlLang:"xml:lang",xmlSpace:"xml:space"}}},function(e,t){e.exports={MUST_USE_PROPERTY:1,HAS_BOOLEAN_VALUE:4,HAS_NUMERIC_VALUE:8,HAS_POSITIVE_NUMERIC_VALUE:24,HAS_OVERLOADED_BOOLEAN_VALUE:32}},function(e,t,n){var r=n(233);e.exports=function(e,t){var n,o=null;if(!e||"string"!=typeof e)return o;for(var i,s,a=r(e),u="function"==typeof t,c=0,l=a.length;c/;e.exports=function(e){if("string"!=typeof e)throw new TypeError("First argument must be a string");if(!e)return[];var t,n=e.match(a);return n&&n[1]&&(t=n[1],s&&(e=e.replace(n[0],""))),i(r(e),null,t)}},function(e,t,n){var r=n(84),o=/<([a-zA-Z]+[0-9]?)/,i=//i,s=//i,a=/<(area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)(.*?)\/?>/gi,u=r.isIE(9),c=u||r.isIE(),l=function(){throw new Error("This browser does not support `document.implementation.createHTMLDocument`")},f=function(){throw new Error("This browser does not support `DOMParser.prototype.parseFromString`")};if("function"==typeof window.DOMParser){var p=new window.DOMParser,h=u?"text/xml":"text/html";l=f=function(e,t){return t&&(e="<"+t+">"+e+""),u&&(e=e.replace(a,"<$1$2$3/>")),p.parseFromString(e,h)}}if(document.implementation){var d=document.implementation.createHTMLDocument(c?"html-dom-parser":void 0);l=function(e,t){if(t)return d.documentElement.getElementsByTagName(t)[0].innerHTML=e,d;try{return d.documentElement.innerHTML=e,d}catch(t){if(f)return f(e)}}}var m,g=document.createElement("template");g.content&&(m=function(e){return g.innerHTML=e,g.content.childNodes}),e.exports=function(e){var t,n,r,a,u=e.match(o);switch(u&&u[1]&&(t=u[1].toLowerCase()),t){case"html":return n=f(e),i.test(e)||(r=n.getElementsByTagName("head")[0])&&r.parentNode.removeChild(r),s.test(e)||(r=n.getElementsByTagName("body")[0])&&r.parentNode.removeChild(r),n.getElementsByTagName("html");case"head":case"body":return a=l(e).getElementsByTagName(t),s.test(e)&&i.test(e)?a[0].parentNode.childNodes:a;default:return m?m(e):l(e,"body").getElementsByTagName("body")[0].childNodes}}},function(e,t){e.exports={CASE_SENSITIVE_TAG_NAMES:["animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussainBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","linearGradient","radialGradient","textPath"]}},function(e,t,n){var r=n(238);e.exports=function(e,t){if(null==e)return{};var n,o,i=r(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},,function(e,t,n){"use strict";n.r(t);var r=n(57),o=function(e){var t=e.namespace,n=e.title,o=e.icon;Object(r.registerBlockCollection)(t,{title:n,icon:o})},i=n(44),s=n.n(i),a=n(30),u=n(6),c=n(32),l=n(47),f=n(17),p=n(18),h=n(19),d=n(4),m=n(0),g=n.n(m),b=n(10);var v=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function W(e){var t=e.className,n=e.isShiftStepEnabled,r=void 0===n||n,o=e.max,i=void 0===o?1/0:o,s=e.min,a=void 0===s?-1/0:s,u=e.onChange,c=void 0===u?q.noop:u,l=e.onKeyDown,f=void 0===l?q.noop:l,p=e.shiftStep,h=void 0===p?10:p,d=e.step,m=void 0===d?1:d,g=$(e,z),b=Object(q.clamp)(0,a,i),v=P()("component-number-control",t);return React.createElement("input",G({inputMode:"numeric"},g,{className:v,type:"number",onChange:function(e){c(e.target.value,{event:e})},onKeyDown:function(e){f(e);var t=e.target.value,n=""===t,o=e.shiftKey&&r?parseFloat(h):parseFloat(m),s=n?b:t;switch(s=parseFloat(s),e.keyCode){case H.UP:e.preventDefault(),s+=o,s=Object(q.clamp)(s,a,i),c(s.toString(),{event:e});break;case H.DOWN:e.preventDefault(),s-=o,s=Object(q.clamp)(s,a,i),c(s.toString(),{event:e})}},__self:this,__source:{fileName:"/Users/sc0ttkclark/Dropbox/Local Sites/test.pods.local/app/public/wp-content/plugins/pods/ui/js/blocks/src/components/NumberControl/index.js",lineNumber:70,columnNumber:3}}))}var Y="/Users/sc0ttkclark/Dropbox/Local Sites/test.pods.local/app/public/wp-content/plugins/pods/ui/js/blocks/src/blocks/components/RenderedField.js";function Z(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function X(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return Object(le.addQueryArgs)("/wp/v2/block-renderer/".concat(e),_e(_e({context:"edit"},null!==t?{attributes:t}:{}),n))}(n,u?null:o,void 0===a?{}:a),l=u?{attributes:o}:null,f=this.currentFetchRequest=ce()({path:c,data:l,method:u?"POST":"GET"}).then((function(e){t.isStillMounted&&f===t.currentFetchRequest&&e&&t.setState({response:e.rendered})})).catch((function(e){t.isStillMounted&&f===t.currentFetchRequest&&t.setState({response:{error:!0,errorMsg:e.message}})}));return f}}},{key:"render",value:function(){var e=this,t=this.state.response,n=this.props,r=n.className,o=n.EmptyResponsePlaceholder,i=n.ErrorResponsePlaceholder,u=n.LoadingResponsePlaceholder;return""===t?React.createElement(o,he({response:t},this.props,{__self:this,__source:{fileName:pe,lineNumber:117,columnNumber:11}})):t?t.error?React.createElement(i,he({response:t},this.props,{__self:this,__source:{fileName:pe,lineNumber:126,columnNumber:5}})):s()(t,{replace:function(t){if("innerblocks"===t.name)return void 0!==t.attribs.template&&(t.attribs.template=JSON.parse(t.attribs.template)),void 0!==t.attribs.allowedBlocks&&(t.attribs.allowedBlocks=JSON.parse(t.attribs.allowedBlocks)),void 0!==t.attribs.templateLock&&"false"===t.attribs.templateLock&&(t.attribs.templateLock=!1),React.createElement(a.InnerBlocks,he({className:r},t.attribs,{__self:e,__source:{fileName:pe,lineNumber:144,columnNumber:13}}))}}):React.createElement(u,he({response:t},this.props,{__self:this,__source:{fileName:pe,lineNumber:121,columnNumber:5}}))}}])&&de(t.prototype,n),r&&de(t,r),i}(ae.Component);Oe.defaultProps={EmptyResponsePlaceholder:function(e){var t=e.className;return React.createElement(u.Placeholder,{className:t,__self:void 0,__source:{fileName:pe,lineNumber:153,columnNumber:3}},Object(A.__)("Block rendered as empty."))},ErrorResponsePlaceholder:function(e){var t=e.response,n=e.className,r=Object(A.sprintf)(Object(A.__)("Error loading block: %s"),t.errorMsg);return React.createElement(u.Placeholder,{className:n,__self:void 0,__source:{fileName:pe,lineNumber:163,columnNumber:10}},r)},LoadingResponsePlaceholder:function(e){var t=e.className;return React.createElement(u.Placeholder,{className:t,__self:void 0,__source:{fileName:pe,lineNumber:167,columnNumber:4}},React.createElement(u.Spinner,{__self:void 0,__source:{fileName:pe,lineNumber:168,columnNumber:5}}))}};var xe=Oe,Se=n(22);function Ce(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function je(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3?arguments[3]:void 0,o=arguments.length>4?arguments[4]:void 0,i=ne()(e,Se.b),a=[];return t.forEach((function(e){var t="function"==typeof o?r(e,n,o):r(e,n);t&&(a[e.name]=je({},t.props));var s=t?Object(ae.renderToString)(t):"";i=i.replace(new RegExp("{@".concat(e.name,"}"),"g"),s)})),s()(i)},Ee="/Users/sc0ttkclark/Dropbox/Local Sites/test.pods.local/app/public/wp-content/plugins/pods/ui/js/blocks/src/blocks/components/BlockPreview.js",Me=function(e,t){var n=e.name,r=e.fieldOptions,o=e.type,i=t[n];if(void 0===i)return null;switch(o){case"TextControl":return React.createElement("div",{key:n,className:"field--textcontrol",__self:void 0,__source:{fileName:Ee,lineNumber:51,columnNumber:5}},ne()(i,Se.a));case"TextareaControl":var s=r.auto_p,u=ne()(i,Se.a);return React.createElement("div",{key:n,className:"field--textareacontrol",dangerouslySetInnerHTML:{__html:s?Object(re.autop)(u):u},__self:void 0,__source:{fileName:Ee,lineNumber:64,columnNumber:5}});case"RichText":return React.createElement(a.RichText.Content,{key:n,tagName:"p",value:i,className:"field--richtext",__self:void 0,__source:{fileName:Ee,lineNumber:75,columnNumber:5}});case"CheckboxControl":return React.createElement("div",{key:n,className:"field--checkbox",__self:void 0,__source:{fileName:Ee,lineNumber:85,columnNumber:5}},i?Object(A.__)("Yes"):Object(A.__)("No"));case"CheckboxGroup":var c=r.options,l=Array.isArray(i)?i.filter((function(e){return!!e.checked})):[];return React.createElement("div",{key:n,className:"field--checkbox-group",__self:void 0,__source:{fileName:Ee,lineNumber:100,columnNumber:5}},l.length?l.map((function(e,t){var n=c.find((function(t){return e.value===t.value}));return React.createElement("span",{className:"field--checkbox-group__item",key:e.value,__self:void 0,__source:{fileName:Ee,lineNumber:106,columnNumber:9}},n.label,t { + const { + namespace, + title, + icon, + } = blockCollection; + + registerBlockCollection( namespace, { + title, + icon, + } ); +}; + +export default createBlockCollection; diff --git a/ui/js/blocks/src/blocks/README.md b/ui/js/blocks/src/blocks/README.md new file mode 100644 index 0000000000..41c2703eaa --- /dev/null +++ b/ui/js/blocks/src/blocks/README.md @@ -0,0 +1,56 @@ +# createBlock + +Dynamically creates a block based on field data. + +## Table of contents + +1. [Adding New Controls](#adding-new-controls) + +## Adding New Controls + +To add support for a new type of control, you'll need to create any custom components (if needed), update the config file, and update the `createBlockEditComponent()` and `renderBlockWithValues()` functions along with their tests. + +To begin: + +### 1. Create any components. + +This can be skipped if there is a Gutenberg control that does exactly what you need it to do. See the [WordPress Block Editor Components Reference](https://developer.wordpress.org/block-editor/components/). + +The components should live in the `components` directory, similar to the CheckboxGroup component. + +### 2. Update test data. +The file `testData.js` contains fixtures that are used by the tests for both `createBlockEditComponent()` and eventually for `renderBlockWithValues()`. + +#### Create Test Field Data +The field data under the "Fields" heading in this file is in the format that the block creator expects to be passed in the API. + +The `type` property should match the name of the component that you created (or the component from Gutenberg core). + +The `name` is specific to this field instance, and will be used in the template to render the block. + +The `fieldOptions` contains props that are passed to the field's control component. + +The `attributeOptions` are used to create the [attributes](https://developer.wordpress.org/block-editor/developers/block-api/block-attributes/) in the block. + +#### Update the Template and Block Definition +You could create an extra template and a new block definition if you'd create a completely new test, or you can add on to the block that already exists to test every supported type of field. + +To add to the existing block, find the `templateWithEveryFieldType` const and add a brief summary of what the new component is, and a template tag that matches the `name` you set in the previous step. + +Then in the `allFieldsBlock` block object, under the `fields` property, add the variable name that you created to hold the field data in the previous step. + +In the `allFieldsBlockProps` object, under the `attributes` property, add a key with the `name` of the field along with a valid value for the field. + +### 3. Update createBlockEditComponent(). +In `createBlockEditComponent.js`, add the dependency to the new component at the top of the file. Then in the `renderField()` function, find the switch statement that has a case for each of our supported controls. Add a new case for the new control name. It would also be good to create a scope for this case, as the others are here. You'll then render the component. + +Any type of component here should take a `key` prop which is set to the `name` and an `onChange` prop set to `changeHandler` - these are already provided in the function. + +In the test file for `createBlockEditComponent()`, find the existing field tests and add one to check that the field has successfully been rendered. + +### 4. Update renderBlockWithValues(). +These steps are similar to `createBlockEditComponent()`, but result in the value being rendered instead of the field. + +In the `renderField()` function, find the switch statement that has a case for each of our supported controls. Add a new case for the new control name. It would also be good to create a scope for this case, as the others are here. You'll then render the component. + +The component being rendered here will vary depending on the control, but any HTML element being returned here should have a `key` property set to the name, as well as a `className` in the convention of `"field--${ typeOfField }"`. diff --git a/ui/js/blocks/src/blocks/components/BlockPreview.js b/ui/js/blocks/src/blocks/components/BlockPreview.js new file mode 100644 index 0000000000..1742e940aa --- /dev/null +++ b/ui/js/blocks/src/blocks/components/BlockPreview.js @@ -0,0 +1,258 @@ +/** + * External dependencies + */ +import sanitizeHtml from 'sanitize-html'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +import { autop } from '@wordpress/autop'; + +import { RichText } from '@wordpress/block-editor'; + +import { + __experimentalGetSettings, + dateI18n, + format as formatDate, +} from '@wordpress/date'; + +import ServerSideRender from '@wordpress/server-side-render'; +import PodsServerSideRender from './PodsServerSideRender'; + +/** + * Internal dependencies + */ +import renderBlockTemplate from '../../utils/renderBlockTemplate'; +import { plainText } from '../../config/html'; + +/** + * Renders an individual field to be used in a template. + * + * @param {Object} field Field data. + * @param {Object} attributes All block attributes. + */ +const renderField = ( field, attributes ) => { + const { + name, + fieldOptions, + type, + } = field; + const fieldValue = attributes[ name ]; + + if ( 'undefined' === typeof fieldValue ) { + return null; + } + + switch ( type ) { + case 'TextControl': { + return ( +
          + { sanitizeHtml( fieldValue, plainText ) } +
          + ); + } + case 'TextareaControl': { + const { + auto_p: shouldAutoP, + } = fieldOptions; + + const sanitizedText = sanitizeHtml( fieldValue, plainText ); + + return ( +
          + ); + } + case 'RichText': { + return ( + + ); + } + case 'CheckboxControl': { + return ( +
          + { fieldValue ? __( 'Yes' ) : __( 'No' ) } +
          + ); + } + case 'CheckboxGroup': { + const { + options, + } = fieldOptions; + + const values = Array.isArray( fieldValue ) + ? fieldValue.filter( ( value ) => !! value.checked ) + : []; + + return ( +
          + { values.length + ? values.map( ( value, index ) => { + const matchingOption = options.find( ( option ) => value.value === option.value ); + + return ( + + { matchingOption.label } + { ( index < values.length - 1 ) ? ', ' : '' } + + ); + } ) + : 'N/A' } +
          + ); + } + case 'RadioControl': { + const { options } = fieldOptions; + + const matchingOption = options.find( ( option ) => fieldValue === option.value ); + + return ( +
          + { !! matchingOption ? matchingOption.label : 'N/A' } +
          + ); + } + case 'SelectControl': { + // Could be either a Select with "multiple" values or not. + if ( ! Array.isArray( fieldValue ) ) { + return ( +
          + { fieldValue.label || 'N/A' } +
          + ); + } + const values = fieldValue; + + return ( +
          + { values.length + ? values.map( ( value, index ) => { + return ( + + { value.label } + { ( index < values.length - 1 ) ? ', ' : '' } + + ); + } ) + : 'N/A' } +
          + ); + } + case 'DateTimePicker': { + const dateFormat = __experimentalGetSettings().formats.datetime; + + return ( +
          + +
          + ); + } + case 'NumberControl': { + let { locale } = __experimentalGetSettings().l10n; + + locale = locale.replace( '_', '-' ); + + return ( +
          + { !! fieldValue && fieldValue.toLocaleString( locale ) } +
          + ); + } + case 'MediaUpload': { + return ( +
          + { fieldValue && fieldValue.url || 'N/A' } +
          + ); + } + case 'ColorPicker': { + return ( +
          + { fieldValue } +
          + ); + } + default: + return null; + } +}; + +const BlockPreview = ( { + block, + attributes = {}, + context = {}, +} ) => { + const { + blockName, + fields = [], + renderTemplate, + renderType, + supports = { + jsx: false, + }, + usesContext = [], + } = block; + + if ( 'php' === renderType ) { + const urlQueryArgs = { + podsContext: {}, + }; + + usesContext.forEach( contextName => { + urlQueryArgs.podsContext[ contextName ] = context[ contextName ] ?? null; + } ); + + if ( true === supports.jsx ) { + return ( + + ); + } + + return ( + + ); + } + + return ( + <> + { renderBlockTemplate( renderTemplate, fields, attributes, renderField, context ) } + + ); +}; + +export default BlockPreview; diff --git a/ui/js/blocks/src/blocks/components/FieldInspectorControls.js b/ui/js/blocks/src/blocks/components/FieldInspectorControls.js new file mode 100644 index 0000000000..60a9939f15 --- /dev/null +++ b/ui/js/blocks/src/blocks/components/FieldInspectorControls.js @@ -0,0 +1,49 @@ +/** + * WordPress dependencies + */ +import { PanelRow } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import RenderedField from './RenderedField'; + +/** + * Renders the fields that live in the Inspector on the sidebar. + * + * @param {Object} root0 + * @param {Array} root0.fields + * @param {Object} root0.attributes + * @param {Object} root0.setAttributes + */ +const FieldInspectorControls = ( { + fields = [], + attributes, + setAttributes, +} ) => { + if ( ! fields.length ) { + return null; + } + + return ( +
          + { fields.map( ( field ) => { + const { + name, + } = field; + + return ( + + + + ); + } ) } +
          + ); +}; + +export default FieldInspectorControls; diff --git a/ui/js/blocks/src/blocks/components/PodsServerSideRender.js b/ui/js/blocks/src/blocks/components/PodsServerSideRender.js new file mode 100644 index 0000000000..aa4e2014d0 --- /dev/null +++ b/ui/js/blocks/src/blocks/components/PodsServerSideRender.js @@ -0,0 +1,174 @@ +/** + * External dependencies + */ +import { debounce, isEqual } from 'lodash'; +import parse from 'html-react-parser'; + +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; +import { __, sprintf } from '@wordpress/i18n'; +import apiFetch from '@wordpress/api-fetch'; +import { addQueryArgs } from '@wordpress/url'; +import { Placeholder, Spinner } from '@wordpress/components'; +import { InnerBlocks } from '@wordpress/block-editor'; + +export function rendererPath( block, attributes = null, urlQueryArgs = {} ) { + return addQueryArgs( `/wp/v2/block-renderer/${ block }`, { + context: 'edit', + ...( null !== attributes ? { attributes } : {} ), + ...urlQueryArgs, + } ); +} + +export class PodsServerSideRender extends Component { + constructor( props ) { + super( props ); + this.state = { + response: null, + }; + } + + componentDidMount() { + this.isStillMounted = true; + this.fetch( this.props ); + // Only debounce once the initial fetch occurs to ensure that the first + // renders show data as soon as possible. + this.fetch = debounce( this.fetch, 500 ); + } + + componentWillUnmount() { + this.isStillMounted = false; + } + + componentDidUpdate( prevProps ) { + if ( ! isEqual( prevProps, this.props ) ) { + this.fetch( this.props ); + } + } + + fetch( props ) { + if ( ! this.isStillMounted ) { + return; + } + if ( null !== this.state.response ) { + this.setState( { response: null } ); + } + + // @todo Support preloaded block content that is already provided on page load. + + const { + block, + attributes = null, + httpMethod = 'GET', + urlQueryArgs = {}, + } = props; + + // If httpMethod is 'POST', send the attributes in the request body instead of the URL. + // This allows sending a larger attributes object than in a GET request, where the attributes are in the URL. + const isPostRequest = 'POST' === httpMethod; + const urlAttributes = isPostRequest ? null : attributes; + const path = rendererPath( block, urlAttributes, urlQueryArgs ); + const data = isPostRequest ? { attributes } : null; + + // Store the latest fetch request so that when we process it, we can + // check if it is the current request, to avoid race conditions on slow networks. + const fetchRequest = ( this.currentFetchRequest = apiFetch( { + path, + data, + method: isPostRequest ? 'POST' : 'GET', + } ) + .then( ( response ) => { + if ( + this.isStillMounted && + fetchRequest === this.currentFetchRequest && + response + ) { + this.setState( { response: response.rendered } ); + } + } ) + .catch( ( error ) => { + if ( this.isStillMounted && fetchRequest === this.currentFetchRequest ) { + this.setState( { + response: { + error: true, + errorMsg: error.message, + }, + } ); + } + } ) ); + + return fetchRequest; + } + + render() { + // @todo Support preloaded block content that is already provided on page load. + + const response = this.state.response; + const { + className, + EmptyResponsePlaceholder, + ErrorResponsePlaceholder, + LoadingResponsePlaceholder, + } = this.props; + + if ( response === '' ) { + return ; + } + if ( ! response ) { + return ( + + ); + } + if ( response.error ) { + return ( + + ); + } + + return parse( response, { + replace: ( domNode ) => { + if ( 'innerblocks' === domNode.name ) { + // Parse JSON-supported properties. + if ( 'undefined' !== typeof domNode.attribs.template ) { + domNode.attribs.template = JSON.parse( domNode.attribs.template ); + } + if ( 'undefined' !== typeof domNode.attribs.allowedBlocks ) { + domNode.attribs.allowedBlocks = JSON.parse( domNode.attribs.allowedBlocks ); + } + if ( 'undefined' !== typeof domNode.attribs.templateLock && 'false' === domNode.attribs.templateLock ) { + domNode.attribs.templateLock = false; + } + + return ; + } + }, + } ); + } +} + +PodsServerSideRender.defaultProps = { + EmptyResponsePlaceholder: ( { className } ) => ( + + { __( 'Block rendered as empty.' ) } + + ), + ErrorResponsePlaceholder: ( { response, className } ) => { + const errorMessage = sprintf( + // translators: %s: error message describing the problem + __( 'Error loading block: %s' ), + response.errorMsg + ); + return { errorMessage }; + }, + LoadingResponsePlaceholder: ( { className } ) => { + return ( + + + + ); + }, +}; + +export default PodsServerSideRender; diff --git a/ui/js/blocks/src/blocks/components/RenderedField.js b/ui/js/blocks/src/blocks/components/RenderedField.js new file mode 100644 index 0000000000..ebe81b569b --- /dev/null +++ b/ui/js/blocks/src/blocks/components/RenderedField.js @@ -0,0 +1,308 @@ +/** + * External dependencies + */ +import Select from 'react-select'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +import { + RichText, + MediaUploadCheck, + MediaUpload, +} from '@wordpress/block-editor'; + +import { + TextControl, + TextareaControl, + BaseControl, + DateTimePicker, + RadioControl, + ColorPicker, + Button, +} from '@wordpress/components'; + +import { useInstanceId } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import CheckboxGroup from '../../components/CheckboxGroup'; +import CheckboxControlExtended from '../../components/CheckboxControlExtended'; +import NumberControl from '../../components/NumberControl'; + +/** + * Creates the handler for the 'onChange' prop for a field. + * + * @param {string} name Name of the field. + * @param {Function} setAttributes The setAttributes function for a block. + * @param {string} type The type of attribute ('string', 'array', 'number'). + * + * @return {Function} Function update attributes to attach to an `onChange` prop. + */ +const createChangeHandler = ( name, setAttributes, type ) => ( newValue ) => { + setAttributes( { + [ name ]: 'NumberControl' === type ? parseInt( newValue, 10 ) : newValue, + } ); +}; + +/** + * Renders an individual field to be used in a template. + * + * @param {Object} root0 + * @param {Object} root0.field + * @param {Object} root0.attributes + * @param {Object} root0.setAttributes + */ +const RenderedField = ( { + field, + attributes, + setAttributes, +} ) => { + const { + name, + type, + fieldOptions = {}, + } = field; + + const fieldValue = attributes[ name ]; + + const changeHandler = createChangeHandler( name, setAttributes, type ); + + switch ( type ) { + case 'TextControl': { + const { + fieldType = 'text', + help, + label, + } = fieldOptions; + + return ( + + ); + } + case 'TextareaControl': { + const { + help, + label, + } = fieldOptions; + + return ( + + ); + } + case 'RichText': { + const { tagName = 'p' } = fieldOptions; + + return ( + + ); + } + case 'CheckboxControl': { + const { + label, + help, + heading = '', + } = fieldOptions; + + return ( + + ); + } + case 'CheckboxGroup': { + const { + help, + options, + heading = '', + } = fieldOptions; + + return ( + + ); + } + case 'RadioControl': { + const { + help, + options, + } = fieldOptions; + + return ( + + ); + } + case 'SelectControl': { + const { + options, + multiple, + label, + } = fieldOptions; + + const instanceId = useInstanceId( Select ); + const id = `inspector-select-control-${ instanceId }`; + + return ( + + + ); +} diff --git a/ui/js/blocks/src/config/html.js b/ui/js/blocks/src/config/html.js new file mode 100644 index 0000000000..6be415b438 --- /dev/null +++ b/ui/js/blocks/src/config/html.js @@ -0,0 +1,73 @@ +export const richText = { + allowedTags: [ + // Block elements + 'blockquote', 'caption', 'div', 'figcaption', 'figure', 'h1', 'h2', + 'h3', 'h4', 'h5', 'h6', 'hr', 'li', 'ol', 'p', 'pre', 'section', + 'table', 'tbody', 'td', 'th', 'thead', 'tr', 'ul', + // Inline elements + 'a', 'abbr', 'acronym', 'audio', 'b', 'bdi', 'bdo', 'big', 'br', + 'button', 'canvas', 'cite', 'code', 'data', 'datalist', 'del', 'dfn', + 'em', 'embed', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', + 'map', 'mark', 'meter', 'noscript', 'object', 'output', 'picture', + 'progress', 'q', 'ruby', 's', 'samp', 'select', 'slot', + 'small', 'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', + 'time', 'u', 'tt', 'var', 'video', 'wbr', + ], + allowedAttributes: { + '*': [ 'class', 'id', 'data-*', 'style' ], + iframe: [ '*' ], + a: [ 'href', 'name', 'target' ], + img: [ 'src', 'srcset', 'sizes', 'alt', 'width', 'height' ], + }, + selfClosing: [ + 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta', + ], + allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ], + allowedSchemesByTag: {}, + allowProtocolRelative: true, +}; + +export const richTextInlineOnly = { + allowedTags: [ + 'a', 'abbr', 'acronym', 'audio', 'b', 'bdi', 'bdo', 'big', 'br', + 'button', 'canvas', 'cite', 'code', 'data', 'datalist', 'del', 'dfn', + 'em', 'embed', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', + 'map', 'mark', 'meter', 'noscript', 'object', 'output', 'picture', + 'progress', 'q', 'ruby', 's', 'samp', 'select', 'slot', + 'small', 'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', + 'time', 'u', 'tt', 'var', 'video', 'wbr', + ], + allowedAttributes: { + '*': [ 'class', 'id', 'data-*', 'style' ], + a: [ 'href', 'name', 'target' ], + img: [ 'src', 'srcset', 'sizes', 'alt', 'width', 'height' ], + }, + selfClosing: [ + 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta', + ], + allowedSchemes: [ 'http', 'https', 'ftp', 'mailto' ], + allowedSchemesByTag: {}, + allowProtocolRelative: true, +}; + +export const richTextNoLinks = { + allowedTags: [ + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'ul', 'ol', + 'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'cite', 'hr', 'br', + 'div', 'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', 'img', + 'figure', 'figcaption', 'iframe', 'section', + ], + allowedAttributes: { + '*': [ 'class', 'id', 'data-*', 'style' ], + iframe: [ '*' ], + img: [ 'src', 'srcset', 'sizes', 'alt', 'width', 'height' ], + }, + selfClosing: [ + 'img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta', + ], +}; + +export const plainText = { + allowedTags: [], + allowedAttributes: {}, +}; diff --git a/ui/js/blocks/src/editor.css b/ui/js/blocks/src/editor.css new file mode 100644 index 0000000000..de89d98c89 --- /dev/null +++ b/ui/js/blocks/src/editor.css @@ -0,0 +1,8 @@ +.pods-inspector-row .components-datetime { + padding-left: 0; + padding-right: 0; +} + +.pods-inspector-row .full-width-base-control { + width: 100%; +} diff --git a/ui/js/blocks/src/index.js b/ui/js/blocks/src/index.js new file mode 100644 index 0000000000..48280818b0 --- /dev/null +++ b/ui/js/blocks/src/index.js @@ -0,0 +1,11 @@ +/** + * Internal dependencies + */ +import createBlockCollection from './block-collections'; +import createBlock from './blocks'; + +// Register block collections from the config. +window.podsBlocksConfig.collections.forEach( createBlockCollection ); + +// Register blocks from the config. +window.podsBlocksConfig.blocks.forEach( createBlock ); diff --git a/ui/js/blocks/src/testData.js b/ui/js/blocks/src/testData.js new file mode 100644 index 0000000000..89107f117b --- /dev/null +++ b/ui/js/blocks/src/testData.js @@ -0,0 +1,221 @@ +// Fields +export const textField = { + type: 'TextControl', + name: 'textField', + fieldOptions: { + className: 'text__container', + type: 'text', + help: 'Some help text', + label: 'Label for the text field', + }, + attributeOptions: { + selector: '.text__container', + source: 'text', + }, +}; + +export const textareaField = { + type: 'TextareaControl', + name: 'textareaField', + fieldOptions: { + className: 'textarea__container', + help: 'Some help text', + label: 'Label for the textarea field', + }, + attributeOptions: { + selector: '.textarea__container', + source: 'text', + }, +}; + +export const richTextField = { + type: 'RichText', + name: 'richTextField', + fieldOptions: { + tagName: 'p', + className: 'custom__container', + }, + attributeOptions: { + selector: '.custom__container', + source: 'html', + }, +}; + +export const checkboxField = { + type: 'CheckboxControl', + name: 'checkboxField', + fieldOptions: { + heading: 'Checkbox Field', + label: 'Checkbox Test', + help: 'Additional help text', + }, + attributeOptions: { + type: 'boolean', + default: true, + }, +}; + +export const checkboxGroup = { + type: 'CheckboxGroup', + name: 'checkboxGroup', + fieldOptions: { + heading: 'Checkbox Field', + help: 'Additional help text', + options: [ + { label: 'First Option', value: 'first' }, + { label: 'Second Option', value: 'second' }, + { label: 'Third Option', value: 'third' }, + ], + }, + attributeOptions: { + type: 'array', + }, +}; + +export const radioField = { + type: 'RadioControl', + name: 'radioField', + fieldOptions: { + heading: 'Radio Field', + help: 'Additional help text', + options: [ + { label: 'First Option', value: 'first' }, + { label: 'Second Option', value: 'second' }, + { label: 'Third Option', value: 'third' }, + ], + }, + attributeOptions: { + type: 'array', + }, +}; + +export const selectField = { + type: 'SelectControl', + name: 'selectField', + fieldOptions: { + heading: 'Select Field', + help: 'Additional help text', + options: [ + { label: 'First Option', value: 'first' }, + { label: 'Second Option', value: 'second' }, + { label: 'Third Option', value: 'third' }, + ], + }, + attributeOptions: { + type: 'array', + }, +}; + +export const dateTimeField = { + type: 'DateTimePicker', + name: 'dateTimeField', + fieldOptions: { + is12Hour: true, + label: 'Label for the datetime field', + }, + attributeOptions: { + type: 'string', + }, +}; + +export const numberField = { + type: 'NumberControl', + name: 'numberField', + fieldOptions: { + isShiftStepEnabled: false, + shiftStep: false, + step: 1, + label: 'Label for the number field', + }, + attributeOptions: { + type: 'number', + }, +}; + +// Templates +export const basicTemplate = '
          Something else here and a field: {@textField}
          '; + +export const multipleFieldsTemplate = '
          A field with content: {@textField}

          And a number: {@numberField}
          '; + +export const templateWithEveryFieldType = `
          + A text field: {@textField} + A textarea field: {@textareaField} + A rich text field: {@richTextField} + A checkbox field: {@checkboxField} + A group of checkboxes: {@checkboxGroup} + A group of radio buttons: {@radioField} + A select menu: {@selectField} + A date/time field: {@dateTimeField} + A number field: {@numberField} +
          `; + +// Full Blocks +export const simpleBlock = { + blockName: 'test/custom-block', + renderType: 'js', + category: 'layout', + description: 'A block to test defining the fields.', + icon: 'editor-insertmore', + keywords: [ 'test' ], + supports: { + html: false, + }, + title: 'Custom Block', + renderTemplate: basicTemplate, + fields: [ + textField, + checkboxField, + ], +}; + +export const simpleBlockProps = { + className: 'simple-block-test', + attributes: { + textField: 'Some content', + checkboxField: true, + }, +}; + +export const allFieldsBlock = { + blockName: 'test/all-fields', + renderType: 'js', + category: 'layout', + description: 'A block to test all supported fields.', + icon: 'editor-insertmore', + keywords: [ 'test' ], + supports: { + html: false, + }, + title: 'All Field Block', + renderTemplate: templateWithEveryFieldType, + fields: [ + textField, + textareaField, + richTextField, + checkboxField, + checkboxGroup, + radioField, + selectField, + dateTimeField, + numberField, + ], +}; + +export const allFieldsBlockProps = { + className: 'all-fields-block-test', + attributes: { + textField: 'Content for the text field, but these tags will be stripped out', + textareaField: 'Content for the textarea field, but these tags will be stripped out', + richTextField: 'Some content', + checkboxField: true, + checkboxGroup: [ + { value: 'first', checked: true }, + { value: 'second', checked: true }, + { value: 'third', checked: false }, + ], + radioField: 'first', + selectField: 'second', + dateTimeField: '1986-10-18T23:00:00', + numberField: 123456, + }, +}; diff --git a/ui/js/blocks/src/utils/renderBlockTemplate.js b/ui/js/blocks/src/utils/renderBlockTemplate.js new file mode 100644 index 0000000000..f756facc20 --- /dev/null +++ b/ui/js/blocks/src/utils/renderBlockTemplate.js @@ -0,0 +1,65 @@ +/** + * External dependencies + */ +import { renderToString } from '@wordpress/element'; +import parse from 'html-react-parser'; +import sanitizeHtml from 'sanitize-html'; + +/** + * Internal dependencies + */ +import { richText } from '../config/html'; + +/** + * Renders the edit template into an edit component. + * + * @todo Is there a more efficient way to do this without + * rendering React components to a string, then parsing the + * final string back to a React component? The parser may have + * callbacks that we can use. + * + * @param {string} renderTemplate Template string. + * @param {Object} fields Fields used in the Block. + * @param {Object} attributes Block attributes with values. + * @param {Function} renderField Function that should return a rendered field. + * @param {Function} setAttributes setAttributes function for the block (Optional). + */ +const renderBlockTemplate = ( + renderTemplate = '', + fields = [], + attributes = {}, + renderField, + setAttributes +) => { + let htmlWithRenderedFields = sanitizeHtml( renderTemplate, richText ); + + // Replace all of the placeholders in the format of `{@fieldName}` with the + // rendered field. To do this, we first need to create the React component for + // the field, then convert it down into a string. To avoid losing any of the props + // during this conversion, we're saving any props from the component based on the name. + // At the end, the whole string will be parsed back into React components. + const savedProps = []; + + fields.forEach( ( field ) => { + // Our renderField may or may not take a setAttributes function as a parameter. + const fieldComponent = ( 'function' === typeof setAttributes ) + ? renderField( field, attributes, setAttributes ) + : renderField( field, attributes ); + + if ( !! fieldComponent ) { + savedProps[ field.name ] = { ...fieldComponent.props }; + } + + const renderedField = !! fieldComponent ? renderToString( fieldComponent ) : ''; + + htmlWithRenderedFields = htmlWithRenderedFields.replace( + new RegExp( `{@${ field.name }}`, 'g' ), + renderedField + ); + } ); + + // @todo Support + return parse( htmlWithRenderedFields ); +}; + +export default renderBlockTemplate; diff --git a/ui/js/blocks/src/utils/test/renderBlockTemplate.test.js b/ui/js/blocks/src/utils/test/renderBlockTemplate.test.js new file mode 100644 index 0000000000..1938bb9289 --- /dev/null +++ b/ui/js/blocks/src/utils/test/renderBlockTemplate.test.js @@ -0,0 +1,70 @@ +/** + * External dependencies + */ +import { mount } from 'enzyme'; + +/** + * Internal dependencies + */ +import renderBlockTemplate from '../renderBlockTemplate'; + +import { + textField, + numberField, + basicTemplate, + multipleFieldsTemplate, +} from '../../testData'; + +// Simplest possible function to render a field. +const renderField = ( field, attributes = {} ) => { + const { name, type } = field; + + const fieldValue = attributes[ name ] || null; + + return ( + + { fieldValue } + + ); +}; + +const fields = [ + textField, + numberField, +]; + +describe( 'renderBlockTemplate', () => { + it( 'renders simple template with no setAttributes function included', () => { + const renderedTree = renderBlockTemplate( + basicTemplate, + fields, + { + textField: 'Test value', + }, + renderField + ); + + const wrapper = mount( renderedTree ); + + expect( wrapper.find( '.field--TextControl' ) ).toHaveLength( 1 ); + expect( wrapper.find( '.field--TextControl' ).text() ).toBe( 'Test value' ); + } ); + + it( 'renders more complex template with no setAttributes function included', () => { + const renderedTree = renderBlockTemplate( + multipleFieldsTemplate, + fields, + { + textField: 'Test value', + numberField: 4, + }, + renderField + ); + + const wrapper = mount( renderedTree ); + + expect( wrapper.find( 'div' ) ).toHaveLength( 3 ); + expect( wrapper.find( '.field--TextControl' ).text() ).toBe( 'Test value' ); + expect( wrapper.find( '.field--NumberControl' ).text() ).toBe( '4' ); + } ); +} ); diff --git a/ui/js/dfv/pods-dfv.min.asset.json b/ui/js/dfv/pods-dfv.min.asset.json new file mode 100644 index 0000000000..3857e4d6a1 --- /dev/null +++ b/ui/js/dfv/pods-dfv.min.asset.json @@ -0,0 +1 @@ +{"dependencies":["moment","wp-api-fetch","wp-autop","wp-components","wp-compose","wp-data","wp-element","wp-i18n","wp-keycodes","wp-plugins","wp-primitives","wp-url"],"version":"24a252ba15d83803f1b7826ab7b44b4c"} \ No newline at end of file diff --git a/ui/js/dfv/pods-dfv.min.js b/ui/js/dfv/pods-dfv.min.js new file mode 100644 index 0000000000..bf0e1194c7 --- /dev/null +++ b/ui/js/dfv/pods-dfv.min.js @@ -0,0 +1 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=240)}([function(e,t){e.exports=React},function(e,t,n){e.exports=n(58)()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t,n){"use strict";n.d(t,"a",(function(){return d})),n.d(t,"b",(function(){return l})),n.d(t,"c",(function(){return s})),n.d(t,"d",(function(){return u}));var r=n(0),o=(n(38),n(10)),i=(n(50),n(27),n(39),n(23)),a=n(25),s=(n(33),function(e,t){var n=arguments;if(null==t||!o.e.call(t,"css"))return r.createElement.apply(void 0,n);var i=n.length,a=new Array(i);a[0]=o.b,a[1]=Object(o.d)(e,t);for(var s=2;s-1}function C(e){return E(e)?window.pageYOffset:e.scrollTop}function N(e,t){E(e)?window.scrollTo(0,t):e.scrollTop=t}function A(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function q(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:200,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:w,o=C(e),i=t-o,a=10,s=0;function l(){var t=A(s+=a,o,i,n);N(e,t),sn.bottom?N(e,Math.min(t.offsetTop+t.clientHeight-e.offsetHeight+o,e.scrollHeight)):r.top-o=p)return{placement:"bottom",maxHeight:t};if(O>=p&&!a)return i&&q(l,k,160),{placement:"bottom",maxHeight:t};if(!a&&O>=r||a&&w>=r)return i&&q(l,k,160),{placement:"bottom",maxHeight:a?w-b:O-b};if("auto"===o||a){var j=t,E=a?_:x;return E>=r&&(j=Math.min(E-b-s.controlHeight,t)),{placement:"top",maxHeight:j}}if("bottom"===o)return i&&N(l,k),{placement:"bottom",maxHeight:t};break;case"top":if(_>=p)return{placement:"top",maxHeight:t};if(x>=p&&!a)return i&&q(l,S,160),{placement:"top",maxHeight:t};if(!a&&x>=r||a&&_>=r){var A=t;return(!a&&x>=r||a&&_>=r)&&(A=a?_-y:x-y),i&&q(l,S,160),{placement:"top",maxHeight:A}}return{placement:"bottom",maxHeight:t};default:throw new Error('Invalid placement provided "'.concat(o,'".'))}return u}var B=function(e){return"auto"===e?"bottom":e},U=function(e){var t,n=e.placement,r=e.theme,o=r.borderRadius,i=r.spacing,a=r.colors;return t={label:"menu"},Object(d.a)(t,function(e){return e?{bottom:"top",top:"bottom"}[e]:"bottom"}(n),"100%"),Object(d.a)(t,"backgroundColor",a.neutral0),Object(d.a)(t,"borderRadius",o),Object(d.a)(t,"boxShadow","0 0 0 1px hsla(0, 0%, 0%, 0.1), 0 4px 11px hsla(0, 0%, 0%, 0.1)"),Object(d.a)(t,"marginBottom",i.menuGutter),Object(d.a)(t,"marginTop",i.menuGutter),Object(d.a)(t,"position","absolute"),Object(d.a)(t,"width","100%"),Object(d.a)(t,"zIndex",1),t},V=Object(p.createContext)({getPortalPlacement:null}),z=function(e){Object(f.a)(n,e);var t=_(n);function n(){var e;Object(u.a)(this,n);for(var r=arguments.length,o=new Array(r),i=0;i0?h(S,--O):0,w--,10===k&&(w=1,_--),k}function N(){return k=O2||P(k)>3?"":" "}function I(e,t){for(;--t&&N()&&!(k<48||k>102||k>57&&k<65||k>70&&k<97););return T(e,q()+(t<6&&32==A()&&32==N()))}function F(e,t){for(;N()&&e+k!==57&&(e+k!==84||47!==A()););return"/*"+T(t,O-1)+"*"+c(47===e?e:N())}function B(e){for(;!P(A());)N();return T(e,O)}function U(e){return L(function e(t,n,r,o,i,a,s,l,u){var f=0,p=0,h=s,m=0,v=0,y=0,_=1,w=1,x=1,O=0,k="",S=i,j=a,E=o,T=k;for(;w;)switch(y=O,O=N()){case 34:case 39:case 91:case 40:T+=D(O);break;case 9:case 10:case 13:case 32:T+=R(y);break;case 92:T+=I(q()-1,7);continue;case 47:switch(A()){case 42:case 47:b(z(F(N(),q()),n,r),u);break;default:T+="/"}break;case 123*_:l[f++]=g(T)*x;case 125*_:case 59:case 0:switch(O){case 0:case 125:w=0;case 59+p:v>0&&g(T)-h&&b(v>32?H(T+";",o,r,h-1):H(d(T," ","")+";",o,r,h-2),u);break;case 59:T+=";";default:if(b(E=V(T,n,r,f,p,i,l,k,S=[],j=[],h),a),123===O)if(0===p)e(T,n,E,E,S,a,h,l,j);else switch(m){case 100:case 109:case 115:e(t,E,E,o&&b(V(t,E,E,0,0,i,l,k,i,S=[],h),j),i,j,h,l,o?S:j);break;default:e(T,E,E,E,[""],j,h,l,j)}}f=p=v=0,_=x=1,k=T="",h=s;break;case 58:h=1+g(T),v=y;default:if(_<1)if(123==O)--_;else if(125==O&&0==_++&&125==C())continue;switch(T+=c(O),O*_){case 38:x=p>0?1:(T+="\f",-1);break;case 44:l[f++]=(g(T)-1)*x,x=1;break;case 64:45===A()&&(T+=D(N())),m=A(),p=g(k=T+=B(q())),O++;break;case 45:45===y&&2==g(T)&&(_=0)}}return a}("",null,null,null,[""],e=M(e),0,[0],e))}function V(e,t,n,r,o,i,a,l,c,p,h){for(var g=o-1,b=0===o?i:[""],y=v(b),_=0,w=0,x=0;_0?b[O]+" "+k:d(k,/&\f/g,b[O])))&&(c[x++]=S);return j(e,t,n,0===o?s:l,c,p,h)}function z(e,t,n){return j(e,t,n,a,c(k),m(e,2,-2),0)}function H(e,t,n,r){return j(e,t,n,l,m(e,0,r),m(e,r+1,-1),r)}function W(e,t){switch(function(e,t){return(((t<<2^h(e,0))<<2^h(e,1))<<2^h(e,2))<<2^h(e,3)}(e,t)){case 5103:return i+"print-"+e+e;case 5737:case 4201:case 3177:case 3433:case 1641:case 4457:case 2921:case 5572:case 6356:case 5844:case 3191:case 6645:case 3005:case 6391:case 5879:case 5623:case 6135:case 4599:case 4855:case 4215:case 6389:case 5109:case 5365:case 5621:case 3829:return i+e+e;case 5349:case 4246:case 4810:case 6968:case 2756:return i+e+o+e+r+e+e;case 6828:case 4268:return i+e+r+e+e;case 6165:return i+e+r+"flex-"+e+e;case 5187:return i+e+d(e,/(\w+).+(:[^]+)/,i+"box-$1$2"+r+"flex-$1$2")+e;case 5443:return i+e+r+"flex-item-"+d(e,/flex-|-self/,"")+e;case 4675:return i+e+r+"flex-line-pack"+d(e,/align-content|flex-|-self/,"")+e;case 5548:return i+e+r+d(e,"shrink","negative")+e;case 5292:return i+e+r+d(e,"basis","preferred-size")+e;case 6060:return i+"box-"+d(e,"-grow","")+i+e+r+d(e,"grow","positive")+e;case 4554:return i+d(e,/([^-])(transform)/g,"$1"+i+"$2")+e;case 6187:return d(d(d(e,/(zoom-|grab)/,i+"$1"),/(image-set)/,i+"$1"),e,"")+e;case 5495:case 3959:return d(e,/(image-set\([^]*)/,i+"$1$`$1");case 4968:return d(d(e,/(.+:)(flex-)?(.*)/,i+"box-pack:$3"+r+"flex-pack:$3"),/s.+-b[^;]+/,"justify")+i+e+e;case 4095:case 3583:case 4068:case 2532:return d(e,/(.+)-inline(.+)/,i+"$1$2")+e;case 8116:case 7059:case 5753:case 5535:case 5445:case 5701:case 4933:case 4677:case 5533:case 5789:case 5021:case 4765:if(g(e)-1-t>6)switch(h(e,t+1)){case 109:if(45!==h(e,t+4))break;case 102:return d(e,/(.+:)(.+)-([^]+)/,"$1"+i+"$2-$3$1"+o+(108==h(e,t+3)?"$3":"$2-$3"))+e;case 115:return~p(e,"stretch")?W(d(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(115!==h(e,t+1))break;case 6444:switch(h(e,g(e)-3-(~p(e,"!important")&&10))){case 107:return d(e,":",":"+i)+e;case 101:return d(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+i+(45===h(e,14)?"inline-":"")+"box$3$1"+i+"$2$3$1"+r+"$2box$3")+e}break;case 5936:switch(h(e,t+11)){case 114:return i+e+r+d(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return i+e+r+d(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return i+e+r+d(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return i+e+r+e+e}return e}function G(e,t){for(var n="",r=v(e),o=0;o=0&&f.splice(t,1)}function v(e){var t=document.createElement("style");if(void 0===e.attrs.type&&(e.attrs.type="text/css"),void 0===e.attrs.nonce){var r=function(){0;return n.nc}();r&&(e.attrs.nonce=r)}return b(t,e.attrs),m(e,t),t}function b(e,t){Object.keys(t).forEach((function(n){e.setAttribute(n,t[n])}))}function y(e,t){var n,r,o,i;if(t.transform&&e.css){if(!(i="function"==typeof t.transform?t.transform(e.css):t.transform.default(e.css)))return function(){};e.css=i}if(t.singleton){var a=c++;n=u||(u=v(t)),r=x.bind(null,n,a,!1),o=x.bind(null,n,a,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",b(t,e.attrs),m(e,t),t}(t),r=k.bind(null,n,t),o=function(){g(n),n.href&&URL.revokeObjectURL(n.href)}):(n=v(t),r=O.bind(null,n),o=function(){g(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else o()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=a()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=h(e,t);return p(n,t),function(e){for(var r=[],o=0;o=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,"a",(function(){return r}))},function(e,t,n){"use strict";function r(e,t){for(var n=0;n=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,s=!1;return{s:function(){n=e[Symbol.iterator]()},n:function(){var e=n.next();return a=e.done,e},e:function(e){s=!0,i=e},f:function(){try{a||null==n.return||n.return()}finally{if(s)throw i}}}}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0?a-4:a;for(n=0;n>16&255,l[c++]=t>>8&255,l[c++]=255&t;return 2===s&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,l[c++]=255&t),1===s&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,l[c++]=t>>8&255,l[c++]=255&t),l},n.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));return 1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"=")),i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,l=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function c(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},{}],2:[function(e,t,n){},{}],3:[function(e,t,n){(function(t){var r=e("base64-js"),o=e("ieee754");function i(e){if(e>2147483647)throw new RangeError('The value "'+e+'" is invalid for option "size"');var n=new Uint8Array(e);return n.__proto__=t.prototype,n}function t(e,t,n){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return l(e)}return a(e,t,n)}function a(e,n,r){if("string"==typeof e)return function(e,n){if("string"==typeof n&&""!==n||(n="utf8"),!t.isEncoding(n))throw new TypeError("Unknown encoding: "+n);var r=0|d(e,n),o=i(r),a=o.write(e,n);return a!==r&&(o=o.slice(0,a)),o}(e,n);if(ArrayBuffer.isView(e))return c(e);if(null==e)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+u(e));if(I(e,ArrayBuffer)||e&&I(e.buffer,ArrayBuffer))return function(e,n,r){if(n<0||e.byteLength=2147483647)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+2147483647..toString(16)+" bytes");return 0|e}function d(e,n){if(t.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||I(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+u(e));var r=e.length,o=arguments.length>2&&!0===arguments[2];if(!o&&0===r)return 0;for(var i=!1;;)switch(n){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return L(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return D(e).length;default:if(i)return o?-1:L(e).length;n=(""+n).toLowerCase(),i=!0}}function p(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return E(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return S(this,t,n);case"latin1":case"binary":return j(this,t,n);case"base64":return O(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function h(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function m(e,n,r,o,i){if(0===e.length)return-1;if("string"==typeof r?(o=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),F(r=+r)&&(r=i?0:e.length-1),r<0&&(r=e.length+r),r>=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof n&&(n=t.from(n,o)),t.isBuffer(n))return 0===n.length?-1:g(e,n,r,o,i);if("number"==typeof n)return n&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,n,r):Uint8Array.prototype.lastIndexOf.call(e,n,r):g(e,[n],r,o,i);throw new TypeError("val must be string, number or Buffer")}function g(e,t,n,r,o){var i,a=1,s=e.length,l=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,l/=2,n/=2}function u(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var c=-1;for(i=n;is&&(n=s-l),i=n;i>=0;i--){for(var f=!0,d=0;do&&(r=o):r=o;var i=t.length;r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function O(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:u>223?3:u>191?2:1;if(o+f<=n)switch(f){case 1:u<128&&(c=u);break;case 2:128==(192&(i=e[o+1]))&&(l=(31&u)<<6|63&i)>127&&(c=l);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(l=(15&u)<<12|(63&i)<<6|63&a)>2047&&(l<55296||l>57343)&&(c=l);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(l=(15&u)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&l<1114112&&(c=l)}null===c?(c=65533,f=1):c>65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c),o+=f}return function(e){var t=e.length;if(t<=4096)return String.fromCharCode.apply(String,e);for(var n="",r=0;ro)&&(n=o);for(var i="",a=t;an)throw new RangeError("Trying to access beyond buffer length")}function A(e,n,r,o,i,a){if(!t.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(n>i||ne.length)throw new RangeError("Index out of range")}function q(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function T(e,t,n,r,i){return t=+t,n>>>=0,i||q(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function P(e,t,n,r,i){return t=+t,n>>>=0,i||q(e,0,n,8),o.write(e,t,n,r,52,8),n+8}n.Buffer=t,n.SlowBuffer=function(e){return+e!=e&&(e=0),t.alloc(+e)},n.INSPECT_MAX_BYTES=50,n.kMaxLength=2147483647,t.TYPED_ARRAY_SUPPORT=function(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()}catch(e){return!1}}(),t.TYPED_ARRAY_SUPPORT||"undefined"==typeof console||"function"!=typeof console.error||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(t.prototype,"parent",{enumerable:!0,get:function(){if(t.isBuffer(this))return this.buffer}}),Object.defineProperty(t.prototype,"offset",{enumerable:!0,get:function(){if(t.isBuffer(this))return this.byteOffset}}),"undefined"!=typeof Symbol&&null!=Symbol.species&&t[Symbol.species]===t&&Object.defineProperty(t,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),t.poolSize=8192,t.from=function(e,t,n){return a(e,t,n)},t.prototype.__proto__=Uint8Array.prototype,t.__proto__=Uint8Array,t.alloc=function(e,t,n){return function(e,t,n){return s(e),e<=0?i(e):void 0!==t?"string"==typeof n?i(e).fill(t,n):i(e).fill(t):i(e)}(e,t,n)},t.allocUnsafe=function(e){return l(e)},t.allocUnsafeSlow=function(e){return l(e)},t.isBuffer=function(e){return null!=e&&!0===e._isBuffer&&e!==t.prototype},t.compare=function(e,n){if(I(e,Uint8Array)&&(e=t.from(e,e.offset,e.byteLength)),I(n,Uint8Array)&&(n=t.from(n,n.offset,n.byteLength)),!t.isBuffer(e)||!t.isBuffer(n))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(e===n)return 0;for(var r=e.length,o=n.length,i=0,a=Math.min(r,o);it&&(e+=" ... "),""},t.prototype.compare=function(e,n,r,o,i){if(I(e,Uint8Array)&&(e=t.from(e,e.offset,e.byteLength)),!t.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+u(e));if(void 0===n&&(n=0),void 0===r&&(r=e?e.length:0),void 0===o&&(o=0),void 0===i&&(i=this.length),n<0||r>e.length||o<0||i>this.length)throw new RangeError("out of range index");if(o>=i&&n>=r)return 0;if(o>=i)return-1;if(n>=r)return 1;if(this===e)return 0;for(var a=(i>>>=0)-(o>>>=0),s=(r>>>=0)-(n>>>=0),l=Math.min(a,s),c=this.slice(o,i),f=e.slice(n,r),d=0;d>>=0,isFinite(n)?(n>>>=0,void 0===r&&(r="utf8")):(r=n,n=void 0)}var o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return v(this,e,t,n);case"utf8":case"utf-8":return b(this,e,t,n);case"ascii":return y(this,e,t,n);case"latin1":case"binary":return _(this,e,t,n);case"base64":return w(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},t.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}},t.prototype.slice=function(e,n){var r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(n=void 0===n?r:~~n)<0?(n+=r)<0&&(n=0):n>r&&(n=r),n>>=0,t>>>=0,n||N(e,t,this.length);for(var r=this[e],o=1,i=0;++i>>=0,t>>>=0,n||N(e,t,this.length);for(var r=this[e+--t],o=1;t>0&&(o*=256);)r+=this[e+--t]*o;return r},t.prototype.readUInt8=function(e,t){return e>>>=0,t||N(e,1,this.length),this[e]},t.prototype.readUInt16LE=function(e,t){return e>>>=0,t||N(e,2,this.length),this[e]|this[e+1]<<8},t.prototype.readUInt16BE=function(e,t){return e>>>=0,t||N(e,2,this.length),this[e]<<8|this[e+1]},t.prototype.readUInt32LE=function(e,t){return e>>>=0,t||N(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},t.prototype.readUInt32BE=function(e,t){return e>>>=0,t||N(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},t.prototype.readIntLE=function(e,t,n){e>>>=0,t>>>=0,n||N(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},t.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||N(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},t.prototype.readInt8=function(e,t){return e>>>=0,t||N(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},t.prototype.readInt16LE=function(e,t){e>>>=0,t||N(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},t.prototype.readInt16BE=function(e,t){e>>>=0,t||N(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},t.prototype.readInt32LE=function(e,t){return e>>>=0,t||N(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},t.prototype.readInt32BE=function(e,t){return e>>>=0,t||N(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},t.prototype.readFloatLE=function(e,t){return e>>>=0,t||N(e,4,this.length),o.read(this,e,!0,23,4)},t.prototype.readFloatBE=function(e,t){return e>>>=0,t||N(e,4,this.length),o.read(this,e,!1,23,4)},t.prototype.readDoubleLE=function(e,t){return e>>>=0,t||N(e,8,this.length),o.read(this,e,!0,52,8)},t.prototype.readDoubleBE=function(e,t){return e>>>=0,t||N(e,8,this.length),o.read(this,e,!1,52,8)},t.prototype.writeUIntLE=function(e,t,n,r){e=+e,t>>>=0,n>>>=0,r||A(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i>>=0,n>>>=0,r||A(this,e,t,n,Math.pow(2,8*n)-1,0);var o=n-1,i=1;for(this[t+o]=255&e;--o>=0&&(i*=256);)this[t+o]=e/i&255;return t+n},t.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,1,255,0),this[t]=255&e,t+1},t.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},t.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},t.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},t.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},t.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var o=Math.pow(2,8*n-1);A(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},t.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t>>>=0,!r){var o=Math.pow(2,8*n-1);A(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},t.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},t.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},t.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},t.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},t.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||A(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},t.prototype.writeFloatLE=function(e,t,n){return T(this,e,t,!0,n)},t.prototype.writeFloatBE=function(e,t,n){return T(this,e,t,!1,n)},t.prototype.writeDoubleLE=function(e,t,n){return P(this,e,t,!0,n)},t.prototype.writeDoubleBE=function(e,t,n){return P(this,e,t,!1,n)},t.prototype.copy=function(e,n,r,o){if(!t.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),o||0===o||(o=this.length),n>=e.length&&(n=e.length),n||(n=0),o>0&&o=this.length)throw new RangeError("Index out of range");if(o<0)throw new RangeError("sourceEnd out of bounds");o>this.length&&(o=this.length),e.length-n=0;--a)e[a+n]=this[a+r];else Uint8Array.prototype.set.call(e,this.subarray(r,o),n);return i},t.prototype.fill=function(e,n,r,o){if("string"==typeof e){if("string"==typeof n?(o=n,n=0,r=this.length):"string"==typeof r&&(o=r,r=this.length),void 0!==o&&"string"!=typeof o)throw new TypeError("encoding must be a string");if("string"==typeof o&&!t.isEncoding(o))throw new TypeError("Unknown encoding: "+o);if(1===e.length){var i=e.charCodeAt(0);("utf8"===o&&i<128||"latin1"===o)&&(e=i)}}else"number"==typeof e&&(e&=255);if(n<0||this.length>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(a=n;a55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function D(e){return r.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(M,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function R(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}function I(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function F(e){return e!=e}}).call(this,e("buffer").Buffer)},{"base64-js":1,buffer:3,ieee754:32}],4:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.attributeNames=n.elementNames=void 0,n.elementNames=new Map([["altglyph","altGlyph"],["altglyphdef","altGlyphDef"],["altglyphitem","altGlyphItem"],["animatecolor","animateColor"],["animatemotion","animateMotion"],["animatetransform","animateTransform"],["clippath","clipPath"],["feblend","feBlend"],["fecolormatrix","feColorMatrix"],["fecomponenttransfer","feComponentTransfer"],["fecomposite","feComposite"],["feconvolvematrix","feConvolveMatrix"],["fediffuselighting","feDiffuseLighting"],["fedisplacementmap","feDisplacementMap"],["fedistantlight","feDistantLight"],["fedropshadow","feDropShadow"],["feflood","feFlood"],["fefunca","feFuncA"],["fefuncb","feFuncB"],["fefuncg","feFuncG"],["fefuncr","feFuncR"],["fegaussianblur","feGaussianBlur"],["feimage","feImage"],["femerge","feMerge"],["femergenode","feMergeNode"],["femorphology","feMorphology"],["feoffset","feOffset"],["fepointlight","fePointLight"],["fespecularlighting","feSpecularLighting"],["fespotlight","feSpotLight"],["fetile","feTile"],["feturbulence","feTurbulence"],["foreignobject","foreignObject"],["glyphref","glyphRef"],["lineargradient","linearGradient"],["radialgradient","radialGradient"],["textpath","textPath"]]),n.attributeNames=new Map([["definitionurl","definitionURL"],["attributename","attributeName"],["attributetype","attributeType"],["basefrequency","baseFrequency"],["baseprofile","baseProfile"],["calcmode","calcMode"],["clippathunits","clipPathUnits"],["diffuseconstant","diffuseConstant"],["edgemode","edgeMode"],["filterunits","filterUnits"],["glyphref","glyphRef"],["gradienttransform","gradientTransform"],["gradientunits","gradientUnits"],["kernelmatrix","kernelMatrix"],["kernelunitlength","kernelUnitLength"],["keypoints","keyPoints"],["keysplines","keySplines"],["keytimes","keyTimes"],["lengthadjust","lengthAdjust"],["limitingconeangle","limitingConeAngle"],["markerheight","markerHeight"],["markerunits","markerUnits"],["markerwidth","markerWidth"],["maskcontentunits","maskContentUnits"],["maskunits","maskUnits"],["numoctaves","numOctaves"],["pathlength","pathLength"],["patterncontentunits","patternContentUnits"],["patterntransform","patternTransform"],["patternunits","patternUnits"],["pointsatx","pointsAtX"],["pointsaty","pointsAtY"],["pointsatz","pointsAtZ"],["preservealpha","preserveAlpha"],["preserveaspectratio","preserveAspectRatio"],["primitiveunits","primitiveUnits"],["refx","refX"],["refy","refY"],["repeatcount","repeatCount"],["repeatdur","repeatDur"],["requiredextensions","requiredExtensions"],["requiredfeatures","requiredFeatures"],["specularconstant","specularConstant"],["specularexponent","specularExponent"],["spreadmethod","spreadMethod"],["startoffset","startOffset"],["stddeviation","stdDeviation"],["stitchtiles","stitchTiles"],["surfacescale","surfaceScale"],["systemlanguage","systemLanguage"],["tablevalues","tableValues"],["targetx","targetX"],["targety","targetY"],["textlength","textLength"],["viewbox","viewBox"],["viewtarget","viewTarget"],["xchannelselector","xChannelSelector"],["ychannelselector","yChannelSelector"],["zoomandpan","zoomAndPan"]])},{}],5:[function(e,t,n){var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n";case s.Comment:return function(e){return"\x3c!--"+e.data+"--\x3e"}(e);case s.CDATA:return function(e){return""}(e);default:return s.isTag(e)?function(e,t){var n;"foreign"===t.xmlMode&&(e.name=null!==(n=u.elementNames.get(e.name))&&void 0!==n?n:e.name,e.parent&&h.has(e.parent.name)&&(t=r(r({},t),{xmlMode:!1}))),!t.xmlMode&&m.has(e.name)&&(t=r(r({},t),{xmlMode:"foreign"}));var o="<"+e.name,i=function(e,t){if(e)return Object.keys(e).map((function(n){var r,o,i=null!==(r=e[n])&&void 0!==r?r:"";return"foreign"===t.xmlMode&&(n=null!==(o=u.attributeNames.get(n))&&void 0!==o?o:n),t.emptyAttrs||t.xmlMode||""!==i?n+'="'+(t.decodeEntities?l.encodeXML(i):i.replace(/"/g,"""))+'"':n})).join(" ")}(e.attribs,t);return i&&(o+=" "+i),0===e.children.length&&(t.xmlMode?!1!==t.selfClosingTags:t.selfClosingTags&&f.has(e.name))?(t.xmlMode||(o+=" "),o+="/>"):(o+=">",e.children.length>0&&(o+=d(e.children,t)),!t.xmlMode&&f.has(e.name)||(o+="")),o}(e,t):function(e,t){var n=e.data||"";return!t.decodeEntities||e.parent&&c.has(e.parent.name)||(n=l.encodeXML(n)),n}(e,t)}}n.default=d;var h=new Set(["mi","mo","mn","ms","mtext","annotation-xml","foreignObject","desc","title"]),m=new Set(["svg","math"])},{"./foreignNames":4,domelementtype:6,entities:20}],6:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.Doctype=n.CDATA=n.Tag=n.Style=n.Script=n.Comment=n.Directive=n.Text=n.isTag=void 0,n.isTag=function(e){return"tag"===e.type||"script"===e.type||"style"===e.type},n.Text="text",n.Directive="directive",n.Comment="comment",n.Script="script",n.Style="style",n.Tag="tag",n.CDATA="cdata",n.Doctype="doctype"},{}],7:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});var r=e("./node");n.Node=r.Node,n.Element=r.Element,n.DataNode=r.DataNode,n.NodeWithChildren=r.NodeWithChildren;var o=/\s+/g,i={normalizeWhitespace:!1,withStartIndices:!1,withEndIndices:!1},a=function(){function e(e,t,n){this.dom=[],this._done=!1,this._tagStack=[],this._lastNode=null,this._parser=null,"function"==typeof t&&(n=t,t=i),"object"===u(e)&&(t=e,e=void 0),this._callback=e||null,this._options=t||i,this._elementCB=n||null}return e.prototype.onparserinit=function(e){this._parser=e},e.prototype.onreset=function(){this.dom=[],this._done=!1,this._tagStack=[],this._lastNode=null,this._parser=this._parser||null},e.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this.handleCallback(null))},e.prototype.onerror=function(e){this.handleCallback(e)},e.prototype.onclosetag=function(){this._lastNode=null;var e=this._tagStack.pop();e&&this._parser&&(this._options.withEndIndices&&(e.endIndex=this._parser.endIndex),this._elementCB&&this._elementCB(e))},e.prototype.onopentag=function(e,t){var n=new r.Element(e,t);this.addNode(n),this._tagStack.push(n)},e.prototype.ontext=function(e){var t=this._options.normalizeWhitespace,n=this._lastNode;if(n&&"text"===n.type)t?n.data=(n.data+e).replace(o," "):n.data+=e;else{t&&(e=e.replace(o," "));var i=new r.DataNode("text",e);this.addNode(i),this._lastNode=i}},e.prototype.oncomment=function(e){if(this._lastNode&&"comment"===this._lastNode.type)this._lastNode.data+=e;else{var t=new r.DataNode("comment",e);this.addNode(t),this._lastNode=t}},e.prototype.oncommentend=function(){this._lastNode=null},e.prototype.oncdatastart=function(){var e=new r.DataNode("text",""),t=new r.NodeWithChildren("cdata",[e]);this.addNode(t),e.parent=t,this._lastNode=e},e.prototype.oncdataend=function(){this._lastNode=null},e.prototype.onprocessinginstruction=function(e,t){var n=new r.ProcessingInstruction(e,t);this.addNode(n)},e.prototype.handleCallback=function(e){if("function"==typeof this._callback)this._callback(e,this.dom);else if(e)throw e},e.prototype.addNode=function(e){var t=this._tagStack[this._tagStack.length-1],n=t?t.children:this.dom,r=n[n.length-1];this._parser&&(this._options.withStartIndices&&(e.startIndex=this._parser.startIndex),this._options.withEndIndices&&(e.endIndex=this._parser.endIndex)),n.push(e),r&&(e.prev=r,r.next=e),t&&(e.parent=t),this._lastNode=null},e.prototype.addDataNode=function(e){this.addNode(e),this._lastNode=e},e}();n.DomHandler=a,n.default=a},{"./node":8}],8:[function(e,t,n){var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)});Object.defineProperty(n,"__esModule",{value:!0});var i=new Map([["tag",1],["script",1],["style",1],["directive",1],["text",3],["cdata",4],["comment",8]]),a=function(){function e(e){this.type=e,this.parent=null,this.prev=null,this.next=null,this.startIndex=null,this.endIndex=null}return Object.defineProperty(e.prototype,"nodeType",{get:function(){return i.get(this.type)||1},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"parentNode",{get:function(){return this.parent||null},set:function(e){this.parent=e},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"previousSibling",{get:function(){return this.prev||null},set:function(e){this.prev=e},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"nextSibling",{get:function(){return this.next||null},set:function(e){this.next=e},enumerable:!0,configurable:!0}),e}();n.Node=a;var s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.data=n,r}return o(t,e),Object.defineProperty(t.prototype,"nodeValue",{get:function(){return this.data},set:function(e){this.data=e},enumerable:!0,configurable:!0}),t}(a);n.DataNode=s;var l=function(e){function t(t,n){var r=e.call(this,"directive",n)||this;return r.name=t,r}return o(t,e),t}(s);n.ProcessingInstruction=l;var u=function(e){function t(t,n){var r=e.call(this,t)||this;return r.children=n,r}return o(t,e),Object.defineProperty(t.prototype,"firstChild",{get:function(){return this.children[0]||null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"lastChild",{get:function(){return this.children[this.children.length-1]||null},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"childNodes",{get:function(){return this.children},set:function(e){this.children=e},enumerable:!0,configurable:!0}),t}(a);n.NodeWithChildren=u;var c=function(e){function t(t,n){var r=e.call(this,"script"===t?"script":"style"===t?"style":"tag",[])||this;return r.name=t,r.attribs=n,r.attribs=n,r}return o(t,e),Object.defineProperty(t.prototype,"tagName",{get:function(){return this.name},set:function(e){this.name=e},enumerable:!0,configurable:!0}),t}(u);n.Element=c},{}],9:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.uniqueSort=n.compareDocumentPosition=n.removeSubsets=void 0;var r=e("./tagtypes");function o(e,t){var n=[],o=[];if(e===t)return 0;for(var i=r.hasChildren(e)?e:e.parent;i;)n.unshift(i),i=i.parent;for(i=r.hasChildren(t)?t:t.parent;i;)o.unshift(i),i=i.parent;for(var a=Math.min(n.length,o.length),s=0;su.indexOf(f)?l===t?20:4:l===e?10:2}n.removeSubsets=function(e){for(var t=e.length;--t>=0;){var n=e[t];if(t>0&&e.lastIndexOf(n,t-1)>=0)e.splice(t,1);else for(var r=n.parent;r;r=r.parent)if(e.includes(r)){e.splice(t,1);break}}return e},n.compareDocumentPosition=o,n.uniqueSort=function(e){return(e=e.filter((function(e,t,n){return!n.includes(e,t+1)}))).sort((function(e,t){var n=o(e,t);return 2&n?-1:4&n?1:0})),e}},{"./tagtypes":15}],10:[function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(n,"__esModule",{value:!0}),o(e("./stringify"),n),o(e("./traversal"),n),o(e("./manipulation"),n),o(e("./querying"),n),o(e("./legacy"),n),o(e("./helpers"),n),o(e("./tagtypes"),n)},{"./helpers":9,"./legacy":11,"./manipulation":12,"./querying":13,"./stringify":14,"./tagtypes":15,"./traversal":16}],11:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.getElementsByTagType=n.getElementsByTagName=n.getElementById=n.getElements=n.testElement=void 0;var r=e("./querying"),o=e("./tagtypes");function i(e){return"text"===e.type}var a={tag_name:function(e){return"function"==typeof e?function(t){return o.isTag(t)&&e(t.name)}:"*"===e?o.isTag:function(t){return o.isTag(t)&&t.name===e}},tag_type:function(e){return"function"==typeof e?function(t){return e(t.type)}:function(t){return t.type===e}},tag_contains:function(e){return"function"==typeof e?function(t){return i(t)&&e(t.data)}:function(t){return i(t)&&t.data===e}}};function s(e,t){return"function"==typeof t?function(n){return o.isTag(n)&&t(n.attribs[e])}:function(n){return o.isTag(n)&&n.attribs[e]===t}}function l(e,t){return function(n){return e(n)||t(n)}}function u(e){var t=Object.keys(e).map((function(t){var n=e[t];return t in a?a[t](n):s(t,n)}));return 0===t.length?null:t.reduce(l)}n.testElement=function(e,t){var n=u(e);return!n||n(t)},n.getElements=function(e,t,n,o){void 0===o&&(o=1/0);var i=u(e);return i?r.filter(i,t,n,o):[]},n.getElementById=function(e,t,n){return void 0===n&&(n=!0),Array.isArray(t)||(t=[t]),r.findOne(s("id",e),t,n)},n.getElementsByTagName=function(e,t,n,o){return void 0===o&&(o=1/0),r.filter(a.tag_name(e),t,n,o)},n.getElementsByTagType=function(e,t,n,o){return void 0===n&&(n=!0),void 0===o&&(o=1/0),r.filter(a.tag_type(e),t,n,o)}},{"./querying":13,"./tagtypes":15}],12:[function(e,t,n){function r(e){if(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e.parent){var t=e.parent.children;t.splice(t.lastIndexOf(e),1)}}Object.defineProperty(n,"__esModule",{value:!0}),n.prepend=n.append=n.appendChild=n.replaceElement=n.removeElement=void 0,n.removeElement=r,n.replaceElement=function(e,t){var n=t.prev=e.prev;n&&(n.next=t);var r=t.next=e.next;r&&(r.prev=t);var o=t.parent=e.parent;if(o){var i=o.children;i[i.lastIndexOf(e)]=t}},n.appendChild=function(e,t){if(r(t),t.parent=e,1!==e.children.push(t)){var n=e.children[e.children.length-2];n.next=t,t.prev=n,t.next=null}},n.append=function(e,t){r(t);var n=e.parent,o=e.next;if(t.next=o,t.prev=e,e.next=t,t.parent=n,o){if(o.prev=t,n){var i=n.children;i.splice(i.lastIndexOf(o),0,t)}}else n&&n.children.push(t)},n.prepend=function(e,t){var n=e.parent;if(n){var r=n.children;r.splice(r.lastIndexOf(e),0,t)}e.prev&&(e.prev.next=t),t.parent=n,t.prev=e.prev,t.next=e,e.prev=t}},{}],13:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.findAll=n.existsOne=n.findOne=n.findOneChild=n.find=n.filter=void 0;var r=e("./tagtypes");function o(e,t,n,i){for(var a=[],s=0,l=t;s0){var c=o(e,u.children,n,i);if(a.push.apply(a,c),(i-=c.length)<=0)break}}return a}n.filter=function(e,t,n,r){return void 0===n&&(n=!0),void 0===r&&(r=1/0),Array.isArray(t)||(t=[t]),o(e,t,n,r)},n.find=o,n.findOneChild=function(e,t){return t.find(e)},n.findOne=function e(t,n,o){void 0===o&&(o=!0);for(var i=null,a=0;a0&&(i=e(t,s.children)))}return i},n.existsOne=function e(t,n){return n.some((function(n){return r.isTag(n)&&(t(n)||n.children.length>0&&e(t,n.children))}))},n.findAll=function(e,t){for(var n,o,i=[],a=t.filter(r.isTag);o=a.shift();){var s=null===(n=o.children)||void 0===n?void 0:n.filter(r.isTag);s&&s.length>0&&a.unshift.apply(a,s),e(o)&&i.push(o)}return i}},{"./tagtypes":15}],14:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.getText=n.getInnerHTML=n.getOuterHTML=void 0;var o=e("./tagtypes"),i=r(e("dom-serializer"));function a(e,t){return i.default(e,t)}n.getOuterHTML=a,n.getInnerHTML=function(e,t){return o.hasChildren(e)?e.children.map((function(e){return a(e,t)})).join(""):""},n.getText=function e(t){return Array.isArray(t)?t.map(e).join(""):o.isTag(t)?"br"===t.name?"\n":e(t.children):o.isCDATA(t)?e(t.children):o.isText(t)?t.data:""}},{"./tagtypes":15,"dom-serializer":5}],15:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.hasChildren=n.isComment=n.isText=n.isCDATA=n.isTag=void 0;var r=e("domelementtype");n.isTag=function(e){return r.isTag(e)},n.isCDATA=function(e){return"cdata"===e.type},n.isText=function(e){return"text"===e.type},n.isComment=function(e){return"comment"===e.type},n.hasChildren=function(e){return Object.prototype.hasOwnProperty.call(e,"children")}},{domelementtype:6}],16:[function(e,t,n){function r(e){return e.children||null}function o(e){return e.parent||null}Object.defineProperty(n,"__esModule",{value:!0}),n.nextElementSibling=n.getName=n.hasAttrib=n.getAttributeValue=n.getSiblings=n.getParent=n.getChildren=void 0,n.getChildren=r,n.getParent=o,n.getSiblings=function(e){var t=o(e);return t?r(t):[e]},n.getAttributeValue=function(e,t){var n;return null===(n=e.attribs)||void 0===n?void 0:n[t]},n.hasAttrib=function(e,t){return!!e.attribs&&Object.prototype.hasOwnProperty.call(e.attribs,t)&&null!=e.attribs[t]},n.getName=function(e){return e.name},n.nextElementSibling=function(e){for(var t=e.next;null!==t&&"tag"!==t.type;)t=t.next;return t}},{}],17:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.decodeHTML=n.decodeHTMLStrict=n.decodeXML=void 0;var o=r(e("./maps/entities.json")),i=r(e("./maps/legacy.json")),a=r(e("./maps/xml.json")),s=r(e("./decode_codepoint"));function l(e){var t=Object.keys(e).join("|"),n=c(e),r=new RegExp("&(?:"+(t+="|#[xX][\\da-fA-F]+|#\\d+")+");","g");return function(e){return String(e).replace(r,n)}}n.decodeXML=l(a.default),n.decodeHTMLStrict=l(o.default);var u=function(e,t){return e=55296&&e<=57343||e>1114111)return"๏ฟฝ";e in o.default&&(e=o.default[e]);var t="";return e>65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|1023&e),t+=String.fromCharCode(e)}},{"./maps/decode.json":21}],19:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.escape=n.encodeHTML=n.encodeXML=void 0;var o=l(r(e("./maps/xml.json")).default),i=u(o);n.encodeXML=d(o,i);var a=l(r(e("./maps/entities.json")).default),s=u(a);function l(e){return Object.keys(e).sort().reduce((function(t,n){return t[e[n]]="&"+n+";",t}),{})}function u(e){for(var t=[],n=[],r=0,o=Object.keys(e);r",GT:">",Gt:"โ‰ซ",gtdot:"โ‹—",gtlPar:"โฆ•",gtquest:"โฉผ",gtrapprox:"โช†",gtrarr:"โฅธ",gtrdot:"โ‹—",gtreqless:"โ‹›",gtreqqless:"โชŒ",gtrless:"โ‰ท",gtrsim:"โ‰ณ",gvertneqq:"โ‰ฉ๏ธ€",gvnE:"โ‰ฉ๏ธ€",Hacek:"ห‡",hairsp:"โ€Š",half:"ยฝ",hamilt:"โ„‹",HARDcy:"ะช",hardcy:"ัŠ",harrcir:"โฅˆ",harr:"โ†”",hArr:"โ‡”",harrw:"โ†ญ",Hat:"^",hbar:"โ„",Hcirc:"ฤค",hcirc:"ฤฅ",hearts:"โ™ฅ",heartsuit:"โ™ฅ",hellip:"โ€ฆ",hercon:"โŠน",hfr:"๐”ฅ",Hfr:"โ„Œ",HilbertSpace:"โ„‹",hksearow:"โคฅ",hkswarow:"โคฆ",hoarr:"โ‡ฟ",homtht:"โˆป",hookleftarrow:"โ†ฉ",hookrightarrow:"โ†ช",hopf:"๐•™",Hopf:"โ„",horbar:"โ€•",HorizontalLine:"โ”€",hscr:"๐’ฝ",Hscr:"โ„‹",hslash:"โ„",Hstrok:"ฤฆ",hstrok:"ฤง",HumpDownHump:"โ‰Ž",HumpEqual:"โ‰",hybull:"โƒ",hyphen:"โ€",Iacute:"ร",iacute:"รญ",ic:"โฃ",Icirc:"รŽ",icirc:"รฎ",Icy:"ะ˜",icy:"ะธ",Idot:"ฤฐ",IEcy:"ะ•",iecy:"ะต",iexcl:"ยก",iff:"โ‡”",ifr:"๐”ฆ",Ifr:"โ„‘",Igrave:"รŒ",igrave:"รฌ",ii:"โ…ˆ",iiiint:"โจŒ",iiint:"โˆญ",iinfin:"โงœ",iiota:"โ„ฉ",IJlig:"ฤฒ",ijlig:"ฤณ",Imacr:"ฤช",imacr:"ฤซ",image:"โ„‘",ImaginaryI:"โ…ˆ",imagline:"โ„",imagpart:"โ„‘",imath:"ฤฑ",Im:"โ„‘",imof:"โŠท",imped:"ฦต",Implies:"โ‡’",incare:"โ„…",in:"โˆˆ",infin:"โˆž",infintie:"โง",inodot:"ฤฑ",intcal:"โŠบ",int:"โˆซ",Int:"โˆฌ",integers:"โ„ค",Integral:"โˆซ",intercal:"โŠบ",Intersection:"โ‹‚",intlarhk:"โจ—",intprod:"โจผ",InvisibleComma:"โฃ",InvisibleTimes:"โข",IOcy:"ะ",iocy:"ั‘",Iogon:"ฤฎ",iogon:"ฤฏ",Iopf:"๐•€",iopf:"๐•š",Iota:"ฮ™",iota:"ฮน",iprod:"โจผ",iquest:"ยฟ",iscr:"๐’พ",Iscr:"โ„",isin:"โˆˆ",isindot:"โ‹ต",isinE:"โ‹น",isins:"โ‹ด",isinsv:"โ‹ณ",isinv:"โˆˆ",it:"โข",Itilde:"ฤจ",itilde:"ฤฉ",Iukcy:"ะ†",iukcy:"ั–",Iuml:"ร",iuml:"รฏ",Jcirc:"ฤด",jcirc:"ฤต",Jcy:"ะ™",jcy:"ะน",Jfr:"๐”",jfr:"๐”ง",jmath:"ศท",Jopf:"๐•",jopf:"๐•›",Jscr:"๐’ฅ",jscr:"๐’ฟ",Jsercy:"ะˆ",jsercy:"ั˜",Jukcy:"ะ„",jukcy:"ั”",Kappa:"ฮš",kappa:"ฮบ",kappav:"ฯฐ",Kcedil:"ฤถ",kcedil:"ฤท",Kcy:"ะš",kcy:"ะบ",Kfr:"๐”Ž",kfr:"๐”จ",kgreen:"ฤธ",KHcy:"ะฅ",khcy:"ั…",KJcy:"ะŒ",kjcy:"ัœ",Kopf:"๐•‚",kopf:"๐•œ",Kscr:"๐’ฆ",kscr:"๐“€",lAarr:"โ‡š",Lacute:"ฤน",lacute:"ฤบ",laemptyv:"โฆด",lagran:"โ„’",Lambda:"ฮ›",lambda:"ฮป",lang:"โŸจ",Lang:"โŸช",langd:"โฆ‘",langle:"โŸจ",lap:"โช…",Laplacetrf:"โ„’",laquo:"ยซ",larrb:"โ‡ค",larrbfs:"โคŸ",larr:"โ†",Larr:"โ†ž",lArr:"โ‡",larrfs:"โค",larrhk:"โ†ฉ",larrlp:"โ†ซ",larrpl:"โคน",larrsim:"โฅณ",larrtl:"โ†ข",latail:"โค™",lAtail:"โค›",lat:"โชซ",late:"โชญ",lates:"โชญ๏ธ€",lbarr:"โคŒ",lBarr:"โคŽ",lbbrk:"โฒ",lbrace:"{",lbrack:"[",lbrke:"โฆ‹",lbrksld:"โฆ",lbrkslu:"โฆ",Lcaron:"ฤฝ",lcaron:"ฤพ",Lcedil:"ฤป",lcedil:"ฤผ",lceil:"โŒˆ",lcub:"{",Lcy:"ะ›",lcy:"ะป",ldca:"โคถ",ldquo:"โ€œ",ldquor:"โ€ž",ldrdhar:"โฅง",ldrushar:"โฅ‹",ldsh:"โ†ฒ",le:"โ‰ค",lE:"โ‰ฆ",LeftAngleBracket:"โŸจ",LeftArrowBar:"โ‡ค",leftarrow:"โ†",LeftArrow:"โ†",Leftarrow:"โ‡",LeftArrowRightArrow:"โ‡†",leftarrowtail:"โ†ข",LeftCeiling:"โŒˆ",LeftDoubleBracket:"โŸฆ",LeftDownTeeVector:"โฅก",LeftDownVectorBar:"โฅ™",LeftDownVector:"โ‡ƒ",LeftFloor:"โŒŠ",leftharpoondown:"โ†ฝ",leftharpoonup:"โ†ผ",leftleftarrows:"โ‡‡",leftrightarrow:"โ†”",LeftRightArrow:"โ†”",Leftrightarrow:"โ‡”",leftrightarrows:"โ‡†",leftrightharpoons:"โ‡‹",leftrightsquigarrow:"โ†ญ",LeftRightVector:"โฅŽ",LeftTeeArrow:"โ†ค",LeftTee:"โŠฃ",LeftTeeVector:"โฅš",leftthreetimes:"โ‹‹",LeftTriangleBar:"โง",LeftTriangle:"โŠฒ",LeftTriangleEqual:"โŠด",LeftUpDownVector:"โฅ‘",LeftUpTeeVector:"โฅ ",LeftUpVectorBar:"โฅ˜",LeftUpVector:"โ†ฟ",LeftVectorBar:"โฅ’",LeftVector:"โ†ผ",lEg:"โช‹",leg:"โ‹š",leq:"โ‰ค",leqq:"โ‰ฆ",leqslant:"โฉฝ",lescc:"โชจ",les:"โฉฝ",lesdot:"โฉฟ",lesdoto:"โช",lesdotor:"โชƒ",lesg:"โ‹š๏ธ€",lesges:"โช“",lessapprox:"โช…",lessdot:"โ‹–",lesseqgtr:"โ‹š",lesseqqgtr:"โช‹",LessEqualGreater:"โ‹š",LessFullEqual:"โ‰ฆ",LessGreater:"โ‰ถ",lessgtr:"โ‰ถ",LessLess:"โชก",lesssim:"โ‰ฒ",LessSlantEqual:"โฉฝ",LessTilde:"โ‰ฒ",lfisht:"โฅผ",lfloor:"โŒŠ",Lfr:"๐”",lfr:"๐”ฉ",lg:"โ‰ถ",lgE:"โช‘",lHar:"โฅข",lhard:"โ†ฝ",lharu:"โ†ผ",lharul:"โฅช",lhblk:"โ–„",LJcy:"ะ‰",ljcy:"ั™",llarr:"โ‡‡",ll:"โ‰ช",Ll:"โ‹˜",llcorner:"โŒž",Lleftarrow:"โ‡š",llhard:"โฅซ",lltri:"โ—บ",Lmidot:"ฤฟ",lmidot:"ล€",lmoustache:"โŽฐ",lmoust:"โŽฐ",lnap:"โช‰",lnapprox:"โช‰",lne:"โช‡",lnE:"โ‰จ",lneq:"โช‡",lneqq:"โ‰จ",lnsim:"โ‹ฆ",loang:"โŸฌ",loarr:"โ‡ฝ",lobrk:"โŸฆ",longleftarrow:"โŸต",LongLeftArrow:"โŸต",Longleftarrow:"โŸธ",longleftrightarrow:"โŸท",LongLeftRightArrow:"โŸท",Longleftrightarrow:"โŸบ",longmapsto:"โŸผ",longrightarrow:"โŸถ",LongRightArrow:"โŸถ",Longrightarrow:"โŸน",looparrowleft:"โ†ซ",looparrowright:"โ†ฌ",lopar:"โฆ…",Lopf:"๐•ƒ",lopf:"๐•",loplus:"โจญ",lotimes:"โจด",lowast:"โˆ—",lowbar:"_",LowerLeftArrow:"โ†™",LowerRightArrow:"โ†˜",loz:"โ—Š",lozenge:"โ—Š",lozf:"โงซ",lpar:"(",lparlt:"โฆ“",lrarr:"โ‡†",lrcorner:"โŒŸ",lrhar:"โ‡‹",lrhard:"โฅญ",lrm:"โ€Ž",lrtri:"โŠฟ",lsaquo:"โ€น",lscr:"๐“",Lscr:"โ„’",lsh:"โ†ฐ",Lsh:"โ†ฐ",lsim:"โ‰ฒ",lsime:"โช",lsimg:"โช",lsqb:"[",lsquo:"โ€˜",lsquor:"โ€š",Lstrok:"ล",lstrok:"ล‚",ltcc:"โชฆ",ltcir:"โฉน",lt:"<",LT:"<",Lt:"โ‰ช",ltdot:"โ‹–",lthree:"โ‹‹",ltimes:"โ‹‰",ltlarr:"โฅถ",ltquest:"โฉป",ltri:"โ—ƒ",ltrie:"โŠด",ltrif:"โ—‚",ltrPar:"โฆ–",lurdshar:"โฅŠ",luruhar:"โฅฆ",lvertneqq:"โ‰จ๏ธ€",lvnE:"โ‰จ๏ธ€",macr:"ยฏ",male:"โ™‚",malt:"โœ ",maltese:"โœ ",Map:"โค…",map:"โ†ฆ",mapsto:"โ†ฆ",mapstodown:"โ†ง",mapstoleft:"โ†ค",mapstoup:"โ†ฅ",marker:"โ–ฎ",mcomma:"โจฉ",Mcy:"ะœ",mcy:"ะผ",mdash:"โ€”",mDDot:"โˆบ",measuredangle:"โˆก",MediumSpace:"โŸ",Mellintrf:"โ„ณ",Mfr:"๐”",mfr:"๐”ช",mho:"โ„ง",micro:"ยต",midast:"*",midcir:"โซฐ",mid:"โˆฃ",middot:"ยท",minusb:"โŠŸ",minus:"โˆ’",minusd:"โˆธ",minusdu:"โจช",MinusPlus:"โˆ“",mlcp:"โซ›",mldr:"โ€ฆ",mnplus:"โˆ“",models:"โŠง",Mopf:"๐•„",mopf:"๐•ž",mp:"โˆ“",mscr:"๐“‚",Mscr:"โ„ณ",mstpos:"โˆพ",Mu:"ฮœ",mu:"ฮผ",multimap:"โŠธ",mumap:"โŠธ",nabla:"โˆ‡",Nacute:"ลƒ",nacute:"ล„",nang:"โˆ โƒ’",nap:"โ‰‰",napE:"โฉฐฬธ",napid:"โ‰‹ฬธ",napos:"ล‰",napprox:"โ‰‰",natural:"โ™ฎ",naturals:"โ„•",natur:"โ™ฎ",nbsp:"ย ",nbump:"โ‰Žฬธ",nbumpe:"โ‰ฬธ",ncap:"โฉƒ",Ncaron:"ล‡",ncaron:"ลˆ",Ncedil:"ล…",ncedil:"ล†",ncong:"โ‰‡",ncongdot:"โฉญฬธ",ncup:"โฉ‚",Ncy:"ะ",ncy:"ะฝ",ndash:"โ€“",nearhk:"โคค",nearr:"โ†—",neArr:"โ‡—",nearrow:"โ†—",ne:"โ‰ ",nedot:"โ‰ฬธ",NegativeMediumSpace:"โ€‹",NegativeThickSpace:"โ€‹",NegativeThinSpace:"โ€‹",NegativeVeryThinSpace:"โ€‹",nequiv:"โ‰ข",nesear:"โคจ",nesim:"โ‰‚ฬธ",NestedGreaterGreater:"โ‰ซ",NestedLessLess:"โ‰ช",NewLine:"\n",nexist:"โˆ„",nexists:"โˆ„",Nfr:"๐”‘",nfr:"๐”ซ",ngE:"โ‰งฬธ",nge:"โ‰ฑ",ngeq:"โ‰ฑ",ngeqq:"โ‰งฬธ",ngeqslant:"โฉพฬธ",nges:"โฉพฬธ",nGg:"โ‹™ฬธ",ngsim:"โ‰ต",nGt:"โ‰ซโƒ’",ngt:"โ‰ฏ",ngtr:"โ‰ฏ",nGtv:"โ‰ซฬธ",nharr:"โ†ฎ",nhArr:"โ‡Ž",nhpar:"โซฒ",ni:"โˆ‹",nis:"โ‹ผ",nisd:"โ‹บ",niv:"โˆ‹",NJcy:"ะŠ",njcy:"ัš",nlarr:"โ†š",nlArr:"โ‡",nldr:"โ€ฅ",nlE:"โ‰ฆฬธ",nle:"โ‰ฐ",nleftarrow:"โ†š",nLeftarrow:"โ‡",nleftrightarrow:"โ†ฎ",nLeftrightarrow:"โ‡Ž",nleq:"โ‰ฐ",nleqq:"โ‰ฆฬธ",nleqslant:"โฉฝฬธ",nles:"โฉฝฬธ",nless:"โ‰ฎ",nLl:"โ‹˜ฬธ",nlsim:"โ‰ด",nLt:"โ‰ชโƒ’",nlt:"โ‰ฎ",nltri:"โ‹ช",nltrie:"โ‹ฌ",nLtv:"โ‰ชฬธ",nmid:"โˆค",NoBreak:"โ ",NonBreakingSpace:"ย ",nopf:"๐•Ÿ",Nopf:"โ„•",Not:"โซฌ",not:"ยฌ",NotCongruent:"โ‰ข",NotCupCap:"โ‰ญ",NotDoubleVerticalBar:"โˆฆ",NotElement:"โˆ‰",NotEqual:"โ‰ ",NotEqualTilde:"โ‰‚ฬธ",NotExists:"โˆ„",NotGreater:"โ‰ฏ",NotGreaterEqual:"โ‰ฑ",NotGreaterFullEqual:"โ‰งฬธ",NotGreaterGreater:"โ‰ซฬธ",NotGreaterLess:"โ‰น",NotGreaterSlantEqual:"โฉพฬธ",NotGreaterTilde:"โ‰ต",NotHumpDownHump:"โ‰Žฬธ",NotHumpEqual:"โ‰ฬธ",notin:"โˆ‰",notindot:"โ‹ตฬธ",notinE:"โ‹นฬธ",notinva:"โˆ‰",notinvb:"โ‹ท",notinvc:"โ‹ถ",NotLeftTriangleBar:"โงฬธ",NotLeftTriangle:"โ‹ช",NotLeftTriangleEqual:"โ‹ฌ",NotLess:"โ‰ฎ",NotLessEqual:"โ‰ฐ",NotLessGreater:"โ‰ธ",NotLessLess:"โ‰ชฬธ",NotLessSlantEqual:"โฉฝฬธ",NotLessTilde:"โ‰ด",NotNestedGreaterGreater:"โชขฬธ",NotNestedLessLess:"โชกฬธ",notni:"โˆŒ",notniva:"โˆŒ",notnivb:"โ‹พ",notnivc:"โ‹ฝ",NotPrecedes:"โŠ€",NotPrecedesEqual:"โชฏฬธ",NotPrecedesSlantEqual:"โ‹ ",NotReverseElement:"โˆŒ",NotRightTriangleBar:"โงฬธ",NotRightTriangle:"โ‹ซ",NotRightTriangleEqual:"โ‹ญ",NotSquareSubset:"โŠฬธ",NotSquareSubsetEqual:"โ‹ข",NotSquareSuperset:"โŠฬธ",NotSquareSupersetEqual:"โ‹ฃ",NotSubset:"โŠ‚โƒ’",NotSubsetEqual:"โŠˆ",NotSucceeds:"โŠ",NotSucceedsEqual:"โชฐฬธ",NotSucceedsSlantEqual:"โ‹ก",NotSucceedsTilde:"โ‰ฟฬธ",NotSuperset:"โŠƒโƒ’",NotSupersetEqual:"โŠ‰",NotTilde:"โ‰",NotTildeEqual:"โ‰„",NotTildeFullEqual:"โ‰‡",NotTildeTilde:"โ‰‰",NotVerticalBar:"โˆค",nparallel:"โˆฆ",npar:"โˆฆ",nparsl:"โซฝโƒฅ",npart:"โˆ‚ฬธ",npolint:"โจ”",npr:"โŠ€",nprcue:"โ‹ ",nprec:"โŠ€",npreceq:"โชฏฬธ",npre:"โชฏฬธ",nrarrc:"โคณฬธ",nrarr:"โ†›",nrArr:"โ‡",nrarrw:"โ†ฬธ",nrightarrow:"โ†›",nRightarrow:"โ‡",nrtri:"โ‹ซ",nrtrie:"โ‹ญ",nsc:"โŠ",nsccue:"โ‹ก",nsce:"โชฐฬธ",Nscr:"๐’ฉ",nscr:"๐“ƒ",nshortmid:"โˆค",nshortparallel:"โˆฆ",nsim:"โ‰",nsime:"โ‰„",nsimeq:"โ‰„",nsmid:"โˆค",nspar:"โˆฆ",nsqsube:"โ‹ข",nsqsupe:"โ‹ฃ",nsub:"โŠ„",nsubE:"โซ…ฬธ",nsube:"โŠˆ",nsubset:"โŠ‚โƒ’",nsubseteq:"โŠˆ",nsubseteqq:"โซ…ฬธ",nsucc:"โŠ",nsucceq:"โชฐฬธ",nsup:"โŠ…",nsupE:"โซ†ฬธ",nsupe:"โŠ‰",nsupset:"โŠƒโƒ’",nsupseteq:"โŠ‰",nsupseteqq:"โซ†ฬธ",ntgl:"โ‰น",Ntilde:"ร‘",ntilde:"รฑ",ntlg:"โ‰ธ",ntriangleleft:"โ‹ช",ntrianglelefteq:"โ‹ฌ",ntriangleright:"โ‹ซ",ntrianglerighteq:"โ‹ญ",Nu:"ฮ",nu:"ฮฝ",num:"#",numero:"โ„–",numsp:"โ€‡",nvap:"โ‰โƒ’",nvdash:"โŠฌ",nvDash:"โŠญ",nVdash:"โŠฎ",nVDash:"โŠฏ",nvge:"โ‰ฅโƒ’",nvgt:">โƒ’",nvHarr:"โค„",nvinfin:"โงž",nvlArr:"โค‚",nvle:"โ‰คโƒ’",nvlt:"<โƒ’",nvltrie:"โŠดโƒ’",nvrArr:"โคƒ",nvrtrie:"โŠตโƒ’",nvsim:"โˆผโƒ’",nwarhk:"โคฃ",nwarr:"โ†–",nwArr:"โ‡–",nwarrow:"โ†–",nwnear:"โคง",Oacute:"ร“",oacute:"รณ",oast:"โŠ›",Ocirc:"ร”",ocirc:"รด",ocir:"โŠš",Ocy:"ะž",ocy:"ะพ",odash:"โŠ",Odblac:"ล",odblac:"ล‘",odiv:"โจธ",odot:"โŠ™",odsold:"โฆผ",OElig:"ล’",oelig:"ล“",ofcir:"โฆฟ",Ofr:"๐”’",ofr:"๐”ฌ",ogon:"ห›",Ograve:"ร’",ograve:"รฒ",ogt:"โง",ohbar:"โฆต",ohm:"ฮฉ",oint:"โˆฎ",olarr:"โ†บ",olcir:"โฆพ",olcross:"โฆป",oline:"โ€พ",olt:"โง€",Omacr:"ลŒ",omacr:"ล",Omega:"ฮฉ",omega:"ฯ‰",Omicron:"ฮŸ",omicron:"ฮฟ",omid:"โฆถ",ominus:"โŠ–",Oopf:"๐•†",oopf:"๐• ",opar:"โฆท",OpenCurlyDoubleQuote:"โ€œ",OpenCurlyQuote:"โ€˜",operp:"โฆน",oplus:"โŠ•",orarr:"โ†ป",Or:"โฉ”",or:"โˆจ",ord:"โฉ",order:"โ„ด",orderof:"โ„ด",ordf:"ยช",ordm:"ยบ",origof:"โŠถ",oror:"โฉ–",orslope:"โฉ—",orv:"โฉ›",oS:"โ“ˆ",Oscr:"๐’ช",oscr:"โ„ด",Oslash:"ร˜",oslash:"รธ",osol:"โŠ˜",Otilde:"ร•",otilde:"รต",otimesas:"โจถ",Otimes:"โจท",otimes:"โŠ—",Ouml:"ร–",ouml:"รถ",ovbar:"โŒฝ",OverBar:"โ€พ",OverBrace:"โž",OverBracket:"โŽด",OverParenthesis:"โœ",para:"ยถ",parallel:"โˆฅ",par:"โˆฅ",parsim:"โซณ",parsl:"โซฝ",part:"โˆ‚",PartialD:"โˆ‚",Pcy:"ะŸ",pcy:"ะฟ",percnt:"%",period:".",permil:"โ€ฐ",perp:"โŠฅ",pertenk:"โ€ฑ",Pfr:"๐”“",pfr:"๐”ญ",Phi:"ฮฆ",phi:"ฯ†",phiv:"ฯ•",phmmat:"โ„ณ",phone:"โ˜Ž",Pi:"ฮ ",pi:"ฯ€",pitchfork:"โ‹”",piv:"ฯ–",planck:"โ„",planckh:"โ„Ž",plankv:"โ„",plusacir:"โจฃ",plusb:"โŠž",pluscir:"โจข",plus:"+",plusdo:"โˆ”",plusdu:"โจฅ",pluse:"โฉฒ",PlusMinus:"ยฑ",plusmn:"ยฑ",plussim:"โจฆ",plustwo:"โจง",pm:"ยฑ",Poincareplane:"โ„Œ",pointint:"โจ•",popf:"๐•ก",Popf:"โ„™",pound:"ยฃ",prap:"โชท",Pr:"โชป",pr:"โ‰บ",prcue:"โ‰ผ",precapprox:"โชท",prec:"โ‰บ",preccurlyeq:"โ‰ผ",Precedes:"โ‰บ",PrecedesEqual:"โชฏ",PrecedesSlantEqual:"โ‰ผ",PrecedesTilde:"โ‰พ",preceq:"โชฏ",precnapprox:"โชน",precneqq:"โชต",precnsim:"โ‹จ",pre:"โชฏ",prE:"โชณ",precsim:"โ‰พ",prime:"โ€ฒ",Prime:"โ€ณ",primes:"โ„™",prnap:"โชน",prnE:"โชต",prnsim:"โ‹จ",prod:"โˆ",Product:"โˆ",profalar:"โŒฎ",profline:"โŒ’",profsurf:"โŒ“",prop:"โˆ",Proportional:"โˆ",Proportion:"โˆท",propto:"โˆ",prsim:"โ‰พ",prurel:"โŠฐ",Pscr:"๐’ซ",pscr:"๐“…",Psi:"ฮจ",psi:"ฯˆ",puncsp:"โ€ˆ",Qfr:"๐””",qfr:"๐”ฎ",qint:"โจŒ",qopf:"๐•ข",Qopf:"โ„š",qprime:"โ—",Qscr:"๐’ฌ",qscr:"๐“†",quaternions:"โ„",quatint:"โจ–",quest:"?",questeq:"โ‰Ÿ",quot:'"',QUOT:'"',rAarr:"โ‡›",race:"โˆฝฬฑ",Racute:"ล”",racute:"ล•",radic:"โˆš",raemptyv:"โฆณ",rang:"โŸฉ",Rang:"โŸซ",rangd:"โฆ’",range:"โฆฅ",rangle:"โŸฉ",raquo:"ยป",rarrap:"โฅต",rarrb:"โ‡ฅ",rarrbfs:"โค ",rarrc:"โคณ",rarr:"โ†’",Rarr:"โ† ",rArr:"โ‡’",rarrfs:"โคž",rarrhk:"โ†ช",rarrlp:"โ†ฌ",rarrpl:"โฅ…",rarrsim:"โฅด",Rarrtl:"โค–",rarrtl:"โ†ฃ",rarrw:"โ†",ratail:"โคš",rAtail:"โคœ",ratio:"โˆถ",rationals:"โ„š",rbarr:"โค",rBarr:"โค",RBarr:"โค",rbbrk:"โณ",rbrace:"}",rbrack:"]",rbrke:"โฆŒ",rbrksld:"โฆŽ",rbrkslu:"โฆ",Rcaron:"ล˜",rcaron:"ล™",Rcedil:"ล–",rcedil:"ล—",rceil:"โŒ‰",rcub:"}",Rcy:"ะ ",rcy:"ั€",rdca:"โคท",rdldhar:"โฅฉ",rdquo:"โ€",rdquor:"โ€",rdsh:"โ†ณ",real:"โ„œ",realine:"โ„›",realpart:"โ„œ",reals:"โ„",Re:"โ„œ",rect:"โ–ญ",reg:"ยฎ",REG:"ยฎ",ReverseElement:"โˆ‹",ReverseEquilibrium:"โ‡‹",ReverseUpEquilibrium:"โฅฏ",rfisht:"โฅฝ",rfloor:"โŒ‹",rfr:"๐”ฏ",Rfr:"โ„œ",rHar:"โฅค",rhard:"โ‡",rharu:"โ‡€",rharul:"โฅฌ",Rho:"ฮก",rho:"ฯ",rhov:"ฯฑ",RightAngleBracket:"โŸฉ",RightArrowBar:"โ‡ฅ",rightarrow:"โ†’",RightArrow:"โ†’",Rightarrow:"โ‡’",RightArrowLeftArrow:"โ‡„",rightarrowtail:"โ†ฃ",RightCeiling:"โŒ‰",RightDoubleBracket:"โŸง",RightDownTeeVector:"โฅ",RightDownVectorBar:"โฅ•",RightDownVector:"โ‡‚",RightFloor:"โŒ‹",rightharpoondown:"โ‡",rightharpoonup:"โ‡€",rightleftarrows:"โ‡„",rightleftharpoons:"โ‡Œ",rightrightarrows:"โ‡‰",rightsquigarrow:"โ†",RightTeeArrow:"โ†ฆ",RightTee:"โŠข",RightTeeVector:"โฅ›",rightthreetimes:"โ‹Œ",RightTriangleBar:"โง",RightTriangle:"โŠณ",RightTriangleEqual:"โŠต",RightUpDownVector:"โฅ",RightUpTeeVector:"โฅœ",RightUpVectorBar:"โฅ”",RightUpVector:"โ†พ",RightVectorBar:"โฅ“",RightVector:"โ‡€",ring:"หš",risingdotseq:"โ‰“",rlarr:"โ‡„",rlhar:"โ‡Œ",rlm:"โ€",rmoustache:"โŽฑ",rmoust:"โŽฑ",rnmid:"โซฎ",roang:"โŸญ",roarr:"โ‡พ",robrk:"โŸง",ropar:"โฆ†",ropf:"๐•ฃ",Ropf:"โ„",roplus:"โจฎ",rotimes:"โจต",RoundImplies:"โฅฐ",rpar:")",rpargt:"โฆ”",rppolint:"โจ’",rrarr:"โ‡‰",Rrightarrow:"โ‡›",rsaquo:"โ€บ",rscr:"๐“‡",Rscr:"โ„›",rsh:"โ†ฑ",Rsh:"โ†ฑ",rsqb:"]",rsquo:"โ€™",rsquor:"โ€™",rthree:"โ‹Œ",rtimes:"โ‹Š",rtri:"โ–น",rtrie:"โŠต",rtrif:"โ–ธ",rtriltri:"โงŽ",RuleDelayed:"โงด",ruluhar:"โฅจ",rx:"โ„ž",Sacute:"ลš",sacute:"ล›",sbquo:"โ€š",scap:"โชธ",Scaron:"ล ",scaron:"ลก",Sc:"โชผ",sc:"โ‰ป",sccue:"โ‰ฝ",sce:"โชฐ",scE:"โชด",Scedil:"ลž",scedil:"ลŸ",Scirc:"ลœ",scirc:"ล",scnap:"โชบ",scnE:"โชถ",scnsim:"โ‹ฉ",scpolint:"โจ“",scsim:"โ‰ฟ",Scy:"ะก",scy:"ั",sdotb:"โŠก",sdot:"โ‹…",sdote:"โฉฆ",searhk:"โคฅ",searr:"โ†˜",seArr:"โ‡˜",searrow:"โ†˜",sect:"ยง",semi:";",seswar:"โคฉ",setminus:"โˆ–",setmn:"โˆ–",sext:"โœถ",Sfr:"๐”–",sfr:"๐”ฐ",sfrown:"โŒข",sharp:"โ™ฏ",SHCHcy:"ะฉ",shchcy:"ั‰",SHcy:"ะจ",shcy:"ัˆ",ShortDownArrow:"โ†“",ShortLeftArrow:"โ†",shortmid:"โˆฃ",shortparallel:"โˆฅ",ShortRightArrow:"โ†’",ShortUpArrow:"โ†‘",shy:"ยญ",Sigma:"ฮฃ",sigma:"ฯƒ",sigmaf:"ฯ‚",sigmav:"ฯ‚",sim:"โˆผ",simdot:"โฉช",sime:"โ‰ƒ",simeq:"โ‰ƒ",simg:"โชž",simgE:"โช ",siml:"โช",simlE:"โชŸ",simne:"โ‰†",simplus:"โจค",simrarr:"โฅฒ",slarr:"โ†",SmallCircle:"โˆ˜",smallsetminus:"โˆ–",smashp:"โจณ",smeparsl:"โงค",smid:"โˆฃ",smile:"โŒฃ",smt:"โชช",smte:"โชฌ",smtes:"โชฌ๏ธ€",SOFTcy:"ะฌ",softcy:"ัŒ",solbar:"โŒฟ",solb:"โง„",sol:"/",Sopf:"๐•Š",sopf:"๐•ค",spades:"โ™ ",spadesuit:"โ™ ",spar:"โˆฅ",sqcap:"โŠ“",sqcaps:"โŠ“๏ธ€",sqcup:"โŠ”",sqcups:"โŠ”๏ธ€",Sqrt:"โˆš",sqsub:"โŠ",sqsube:"โŠ‘",sqsubset:"โŠ",sqsubseteq:"โŠ‘",sqsup:"โŠ",sqsupe:"โŠ’",sqsupset:"โŠ",sqsupseteq:"โŠ’",square:"โ–ก",Square:"โ–ก",SquareIntersection:"โŠ“",SquareSubset:"โŠ",SquareSubsetEqual:"โŠ‘",SquareSuperset:"โŠ",SquareSupersetEqual:"โŠ’",SquareUnion:"โŠ”",squarf:"โ–ช",squ:"โ–ก",squf:"โ–ช",srarr:"โ†’",Sscr:"๐’ฎ",sscr:"๐“ˆ",ssetmn:"โˆ–",ssmile:"โŒฃ",sstarf:"โ‹†",Star:"โ‹†",star:"โ˜†",starf:"โ˜…",straightepsilon:"ฯต",straightphi:"ฯ•",strns:"ยฏ",sub:"โŠ‚",Sub:"โ‹",subdot:"โชฝ",subE:"โซ…",sube:"โŠ†",subedot:"โซƒ",submult:"โซ",subnE:"โซ‹",subne:"โŠŠ",subplus:"โชฟ",subrarr:"โฅน",subset:"โŠ‚",Subset:"โ‹",subseteq:"โŠ†",subseteqq:"โซ…",SubsetEqual:"โŠ†",subsetneq:"โŠŠ",subsetneqq:"โซ‹",subsim:"โซ‡",subsub:"โซ•",subsup:"โซ“",succapprox:"โชธ",succ:"โ‰ป",succcurlyeq:"โ‰ฝ",Succeeds:"โ‰ป",SucceedsEqual:"โชฐ",SucceedsSlantEqual:"โ‰ฝ",SucceedsTilde:"โ‰ฟ",succeq:"โชฐ",succnapprox:"โชบ",succneqq:"โชถ",succnsim:"โ‹ฉ",succsim:"โ‰ฟ",SuchThat:"โˆ‹",sum:"โˆ‘",Sum:"โˆ‘",sung:"โ™ช",sup1:"ยน",sup2:"ยฒ",sup3:"ยณ",sup:"โŠƒ",Sup:"โ‹‘",supdot:"โชพ",supdsub:"โซ˜",supE:"โซ†",supe:"โŠ‡",supedot:"โซ„",Superset:"โŠƒ",SupersetEqual:"โŠ‡",suphsol:"โŸ‰",suphsub:"โซ—",suplarr:"โฅป",supmult:"โซ‚",supnE:"โซŒ",supne:"โŠ‹",supplus:"โซ€",supset:"โŠƒ",Supset:"โ‹‘",supseteq:"โŠ‡",supseteqq:"โซ†",supsetneq:"โŠ‹",supsetneqq:"โซŒ",supsim:"โซˆ",supsub:"โซ”",supsup:"โซ–",swarhk:"โคฆ",swarr:"โ†™",swArr:"โ‡™",swarrow:"โ†™",swnwar:"โคช",szlig:"รŸ",Tab:"\t",target:"โŒ–",Tau:"ฮค",tau:"ฯ„",tbrk:"โŽด",Tcaron:"ลค",tcaron:"ลฅ",Tcedil:"ลข",tcedil:"ลฃ",Tcy:"ะข",tcy:"ั‚",tdot:"โƒ›",telrec:"โŒ•",Tfr:"๐”—",tfr:"๐”ฑ",there4:"โˆด",therefore:"โˆด",Therefore:"โˆด",Theta:"ฮ˜",theta:"ฮธ",thetasym:"ฯ‘",thetav:"ฯ‘",thickapprox:"โ‰ˆ",thicksim:"โˆผ",ThickSpace:"โŸโ€Š",ThinSpace:"โ€‰",thinsp:"โ€‰",thkap:"โ‰ˆ",thksim:"โˆผ",THORN:"รž",thorn:"รพ",tilde:"หœ",Tilde:"โˆผ",TildeEqual:"โ‰ƒ",TildeFullEqual:"โ‰…",TildeTilde:"โ‰ˆ",timesbar:"โจฑ",timesb:"โŠ ",times:"ร—",timesd:"โจฐ",tint:"โˆญ",toea:"โคจ",topbot:"โŒถ",topcir:"โซฑ",top:"โŠค",Topf:"๐•‹",topf:"๐•ฅ",topfork:"โซš",tosa:"โคฉ",tprime:"โ€ด",trade:"โ„ข",TRADE:"โ„ข",triangle:"โ–ต",triangledown:"โ–ฟ",triangleleft:"โ—ƒ",trianglelefteq:"โŠด",triangleq:"โ‰œ",triangleright:"โ–น",trianglerighteq:"โŠต",tridot:"โ—ฌ",trie:"โ‰œ",triminus:"โจบ",TripleDot:"โƒ›",triplus:"โจน",trisb:"โง",tritime:"โจป",trpezium:"โข",Tscr:"๐’ฏ",tscr:"๐“‰",TScy:"ะฆ",tscy:"ั†",TSHcy:"ะ‹",tshcy:"ั›",Tstrok:"ลฆ",tstrok:"ลง",twixt:"โ‰ฌ",twoheadleftarrow:"โ†ž",twoheadrightarrow:"โ† ",Uacute:"รš",uacute:"รบ",uarr:"โ†‘",Uarr:"โ†Ÿ",uArr:"โ‡‘",Uarrocir:"โฅ‰",Ubrcy:"ะŽ",ubrcy:"ัž",Ubreve:"ลฌ",ubreve:"ลญ",Ucirc:"ร›",ucirc:"รป",Ucy:"ะฃ",ucy:"ัƒ",udarr:"โ‡…",Udblac:"ลฐ",udblac:"ลฑ",udhar:"โฅฎ",ufisht:"โฅพ",Ufr:"๐”˜",ufr:"๐”ฒ",Ugrave:"ร™",ugrave:"รน",uHar:"โฅฃ",uharl:"โ†ฟ",uharr:"โ†พ",uhblk:"โ–€",ulcorn:"โŒœ",ulcorner:"โŒœ",ulcrop:"โŒ",ultri:"โ—ธ",Umacr:"ลช",umacr:"ลซ",uml:"ยจ",UnderBar:"_",UnderBrace:"โŸ",UnderBracket:"โŽต",UnderParenthesis:"โ",Union:"โ‹ƒ",UnionPlus:"โŠŽ",Uogon:"ลฒ",uogon:"ลณ",Uopf:"๐•Œ",uopf:"๐•ฆ",UpArrowBar:"โค’",uparrow:"โ†‘",UpArrow:"โ†‘",Uparrow:"โ‡‘",UpArrowDownArrow:"โ‡…",updownarrow:"โ†•",UpDownArrow:"โ†•",Updownarrow:"โ‡•",UpEquilibrium:"โฅฎ",upharpoonleft:"โ†ฟ",upharpoonright:"โ†พ",uplus:"โŠŽ",UpperLeftArrow:"โ†–",UpperRightArrow:"โ†—",upsi:"ฯ…",Upsi:"ฯ’",upsih:"ฯ’",Upsilon:"ฮฅ",upsilon:"ฯ…",UpTeeArrow:"โ†ฅ",UpTee:"โŠฅ",upuparrows:"โ‡ˆ",urcorn:"โŒ",urcorner:"โŒ",urcrop:"โŒŽ",Uring:"ลฎ",uring:"ลฏ",urtri:"โ—น",Uscr:"๐’ฐ",uscr:"๐“Š",utdot:"โ‹ฐ",Utilde:"ลจ",utilde:"ลฉ",utri:"โ–ต",utrif:"โ–ด",uuarr:"โ‡ˆ",Uuml:"รœ",uuml:"รผ",uwangle:"โฆง",vangrt:"โฆœ",varepsilon:"ฯต",varkappa:"ฯฐ",varnothing:"โˆ…",varphi:"ฯ•",varpi:"ฯ–",varpropto:"โˆ",varr:"โ†•",vArr:"โ‡•",varrho:"ฯฑ",varsigma:"ฯ‚",varsubsetneq:"โŠŠ๏ธ€",varsubsetneqq:"โซ‹๏ธ€",varsupsetneq:"โŠ‹๏ธ€",varsupsetneqq:"โซŒ๏ธ€",vartheta:"ฯ‘",vartriangleleft:"โŠฒ",vartriangleright:"โŠณ",vBar:"โซจ",Vbar:"โซซ",vBarv:"โซฉ",Vcy:"ะ’",vcy:"ะฒ",vdash:"โŠข",vDash:"โŠจ",Vdash:"โŠฉ",VDash:"โŠซ",Vdashl:"โซฆ",veebar:"โŠป",vee:"โˆจ",Vee:"โ‹",veeeq:"โ‰š",vellip:"โ‹ฎ",verbar:"|",Verbar:"โ€–",vert:"|",Vert:"โ€–",VerticalBar:"โˆฃ",VerticalLine:"|",VerticalSeparator:"โ˜",VerticalTilde:"โ‰€",VeryThinSpace:"โ€Š",Vfr:"๐”™",vfr:"๐”ณ",vltri:"โŠฒ",vnsub:"โŠ‚โƒ’",vnsup:"โŠƒโƒ’",Vopf:"๐•",vopf:"๐•ง",vprop:"โˆ",vrtri:"โŠณ",Vscr:"๐’ฑ",vscr:"๐“‹",vsubnE:"โซ‹๏ธ€",vsubne:"โŠŠ๏ธ€",vsupnE:"โซŒ๏ธ€",vsupne:"โŠ‹๏ธ€",Vvdash:"โŠช",vzigzag:"โฆš",Wcirc:"ลด",wcirc:"ลต",wedbar:"โฉŸ",wedge:"โˆง",Wedge:"โ‹€",wedgeq:"โ‰™",weierp:"โ„˜",Wfr:"๐”š",wfr:"๐”ด",Wopf:"๐•Ž",wopf:"๐•จ",wp:"โ„˜",wr:"โ‰€",wreath:"โ‰€",Wscr:"๐’ฒ",wscr:"๐“Œ",xcap:"โ‹‚",xcirc:"โ—ฏ",xcup:"โ‹ƒ",xdtri:"โ–ฝ",Xfr:"๐”›",xfr:"๐”ต",xharr:"โŸท",xhArr:"โŸบ",Xi:"ฮž",xi:"ฮพ",xlarr:"โŸต",xlArr:"โŸธ",xmap:"โŸผ",xnis:"โ‹ป",xodot:"โจ€",Xopf:"๐•",xopf:"๐•ฉ",xoplus:"โจ",xotime:"โจ‚",xrarr:"โŸถ",xrArr:"โŸน",Xscr:"๐’ณ",xscr:"๐“",xsqcup:"โจ†",xuplus:"โจ„",xutri:"โ–ณ",xvee:"โ‹",xwedge:"โ‹€",Yacute:"ร",yacute:"รฝ",YAcy:"ะฏ",yacy:"ั",Ycirc:"ลถ",ycirc:"ลท",Ycy:"ะซ",ycy:"ั‹",yen:"ยฅ",Yfr:"๐”œ",yfr:"๐”ถ",YIcy:"ะ‡",yicy:"ั—",Yopf:"๐•",yopf:"๐•ช",Yscr:"๐’ด",yscr:"๐“Ž",YUcy:"ะฎ",yucy:"ัŽ",yuml:"รฟ",Yuml:"ลธ",Zacute:"ลน",zacute:"ลบ",Zcaron:"ลฝ",zcaron:"ลพ",Zcy:"ะ—",zcy:"ะท",Zdot:"ลป",zdot:"ลผ",zeetrf:"โ„จ",ZeroWidthSpace:"โ€‹",Zeta:"ฮ–",zeta:"ฮถ",zfr:"๐”ท",Zfr:"โ„จ",ZHcy:"ะ–",zhcy:"ะถ",zigrarr:"โ‡",zopf:"๐•ซ",Zopf:"โ„ค",Zscr:"๐’ต",zscr:"๐“",zwj:"โ€",zwnj:"โ€Œ"}},{}],23:[function(e,t,n){t.exports={Aacute:"ร",aacute:"รก",Acirc:"ร‚",acirc:"รข",acute:"ยด",AElig:"ร†",aelig:"รฆ",Agrave:"ร€",agrave:"ร ",amp:"&",AMP:"&",Aring:"ร…",aring:"รฅ",Atilde:"รƒ",atilde:"รฃ",Auml:"ร„",auml:"รค",brvbar:"ยฆ",Ccedil:"ร‡",ccedil:"รง",cedil:"ยธ",cent:"ยข",copy:"ยฉ",COPY:"ยฉ",curren:"ยค",deg:"ยฐ",divide:"รท",Eacute:"ร‰",eacute:"รฉ",Ecirc:"รŠ",ecirc:"รช",Egrave:"รˆ",egrave:"รจ",ETH:"ร",eth:"รฐ",Euml:"ร‹",euml:"รซ",frac12:"ยฝ",frac14:"ยผ",frac34:"ยพ",gt:">",GT:">",Iacute:"ร",iacute:"รญ",Icirc:"รŽ",icirc:"รฎ",iexcl:"ยก",Igrave:"รŒ",igrave:"รฌ",iquest:"ยฟ",Iuml:"ร",iuml:"รฏ",laquo:"ยซ",lt:"<",LT:"<",macr:"ยฏ",micro:"ยต",middot:"ยท",nbsp:"ย ",not:"ยฌ",Ntilde:"ร‘",ntilde:"รฑ",Oacute:"ร“",oacute:"รณ",Ocirc:"ร”",ocirc:"รด",Ograve:"ร’",ograve:"รฒ",ordf:"ยช",ordm:"ยบ",Oslash:"ร˜",oslash:"รธ",Otilde:"ร•",otilde:"รต",Ouml:"ร–",ouml:"รถ",para:"ยถ",plusmn:"ยฑ",pound:"ยฃ",quot:'"',QUOT:'"',raquo:"ยป",reg:"ยฎ",REG:"ยฎ",sect:"ยง",shy:"ยญ",sup1:"ยน",sup2:"ยฒ",sup3:"ยณ",szlig:"รŸ",THORN:"รž",thorn:"รพ",times:"ร—",Uacute:"รš",uacute:"รบ",Ucirc:"ร›",ucirc:"รป",Ugrave:"ร™",ugrave:"รน",uml:"ยจ",Uuml:"รœ",uuml:"รผ",Yacute:"ร",yacute:"รฝ",yen:"ยฅ",yuml:"รฟ"}},{}],24:[function(e,t,n){t.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],25:[function(e,t,n){var r=Object.create||function(e){var t=function(){};return t.prototype=e,new t},o=Object.keys||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return n},i=Function.prototype.bind||function(e){var t=this;return function(){return t.apply(e,arguments)}};function a(){this._events&&Object.prototype.hasOwnProperty.call(this,"_events")||(this._events=r(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0}t.exports=a,a.EventEmitter=a,a.prototype._events=void 0,a.prototype._maxListeners=void 0;var s,l=10;try{var c={};Object.defineProperty&&Object.defineProperty(c,"x",{value:0}),s=0===c.x}catch(e){s=!1}function f(e){return void 0===e._maxListeners?a.defaultMaxListeners:e._maxListeners}function d(e,t,n){if(t)e.call(n);else for(var r=e.length,o=x(e,r),i=0;i0&&s.length>i){s.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+s.length+' "'+String(t)+'" listeners added. Use emitter.setMaxListeners() to increase limit.');l.name="MaxListenersExceededWarning",l.emitter=e,l.type=t,l.count=s.length,"object"===("undefined"==typeof console?"undefined":u(console))&&console.warn&&console.warn("%s: %s",l.name,l.message)}}else s=a[t]=n,++e._eventsCount;return e}function b(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var e=new Array(arguments.length),t=0;t1&&(t=arguments[1]),t instanceof Error)throw t;var l=new Error('Unhandled "error" event. ('+t+")");throw l.context=t,l}if(!(n=a[e]))return!1;var u="function"==typeof n;switch(r=arguments.length){case 1:d(n,u,this);break;case 2:p(n,u,this,arguments[1]);break;case 3:h(n,u,this,arguments[1],arguments[2]);break;case 4:m(n,u,this,arguments[1],arguments[2],arguments[3]);break;default:for(o=new Array(r-1),i=1;i=0;a--)if(n[a]===t||n[a].listener===t){s=n[a].listener,i=a;break}if(i<0)return this;0===i?n.shift():function(e,t){for(var n=t,r=n+1,o=e.length;r=0;i--)this.removeListener(e,t[i]);return this},a.prototype.listeners=function(e){return _(this,e,!0)},a.prototype.rawListeners=function(e){return _(this,e,!1)},a.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):w.call(e,t)},a.prototype.listenerCount=w,a.prototype.eventNames=function(){return this._eventsCount>0?Reflect.ownKeys(this._events):[]}},{}],26:[function(e,t,n){var r,o=this&&this.__extends||(r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0});var a=function(e){function t(t){void 0===t&&(t={});var n=e.call(this,(function(e){for(var t,r=[],o=1;o0;this._cbs.onclosetag(this._stack[--e]));this._cbs.onend&&this._cbs.onend()},t.prototype.reset=function(){this._cbs.onreset&&this._cbs.onreset(),this._tokenizer.reset(),this._tagname="",this._attribname="",this._attribs=null,this._stack=[],this._cbs.onparserinit&&this._cbs.onparserinit(this)},t.prototype.parseComplete=function(e){this.reset(),this.end(e)},t.prototype.write=function(e){this._tokenizer.write(e)},t.prototype.end=function(e){this._tokenizer.end(e)},t.prototype.pause=function(){this._tokenizer.pause()},t.prototype.resume=function(){this._tokenizer.resume()},t}(s.EventEmitter);n.Parser=m},{"./Tokenizer":30,events:25}],30:[function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0});var o=r(e("entities/lib/decode_codepoint")),i=r(e("entities/lib/maps/entities.json")),a=r(e("entities/lib/maps/legacy.json")),s=r(e("entities/lib/maps/xml.json"));function l(e){return" "===e||"\n"===e||"\t"===e||"\f"===e||"\r"===e}function u(e,t,n){var r=e.toLowerCase();return e===r?function(e,o){o===r?e._state=t:(e._state=n,e._index--)}:function(o,i){i===r||i===e?o._state=t:(o._state=n,o._index--)}}function c(e,t){var n=e.toLowerCase();return function(r,o){o===n||o===e?r._state=t:(r._state=3,r._index--)}}var f=u("C",23,16),d=u("D",24,16),p=u("A",25,16),h=u("T",26,16),m=u("A",27,16),g=c("R",34),v=c("I",35),b=c("P",36),y=c("T",37),_=u("R",39,1),w=u("I",40,1),x=u("P",41,1),O=u("T",42,1),k=c("Y",44),S=c("L",45),j=c("E",46),E=u("Y",48,1),C=u("L",49,1),N=u("E",50,1),A=u("#",52,53),q=u("X",55,54),T=function(){function e(e,t){this._state=1,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=1,this._special=1,this._running=!0,this._ended=!1,this._cbs=t,this._xmlMode=!(!e||!e.xmlMode),this._decodeEntities=!(!e||!e.decodeEntities)}return e.prototype.reset=function(){this._state=1,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=1,this._special=1,this._running=!0,this._ended=!1},e.prototype._stateText=function(e){"<"===e?(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._state=2,this._sectionStart=this._index):this._decodeEntities&&1===this._special&&"&"===e&&(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._baseState=1,this._state=51,this._sectionStart=this._index)},e.prototype._stateBeforeTagName=function(e){"/"===e?this._state=5:"<"===e?(this._cbs.ontext(this._getSection()),this._sectionStart=this._index):">"===e||1!==this._special||l(e)?this._state=1:"!"===e?(this._state=15,this._sectionStart=this._index+1):"?"===e?(this._state=17,this._sectionStart=this._index+1):(this._state=this._xmlMode||"s"!==e&&"S"!==e?3:31,this._sectionStart=this._index)},e.prototype._stateInTagName=function(e){("/"===e||">"===e||l(e))&&(this._emitToken("onopentagname"),this._state=8,this._index--)},e.prototype._stateBeforeClosingTagName=function(e){l(e)||(">"===e?this._state=1:1!==this._special?"s"===e||"S"===e?this._state=32:(this._state=1,this._index--):(this._state=6,this._sectionStart=this._index))},e.prototype._stateInClosingTagName=function(e){(">"===e||l(e))&&(this._emitToken("onclosetag"),this._state=7,this._index--)},e.prototype._stateAfterClosingTagName=function(e){">"===e&&(this._state=1,this._sectionStart=this._index+1)},e.prototype._stateBeforeAttributeName=function(e){">"===e?(this._cbs.onopentagend(),this._state=1,this._sectionStart=this._index+1):"/"===e?this._state=4:l(e)||(this._state=9,this._sectionStart=this._index)},e.prototype._stateInSelfClosingTag=function(e){">"===e?(this._cbs.onselfclosingtag(),this._state=1,this._sectionStart=this._index+1):l(e)||(this._state=8,this._index--)},e.prototype._stateInAttributeName=function(e){("="===e||"/"===e||">"===e||l(e))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=10,this._index--)},e.prototype._stateAfterAttributeName=function(e){"="===e?this._state=11:"/"===e||">"===e?(this._cbs.onattribend(),this._state=8,this._index--):l(e)||(this._cbs.onattribend(),this._state=9,this._sectionStart=this._index)},e.prototype._stateBeforeAttributeValue=function(e){'"'===e?(this._state=12,this._sectionStart=this._index+1):"'"===e?(this._state=13,this._sectionStart=this._index+1):l(e)||(this._state=14,this._sectionStart=this._index,this._index--)},e.prototype._stateInAttributeValueDoubleQuotes=function(e){'"'===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=8):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=51,this._sectionStart=this._index)},e.prototype._stateInAttributeValueSingleQuotes=function(e){"'"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=8):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=51,this._sectionStart=this._index)},e.prototype._stateInAttributeValueNoQuotes=function(e){l(e)||">"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=8,this._index--):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=51,this._sectionStart=this._index)},e.prototype._stateBeforeDeclaration=function(e){this._state="["===e?22:"-"===e?18:16},e.prototype._stateInDeclaration=function(e){">"===e&&(this._cbs.ondeclaration(this._getSection()),this._state=1,this._sectionStart=this._index+1)},e.prototype._stateInProcessingInstruction=function(e){">"===e&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=1,this._sectionStart=this._index+1)},e.prototype._stateBeforeComment=function(e){"-"===e?(this._state=19,this._sectionStart=this._index+1):this._state=16},e.prototype._stateInComment=function(e){"-"===e&&(this._state=20)},e.prototype._stateAfterComment1=function(e){this._state="-"===e?21:19},e.prototype._stateAfterComment2=function(e){">"===e?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=1,this._sectionStart=this._index+1):"-"!==e&&(this._state=19)},e.prototype._stateBeforeCdata6=function(e){"["===e?(this._state=28,this._sectionStart=this._index+1):(this._state=16,this._index--)},e.prototype._stateInCdata=function(e){"]"===e&&(this._state=29)},e.prototype._stateAfterCdata1=function(e){this._state="]"===e?30:28},e.prototype._stateAfterCdata2=function(e){">"===e?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=1,this._sectionStart=this._index+1):"]"!==e&&(this._state=28)},e.prototype._stateBeforeSpecial=function(e){"c"===e||"C"===e?this._state=33:"t"===e||"T"===e?this._state=43:(this._state=3,this._index--)},e.prototype._stateBeforeSpecialEnd=function(e){2!==this._special||"c"!==e&&"C"!==e?3!==this._special||"t"!==e&&"T"!==e?this._state=1:this._state=47:this._state=38},e.prototype._stateBeforeScript5=function(e){("/"===e||">"===e||l(e))&&(this._special=2),this._state=3,this._index--},e.prototype._stateAfterScript5=function(e){">"===e||l(e)?(this._special=1,this._state=6,this._sectionStart=this._index-6,this._index--):this._state=1},e.prototype._stateBeforeStyle4=function(e){("/"===e||">"===e||l(e))&&(this._special=3),this._state=3,this._index--},e.prototype._stateAfterStyle4=function(e){">"===e||l(e)?(this._special=1,this._state=6,this._sectionStart=this._index-5,this._index--):this._state=1},e.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+16&&(t=6);t>=2;){var n=this._buffer.substr(e,t);if(Object.prototype.hasOwnProperty.call(a.default,n))return this._emitPartial(a.default[n]),void(this._sectionStart+=t+1);t--}},e.prototype._stateInNamedEntity=function(e){";"===e?(this._parseNamedEntityStrict(),this._sectionStart+1"z")&&(e<"A"||e>"Z")&&(e<"0"||e>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(1!==this._baseState?"="!==e&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},e.prototype._decodeNumericEntity=function(e,t){var n=this._sectionStart+e;if(n!==this._index){var r=this._buffer.substring(n,this._index),i=parseInt(r,t);this._emitPartial(o.default(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},e.prototype._stateInNumericEntity=function(e){";"===e?(this._decodeNumericEntity(2,10),this._sectionStart++):(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},e.prototype._stateInHexEntity=function(e){";"===e?(this._decodeNumericEntity(3,16),this._sectionStart++):(e<"a"||e>"f")&&(e<"A"||e>"F")&&(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},e.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._bufferOffset+=this._index,this._index=0):this._running&&(1===this._state?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._bufferOffset+=this._index,this._index=0):this._sectionStart===this._index?(this._buffer="",this._bufferOffset+=this._index,this._index=0):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},e.prototype.write=function(e){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=e,this._parse()},e.prototype._parse=function(){for(;this._index>1,c=-7,f=n?o-1:0,d=n?-1:1,p=e[t+f];for(f+=d,i=p&(1<<-c)-1,p>>=-c,c+=s;c>0;i=256*i+e[t+f],f+=d,c-=8);for(a=i&(1<<-c)-1,i>>=-c,c+=r;c>0;a=256*a+e[t+f],f+=d,c-=8);if(0===i)i=1-u;else{if(i===l)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=u}return(p?-1:1)*a*Math.pow(2,i-r)},n.write=function(e,t,n,r,o,i){var a,s,l,u=8*i-o-1,c=(1<>1,d=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,h=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=c):(a=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-a))<1&&(a--,l*=2),(t+=a+f>=1?d/l:d*Math.pow(2,1-f))*l>=2&&(a++,l/=2),a+f>=c?(s=0,a=c):a+f>=1?(s=(t*l-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=h,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=h,a/=256,u-=8);e[n+p-h]|=128*m}},{}],33:[function(e,t,n){var r=e("./_getNative")(e("./_root"),"DataView");t.exports=r},{"./_getNative":93,"./_root":130}],34:[function(e,t,n){var r=e("./_hashClear"),o=e("./_hashDelete"),i=e("./_hashGet"),a=e("./_hashHas"),s=e("./_hashSet");function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t1?n[i-1]:void 0,s=i>2?n[2]:void 0;for(a=e.length>3&&"function"==typeof a?(i--,a):void 0,s&&o(n[0],n[1],s)&&(a=i<3?void 0:a,i=1),t=Object(t);++r-1&&e%1==0&&e-1}},{"./_assocIndexOf":52}],117:[function(e,t,n){var r=e("./_assocIndexOf");t.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},{"./_assocIndexOf":52}],118:[function(e,t,n){var r=e("./_Hash"),o=e("./_ListCache"),i=e("./_Map");t.exports=function(){this.size=0,this.__data__={hash:new r,map:new(i||o),string:new r}}},{"./_Hash":34,"./_ListCache":35,"./_Map":36}],119:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},{"./_getMapData":92}],120:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e){return r(this,e).get(e)}},{"./_getMapData":92}],121:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e){return r(this,e).has(e)}},{"./_getMapData":92}],122:[function(e,t,n){var r=e("./_getMapData");t.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},{"./_getMapData":92}],123:[function(e,t,n){var r=e("./_getNative")(Object,"create");t.exports=r},{"./_getNative":93}],124:[function(e,t,n){var r=e("./_overArg")(Object.keys,Object);t.exports=r},{"./_overArg":128}],125:[function(e,t,n){t.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},{}],126:[function(e,t,n){var r=e("./_freeGlobal"),o="object"==u(n)&&n&&!n.nodeType&&n,i=o&&"object"==u(t)&&t&&!t.nodeType&&t,a=i&&i.exports===o&&r.process,s=function(){try{var e=i&&i.require&&i.require("util").types;return e||a&&a.binding&&a.binding("util")}catch(e){}}();t.exports=s},{"./_freeGlobal":89}],127:[function(e,t,n){var r=Object.prototype.toString;t.exports=function(e){return r.call(e)}},{}],128:[function(e,t,n){t.exports=function(e,t){return function(n){return e(t(n))}}},{}],129:[function(e,t,n){var r=e("./_apply"),o=Math.max;t.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var i=arguments,a=-1,s=o(i.length-t,0),l=Array(s);++a0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}},{}],134:[function(e,t,n){var r=e("./_ListCache");t.exports=function(){this.__data__=new r,this.size=0}},{"./_ListCache":35}],135:[function(e,t,n){t.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},{}],136:[function(e,t,n){t.exports=function(e){return this.__data__.get(e)}},{}],137:[function(e,t,n){t.exports=function(e){return this.__data__.has(e)}},{}],138:[function(e,t,n){var r=e("./_ListCache"),o=e("./_Map"),i=e("./_MapCache");t.exports=function(e,t){var n=this.__data__;if(n instanceof r){var a=n.__data__;if(!o||a.length<199)return a.push([e,t]),this.size=++n.size,this;n=this.__data__=new i(a)}return n.set(e,t),this.size=n.size,this}},{"./_ListCache":35,"./_Map":36,"./_MapCache":37}],139:[function(e,t,n){var r=Function.prototype.toString;t.exports=function(e){if(null!=e){try{return r.call(e)}catch(e){}try{return e+""}catch(e){}}return""}},{}],140:[function(e,t,n){var r=e("./_baseClone");t.exports=function(e){return r(e,5)}},{"./_baseClone":56}],141:[function(e,t,n){t.exports=function(e){return function(){return e}}},{}],142:[function(e,t,n){t.exports=function(e,t){return e===t||e!=e&&t!=t}},{}],143:[function(e,t,n){var r=e("./toString"),o=/[\\^$.*+?()[\]{}|]/g,i=RegExp(o.source);t.exports=function(e){return(e=r(e))&&i.test(e)?e.replace(o,"\\$&"):e}},{"./toString":166}],144:[function(e,t,n){t.exports=function(e){return e}},{}],145:[function(e,t,n){var r=e("./_baseIsArguments"),o=e("./isObjectLike"),i=Object.prototype,a=i.hasOwnProperty,s=i.propertyIsEnumerable,l=r(function(){return arguments}())?r:function(e){return o(e)&&a.call(e,"callee")&&!s.call(e,"callee")};t.exports=l},{"./_baseIsArguments":61,"./isObjectLike":154}],146:[function(e,t,n){var r=Array.isArray;t.exports=r},{}],147:[function(e,t,n){var r=e("./isFunction"),o=e("./isLength");t.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},{"./isFunction":150,"./isLength":151}],148:[function(e,t,n){var r=e("./isArrayLike"),o=e("./isObjectLike");t.exports=function(e){return o(e)&&r(e)}},{"./isArrayLike":147,"./isObjectLike":154}],149:[function(e,t,n){var r=e("./_root"),o=e("./stubFalse"),i="object"==u(n)&&n&&!n.nodeType&&n,a=i&&"object"==u(t)&&t&&!t.nodeType&&t,s=a&&a.exports===i?r.Buffer:void 0,l=(s?s.isBuffer:void 0)||o;t.exports=l},{"./_root":130,"./stubFalse":164}],150:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./isObject");t.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},{"./_baseGetTag":60,"./isObject":153}],151:[function(e,t,n){t.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},{}],152:[function(e,t,n){var r=e("./_baseIsMap"),o=e("./_baseUnary"),i=e("./_nodeUtil"),a=i&&i.isMap,s=a?o(a):r;t.exports=s},{"./_baseIsMap":62,"./_baseUnary":74,"./_nodeUtil":126}],153:[function(e,t,n){t.exports=function(e){var t=u(e);return null!=e&&("object"==t||"function"==t)}},{}],154:[function(e,t,n){t.exports=function(e){return null!=e&&"object"==u(e)}},{}],155:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./_getPrototype"),i=e("./isObjectLike"),a=Function.prototype,s=Object.prototype,l=a.toString,u=s.hasOwnProperty,c=l.call(Object);t.exports=function(e){if(!i(e)||"[object Object]"!=r(e))return!1;var t=o(e);if(null===t)return!0;var n=u.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&l.call(n)==c}},{"./_baseGetTag":60,"./_getPrototype":94,"./isObjectLike":154}],156:[function(e,t,n){var r=e("./_baseIsSet"),o=e("./_baseUnary"),i=e("./_nodeUtil"),a=i&&i.isSet,s=a?o(a):r;t.exports=s},{"./_baseIsSet":64,"./_baseUnary":74,"./_nodeUtil":126}],157:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./isArray"),i=e("./isObjectLike");t.exports=function(e){return"string"==typeof e||!o(e)&&i(e)&&"[object String]"==r(e)}},{"./_baseGetTag":60,"./isArray":146,"./isObjectLike":154}],158:[function(e,t,n){var r=e("./_baseGetTag"),o=e("./isObjectLike");t.exports=function(e){return"symbol"==u(e)||o(e)&&"[object Symbol]"==r(e)}},{"./_baseGetTag":60,"./isObjectLike":154}],159:[function(e,t,n){var r=e("./_baseIsTypedArray"),o=e("./_baseUnary"),i=e("./_nodeUtil"),a=i&&i.isTypedArray,s=a?o(a):r;t.exports=s},{"./_baseIsTypedArray":65,"./_baseUnary":74,"./_nodeUtil":126}],160:[function(e,t,n){var r=e("./_arrayLikeKeys"),o=e("./_baseKeys"),i=e("./isArrayLike");t.exports=function(e){return i(e)?r(e):o(e)}},{"./_arrayLikeKeys":47,"./_baseKeys":66,"./isArrayLike":147}],161:[function(e,t,n){var r=e("./_arrayLikeKeys"),o=e("./_baseKeysIn"),i=e("./isArrayLike");t.exports=function(e){return i(e)?r(e,!0):o(e)}},{"./_arrayLikeKeys":47,"./_baseKeysIn":67,"./isArrayLike":147}],162:[function(e,t,n){var r=e("./_baseMerge"),o=e("./_createAssigner")((function(e,t,n,o){r(e,t,n,o)}));t.exports=o},{"./_baseMerge":68,"./_createAssigner":86}],163:[function(e,t,n){t.exports=function(){return[]}},{}],164:[function(e,t,n){t.exports=function(){return!1}},{}],165:[function(e,t,n){var r=e("./_copyObject"),o=e("./keysIn");t.exports=function(e){return r(e,o(e))}},{"./_copyObject":82,"./keysIn":161}],166:[function(e,t,n){var r=e("./_baseToString");t.exports=function(e){return null==e?"":r(e)}},{"./_baseToString":73}],167:[function(e,t,n){var r,o;r=this,o=function(){return function(e){function t(e){return" "===e||"\t"===e||"\n"===e||"\f"===e||"\r"===e}function n(t){var n,r=t.exec(e.substring(m));if(r)return n=r[0],m+=n.length,n}for(var r,o,i,a,s,l=e.length,u=/^[ \t\n\r\u000c]+/,c=/^[, \t\n\r\u000c]+/,f=/^[^ \t\n\r\u000c]+/,d=/[,]+$/,p=/^\d+$/,h=/^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/,m=0,g=[];;){if(n(c),m>=l)return g;r=n(f),o=[],","===r.slice(-1)?(r=r.replace(d,""),b()):v()}function v(){for(n(u),i="",a="in descriptor";;){if(s=e.charAt(m),"in descriptor"===a)if(t(s))i&&(o.push(i),i="",a="after descriptor");else{if(","===s)return m+=1,i&&o.push(i),void b();if("("===s)i+=s,a="in parens";else{if(""===s)return i&&o.push(i),void b();i+=s}}else if("in parens"===a)if(")"===s)i+=s,a="in descriptor";else{if(""===s)return o.push(i),void b();i+=s}else if("after descriptor"===a)if(t(s));else{if(""===s)return void b();a="in descriptor",m-=1}m+=1}}function b(){var t,n,i,a,s,l,u,c,f,d=!1,m={};for(a=0;a=0;r--){var o=e[r];"."===o?e.splice(r,1):".."===o?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r=-1&&!o;i--){var a=i>=0?arguments[i]:e.cwd();if("string"!=typeof a)throw new TypeError("Arguments to path.resolve must be strings");a&&(n=a+"/"+n,o="/"===a.charAt(0))}return(o?"/":"")+(n=t(r(n.split("/"),(function(e){return!!e})),!o).join("/"))||"."},n.normalize=function(e){var i=n.isAbsolute(e),a="/"===o(e,-1);return(e=t(r(e.split("/"),(function(e){return!!e})),!i).join("/"))||i||(e="."),e&&a&&(e+="/"),(i?"/":"")+e},n.isAbsolute=function(e){return"/"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,(function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e})).join("/"))},n.relative=function(e,t){function r(e){for(var t=0;t=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var o=r(e.split("/")),i=r(t.split("/")),a=Math.min(o.length,i.length),s=a,l=0;l=1;--i)if(47===(t=e.charCodeAt(i))){if(!o){r=i;break}}else o=!1;return-1===r?n?"/":".":n&&1===r?"/":e.slice(0,r)},n.basename=function(e,t){var n=function(e){"string"!=typeof e&&(e+="");var t,n=0,r=-1,o=!0;for(t=e.length-1;t>=0;--t)if(47===e.charCodeAt(t)){if(!o){n=t+1;break}}else-1===r&&(o=!1,r=t+1);return-1===r?"":e.slice(n,r)}(e);return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},n.extname=function(e){"string"!=typeof e&&(e+="");for(var t=-1,n=0,r=-1,o=!0,i=0,a=e.length-1;a>=0;--a){var s=e.charCodeAt(a);if(47!==s)-1===r&&(o=!1,r=a+1),46===s?-1===t?t=a:1!==i&&(i=1):-1!==t&&(i=-1);else if(!o){n=a+1;break}}return-1===t||-1===r||0===i||1===i&&t===r-1&&t===n+1?"":e.slice(t,r)};var o="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,e("_process"))},{_process:193}],169:[function(e,t,n){var r;n.__esModule=!0,n.default=void 0;var o=function(e){var t,n;function r(t){var n;return(n=e.call(this,t)||this).type="atrule",n}n=e,(t=r).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var o=r.prototype;return o.append=function(){var t;this.nodes||(this.nodes=[]);for(var n=arguments.length,r=new Array(n),o=0;o=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e&&(this.indexes[n]=t-1);return this},d.removeAll=function(){for(var e,t=a(this.nodes);!(e=t()).done;)e.value.parent=void 0;return this.nodes=[],this},d.replaceValues=function(e,t,n){return n||(n=t,t={}),this.walkDecls((function(r){t.props&&-1===t.props.indexOf(r.prop)||t.fast&&-1===r.value.indexOf(t.fast)||(r.value=r.value.replace(e,n))})),this},d.every=function(e){return this.nodes.every(e)},d.some=function(e){return this.nodes.some(e)},d.index=function(e){return"number"==typeof e?e:this.nodes.indexOf(e)},d.normalize=function(t,n){var i=this;if("string"==typeof t)t=function e(t){return t.map((function(t){return t.nodes&&(t.nodes=e(t.nodes)),delete t.source,t}))}(e("./parse")(t).nodes);else if(Array.isArray(t))for(var s,l=a(t=t.slice(0));!(s=l()).done;){var u=s.value;u.parent&&u.parent.removeChild(u,"ignore")}else if("root"===t.type)for(var c,f=a(t=t.nodes.slice(0));!(c=f()).done;){var d=c.value;d.parent&&d.parent.removeChild(d,"ignore")}else if(t.type)t=[t];else if(t.prop){if(void 0===t.value)throw new Error("Value field is missed in node creation");"string"!=typeof t.value&&(t.value=String(t.value)),t=[new r.default(t)]}else if(t.selector)t=[new(e("./rule"))(t)];else if(t.name)t=[new(e("./at-rule"))(t)];else{if(!t.text)throw new Error("Unknown node type in node creation");t=[new o.default(t)]}return t.map((function(e){return e.parent&&e.parent.removeChild(e),void 0===e.raws.before&&n&&void 0!==n.raws.before&&(e.raws.before=n.raws.before.replace(/[^\s]/g,"")),e.parent=i,e}))},u=s,(c=[{key:"first",get:function(){if(this.nodes)return this.nodes[0]}},{key:"last",get:function(){if(this.nodes)return this.nodes[this.nodes.length-1]}}])&&l(u.prototype,c),f&&l(u,f),s}(i(e("./node")).default);n.default=u,t.exports=n.default},{"./at-rule":169,"./comment":170,"./declaration":173,"./node":178,"./parse":179,"./rule":186}],172:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=a(e("supports-color")),o=a(e("chalk")),i=a(e("./terminal-highlight"));function a(e){return e&&e.__esModule?e:{default:e}}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return l(e,arguments,f(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),c(r,e)})(e)}function l(e,t,n){return(l=u()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var o=new(Function.bind.apply(e,r));return n&&c(o,n.prototype),o}).apply(null,arguments)}function u(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function c(e,t){return(c=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function f(e){return(f=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}var d=function(e){var t,n;function a(t,n,r,o,i,s){var l;return(l=e.call(this,t)||this).name="CssSyntaxError",l.reason=t,i&&(l.file=i),o&&(l.source=o),s&&(l.plugin=s),void 0!==n&&void 0!==r&&(l.line=n,l.column=r),l.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(l),a),l}n=e,(t=a).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n;var s=a.prototype;return s.setMessage=function(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",void 0!==this.line&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason},s.showSourceCode=function(e){var t=this;if(!this.source)return"";var n=this.source;i.default&&(void 0===e&&(e=r.default.stdout),e&&(n=(0,i.default)(n)));var a=n.split(/\r?\n/),s=Math.max(this.line-3,0),l=Math.min(this.line+2,a.length),u=String(l).length;function c(t){return e&&o.default.red?o.default.red.bold(t):t}function f(t){return e&&o.default.gray?o.default.gray(t):t}return a.slice(s,l).map((function(e,n){var r=s+1+n,o=" "+(" "+r).slice(-u)+" | ";if(r===t.line){var i=f(o.replace(/\d/g," "))+e.slice(0,t.column-1).replace(/[^\t]/g," ");return c(">")+f(o)+e+"\n "+i+c("^")}return" "+f(o)+e})).join("\n")},s.toString=function(){var e=this.showSourceCode();return e&&(e="\n\n"+e+"\n"),this.name+": "+this.message+e},a}(s(Error));n.default=d,t.exports=n.default},{"./terminal-highlight":2,chalk:2,"supports-color":2}],173:[function(e,t,n){var r;n.__esModule=!0,n.default=void 0;var o=function(e){var t,n;function r(t){var n;return(n=e.call(this,t)||this).type="decl",n}return n=e,(t=r).prototype=Object.create(n.prototype),t.prototype.constructor=t,t.__proto__=n,r}(((r=e("./node"))&&r.__esModule?r:{default:r}).default);n.default=o,t.exports=n.default},{"./node":178}],174:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=a(e("path")),o=a(e("./css-syntax-error")),i=a(e("./previous-map"));function a(e){return e&&e.__esModule?e:{default:e}}function s(e,t){for(var n=0;n"),this.map&&(this.map.file=this.from)}var t,n,a,c=e.prototype;return c.error=function(e,t,n,r){var i;void 0===r&&(r={});var a=this.origin(t,n);return(i=a?new o.default(e,a.line,a.column,a.source,a.file,r.plugin):new o.default(e,t,n,this.css,this.file,r.plugin)).input={line:t,column:n,source:this.css},this.file&&(i.input.file=this.file),i},c.origin=function(e,t){if(!this.map)return!1;var n=this.map.consumer(),r=n.originalPositionFor({line:e,column:t});if(!r.source)return!1;var o={file:this.mapResolve(r.source),line:r.line,column:r.column},i=n.sourceContentFor(r.source);return i&&(o.source=i),o},c.mapResolve=function(e){return/^\w+:\/\//.test(e)?e:r.default.resolve(this.map.consumer().sourceRoot||".",e)},t=e,(n=[{key:"from",get:function(){return this.file||this.id}}])&&s(t.prototype,n),a&&s(t,a),e}();n.default=c,t.exports=n.default},{"./css-syntax-error":172,"./previous-map":182,path:168}],175:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o=c(e("./map-generator")),i=c(e("./stringify")),a=c(e("./warn-once")),s=c(e("./result")),l=c(e("./parse"));function c(e){return e&&e.__esModule?e:{default:e}}function f(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return d(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);nparseInt(s[1]))&&console.error("Unknown error from PostCSS plugin. Your current PostCSS version is "+i+", but "+n+" uses "+o+". Perhaps this is the source of the error below.")}}else e.plugin=t.postcssPlugin,e.setMessage()}catch(e){console&&console.error&&console.error(e)}},d.asyncTick=function(e,t){var n=this;if(this.plugin>=this.processor.plugins.length)return this.processed=!0,e();try{var r=this.processor.plugins[this.plugin],o=this.run(r);this.plugin+=1,h(o)?o.then((function(){n.asyncTick(e,t)})).catch((function(e){n.handleError(e,r),n.processed=!0,t(e)})):this.asyncTick(e,t)}catch(e){this.processed=!0,t(e)}},d.async=function(){var e=this;return this.processed?new Promise((function(t,n){e.error?n(e.error):t(e.stringify())})):(this.processing||(this.processing=new Promise((function(t,n){if(e.error)return n(e.error);e.plugin=0,e.asyncTick(t,n)})).then((function(){return e.processed=!0,e.stringify()}))),this.processing)},d.sync=function(){if(this.processed)return this.result;if(this.processed=!0,this.processing)throw new Error("Use process(css).then(cb) to work with async plugins");if(this.error)throw this.error;for(var e,t=f(this.result.processor.plugins);!(e=t()).done;){var n=e.value;if(h(this.run(n)))throw new Error("Use process(css).then(cb) to work with async plugins")}return this.result},d.run=function(e){this.result.lastPlugin=e;try{return e(this.result.root,this.result)}catch(t){throw this.handleError(t,e),t}},d.stringify=function(){if(this.stringified)return this.result;this.stringified=!0,this.sync();var e=this.result.opts,t=i.default;e.syntax&&(t=e.syntax.stringify),e.stringifier&&(t=e.stringifier),t.stringify&&(t=t.stringify);var n=new o.default(t,this.result.root,this.result.opts).generate();return this.result.css=n[0],this.result.map=n[1],this.result},t=e,(n=[{key:"processor",get:function(){return this.result.processor}},{key:"opts",get:function(){return this.result.opts}},{key:"css",get:function(){return this.stringify().css}},{key:"content",get:function(){return this.stringify().content}},{key:"map",get:function(){return this.stringify().map}},{key:"root",get:function(){return this.sync().root}},{key:"messages",get:function(){return this.sync().messages}}])&&p(t.prototype,n),c&&p(t,c),e}();n.default=m,t.exports=n.default}).call(this,e("_process"))},{"./map-generator":177,"./parse":179,"./result":184,"./stringify":188,"./warn-once":191,_process:193}],176:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r={split:function(e,t,n){for(var r=[],o="",i=!1,a=0,s=!1,l=!1,u=0;u0&&(a-=1):0===a&&-1!==t.indexOf(c)&&(i=!0),i?(""!==o&&r.push(o.trim()),o="",i=!1):o+=c}return(n||""!==o)&&r.push(o.trim()),r},space:function(e){return r.split(e,[" ","\n","\t"])},comma:function(e){return r.split(e,[","],!0)}},o=r;n.default=o,t.exports=n.default},{}],177:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o=a(e("source-map")),i=a(e("path"));function a(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return l(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0},t.previous=function(){var e=this;return this.previousMaps||(this.previousMaps=[],this.root.walk((function(t){if(t.source&&t.source.input.map){var n=t.source.input.map;-1===e.previousMaps.indexOf(n)&&e.previousMaps.push(n)}}))),this.previousMaps},t.isInline=function(){if(void 0!==this.mapOpts.inline)return this.mapOpts.inline;var e=this.mapOpts.annotation;return(void 0===e||!0===e)&&(!this.previous().length||this.previous().some((function(e){return e.inline})))},t.isSourcesContent=function(){return void 0!==this.mapOpts.sourcesContent?this.mapOpts.sourcesContent:!this.previous().length||this.previous().some((function(e){return e.withContent()}))},t.clearAnnotation=function(){if(!1!==this.mapOpts.annotation)for(var e,t=this.root.nodes.length-1;t>=0;t--)"comment"===(e=this.root.nodes[t]).type&&0===e.text.indexOf("# sourceMappingURL=")&&this.root.removeChild(t)},t.setSourcesContent=function(){var e=this,t={};this.root.walk((function(n){if(n.source){var r=n.source.input.from;if(r&&!t[r]){t[r]=!0;var o=e.relative(r);e.map.setSourceContent(o,n.source.input.css)}}}))},t.applyPrevMaps=function(){for(var e,t=s(this.previous());!(e=t()).done;){var n=e.value,r=this.relative(n.file),a=n.root||i.default.dirname(n.file),l=void 0;!1===this.mapOpts.sourcesContent?(l=new o.default.SourceMapConsumer(n.text)).sourcesContent&&(l.sourcesContent=l.sourcesContent.map((function(){return null}))):l=n.consumer(),this.map.applySourceMap(l,r,this.relative(a))}},t.isAnnotation=function(){return!!this.isInline()||(void 0!==this.mapOpts.annotation?this.mapOpts.annotation:!this.previous().length||this.previous().some((function(e){return e.annotation})))},t.toBase64=function(e){return r?r.from(e).toString("base64"):window.btoa(unescape(encodeURIComponent(e)))},t.addAnnotation=function(){var e;e=this.isInline()?"data:application/json;base64,"+this.toBase64(this.map.toString()):"string"==typeof this.mapOpts.annotation?this.mapOpts.annotation:this.outputFile()+".map";var t="\n";-1!==this.css.indexOf("\r\n")&&(t="\r\n"),this.css+=t+"/*# sourceMappingURL="+e+" */"},t.outputFile=function(){return this.opts.to?this.relative(this.opts.to):this.opts.from?this.relative(this.opts.from):"to.css"},t.generateMap=function(){return this.generateString(),this.isSourcesContent()&&this.setSourcesContent(),this.previous().length>0&&this.applyPrevMaps(),this.isAnnotation()&&this.addAnnotation(),this.isInline()?[this.css]:[this.css,this.map]},t.relative=function(e){if(0===e.indexOf("<"))return e;if(/^\w+:\/\//.test(e))return e;var t=this.opts.to?i.default.dirname(this.opts.to):".";return"string"==typeof this.mapOpts.annotation&&(t=i.default.dirname(i.default.resolve(t,this.mapOpts.annotation))),e=i.default.relative(t,e),"\\"===i.default.sep?e.replace(/\\/g,"/"):e},t.sourcePath=function(e){return this.mapOpts.from?this.mapOpts.from:this.relative(e.source.input.from)},t.generateString=function(){var e=this;this.css="",this.map=new o.default.SourceMapGenerator({file:this.outputFile()});var t,n,r=1,i=1;this.stringify(this.root,(function(o,a,s){if(e.css+=o,a&&"end"!==s&&(a.source&&a.source.start?e.map.addMapping({source:e.sourcePath(a),generated:{line:r,column:i-1},original:{line:a.source.start.line,column:a.source.start.column-1}}):e.map.addMapping({source:"",original:{line:1,column:0},generated:{line:r,column:i-1}})),(t=o.match(/\n/g))?(r+=t.length,n=o.lastIndexOf("\n"),i=o.length-n):i+=o.length,a&&"start"!==s){var l=a.parent||{raws:{}};("decl"!==a.type||a!==l.last||l.raws.semicolon)&&(a.source&&a.source.end?e.map.addMapping({source:e.sourcePath(a),generated:{line:r,column:i-2},original:{line:a.source.end.line,column:a.source.end.column-1}}):e.map.addMapping({source:"",original:{line:1,column:0},generated:{line:r,column:i-1}}))}}))},t.generate=function(){if(this.clearAnnotation(),this.isMap())return this.generateMap();var e="";return this.stringify(this.root,(function(t){e+=t})),[e]},e}();n.default=u,t.exports=n.default}).call(this,e("buffer").Buffer)},{buffer:3,path:168,"source-map":208}],178:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o=s(e("./css-syntax-error")),i=s(e("./stringifier")),a=s(e("./stringify"));function s(e){return e&&e.__esModule?e:{default:e}}var l=function(){function e(e){if(void 0===e&&(e={}),this.raws={},"production"!==r.env.NODE_ENV&&"object"!==u(e)&&void 0!==e)throw new Error("PostCSS nodes constructor accepts object, not "+JSON.stringify(e));for(var t in e)this[t]=e[t]}var t=e.prototype;return t.error=function(e,t){if(void 0===t&&(t={}),this.source){var n=this.positionBy(t);return this.source.input.error(e,n.line,n.column,t)}return new o.default(e)},t.warn=function(e,t,n){var r={node:this};for(var o in n)r[o]=n[o];return e.warn(t,r)},t.remove=function(){return this.parent&&this.parent.removeChild(this),this.parent=void 0,this},t.toString=function(e){void 0===e&&(e=a.default),e.stringify&&(e=e.stringify);var t="";return e(this,(function(e){t+=e})),t},t.clone=function(e){void 0===e&&(e={});var t=function e(t,n){var r=new t.constructor;for(var o in t)if(t.hasOwnProperty(o)){var i=t[o],a=u(i);"parent"===o&&"object"===a?n&&(r[o]=n):"source"===o?r[o]=i:i instanceof Array?r[o]=i.map((function(t){return e(t,r)})):("object"===a&&null!==i&&(i=e(i)),r[o]=i)}return r}(this);for(var n in e)t[n]=e[n];return t},t.cloneBefore=function(e){void 0===e&&(e={});var t=this.clone(e);return this.parent.insertBefore(this,t),t},t.cloneAfter=function(e){void 0===e&&(e={});var t=this.clone(e);return this.parent.insertAfter(this,t),t},t.replaceWith=function(){if(this.parent){for(var e=arguments.length,t=new Array(e),n=0;n0&&this.unclosedBracket(o),t&&r){for(;a.length&&("space"===(s=a[a.length-1][0])||"comment"===s);)this.tokenizer.back(a.pop());this.decl(a)}else this.unknownWord(a)},t.rule=function(e){e.pop();var t=new l.default;this.init(t,e[0][2],e[0][3]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t},t.decl=function(e){var t=new r.default;this.init(t);var n,o=e[e.length-1];for(";"===o[0]&&(this.semicolon=!0,e.pop()),o[4]?t.source.end={line:o[4],column:o[5]}:t.source.end={line:o[2],column:o[3]};"word"!==e[0][0];)1===e.length&&this.unknownWord(e),t.raws.before+=e.shift()[1];for(t.source.start={line:e[0][2],column:e[0][3]},t.prop="";e.length;){var i=e[0][0];if(":"===i||"space"===i||"comment"===i)break;t.prop+=e.shift()[1]}for(t.raws.between="";e.length;){if(":"===(n=e.shift())[0]){t.raws.between+=n[1];break}"word"===n[0]&&/\w/.test(n[1])&&this.unknownWord([n]),t.raws.between+=n[1]}"_"!==t.prop[0]&&"*"!==t.prop[0]||(t.raws.before+=t.prop[0],t.prop=t.prop.slice(1)),t.raws.between+=this.spacesAndCommentsFromStart(e),this.precheckMissedSemicolon(e);for(var a=e.length-1;a>0;a--){if("!important"===(n=e[a])[1].toLowerCase()){t.important=!0;var s=this.stringFrom(e,a);" !important"!==(s=this.spacesFromEnd(e)+s)&&(t.raws.important=s);break}if("important"===n[1].toLowerCase()){for(var l=e.slice(0),u="",c=a;c>0;c--){var f=l[c][0];if(0===u.trim().indexOf("!")&&"space"!==f)break;u=l.pop()[1]+u}0===u.trim().indexOf("!")&&(t.important=!0,t.raws.important=u,e=l)}if("space"!==n[0]&&"comment"!==n[0])break}this.raw(t,"value",e),-1!==t.value.indexOf(":")&&this.checkMissedSemicolon(e)},t.atrule=function(e){var t,n,r=new a.default;r.name=e[1].slice(1),""===r.name&&this.unnamedAtrule(r,e),this.init(r,e[2],e[3]);for(var o=!1,i=!1,s=[];!this.tokenizer.endOfFile();){if(";"===(e=this.tokenizer.nextToken())[0]){r.source.end={line:e[2],column:e[3]},this.semicolon=!0;break}if("{"===e[0]){i=!0;break}if("}"===e[0]){if(s.length>0){for(t=s[n=s.length-1];t&&"space"===t[0];)t=s[--n];t&&(r.source.end={line:t[4],column:t[5]})}this.end(e);break}if(s.push(e),this.tokenizer.endOfFile()){o=!0;break}}r.raws.between=this.spacesAndCommentsFromEnd(s),s.length?(r.raws.afterName=this.spacesAndCommentsFromStart(s),this.raw(r,"params",s),o&&(e=s[s.length-1],r.source.end={line:e[4],column:e[5]},this.spaces=r.raws.between,r.raws.between="")):(r.raws.afterName="",r.params=""),i&&(r.nodes=[],this.current=r)},t.end=function(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end={line:e[2],column:e[3]},this.current=this.current.parent):this.unexpectedClose(e)},t.endFile=function(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces},t.freeSemicolon=function(e){if(this.spaces+=e[1],this.current.nodes){var t=this.current.nodes[this.current.nodes.length-1];t&&"rule"===t.type&&!t.raws.ownSemicolon&&(t.raws.ownSemicolon=this.spaces,this.spaces="")}},t.init=function(e,t,n){this.current.push(e),e.source={start:{line:t,column:n},input:this.input},e.raws.before=this.spaces,this.spaces="","comment"!==e.type&&(this.semicolon=!1)},t.raw=function(e,t,n){for(var r,o,i,a,s=n.length,l="",u=!0,c=/^([.|#])?([\w])+/i,f=0;f=0&&("space"===(n=e[o])[0]||2!==(r+=1));o--);throw this.input.error("Missed semicolon",n[2],n[3])}},e}();n.default=c,t.exports=n.default},{"./at-rule":169,"./comment":170,"./declaration":173,"./root":185,"./rule":186,"./tokenize":189}],181:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=p(e("./declaration")),o=p(e("./processor")),i=p(e("./stringify")),a=p(e("./comment")),s=p(e("./at-rule")),l=p(e("./vendor")),u=p(e("./parse")),c=p(e("./list")),f=p(e("./rule")),d=p(e("./root"));function p(e){return e&&e.__esModule?e:{default:e}}function h(){for(var e=arguments.length,t=new Array(e),n=0;n0)},t.startWith=function(e,t){return!!e&&e.substr(0,t.length)===t},t.getAnnotationURL=function(e){return e.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//)[1].trim()},t.loadAnnotation=function(e){var t=e.match(/\/\*\s*# sourceMappingURL=(.*)\s*\*\//gm);if(t&&t.length>0){var n=t[t.length-1];n&&(this.annotation=this.getAnnotationURL(n))}},t.decodeInline=function(e){var t,n="data:application/json,";if(this.startWith(e,n))return decodeURIComponent(e.substr(n.length));if(/^data:application\/json;charset=utf-?8;base64,/.test(e)||/^data:application\/json;base64,/.test(e))return t=e.substr(RegExp.lastMatch.length),r?r.from(t,"base64").toString():window.atob(t);var o=e.match(/data:application\/json;([^,]+),/)[1];throw new Error("Unsupported source map encoding "+o)},t.loadMap=function(e,t){if(!1===t)return!1;if(t){if("string"==typeof t)return t;if("function"==typeof t){var n=t(e);if(n&&a.default.existsSync&&a.default.existsSync(n))return a.default.readFileSync(n,"utf-8").toString().trim();throw new Error("Unable to load previous source map: "+n.toString())}if(t instanceof o.default.SourceMapConsumer)return o.default.SourceMapGenerator.fromSourceMap(t).toString();if(t instanceof o.default.SourceMapGenerator)return t.toString();if(this.isMap(t))return JSON.stringify(t);throw new Error("Unsupported previous source map format: "+t.toString())}if(this.inline)return this.decodeInline(this.annotation);if(this.annotation){var r=this.annotation;return e&&(r=i.default.join(i.default.dirname(e),r)),this.root=i.default.dirname(r),!(!a.default.existsSync||!a.default.existsSync(r))&&a.default.readFileSync(r,"utf-8").toString().trim()}},t.isMap=function(e){return"object"===u(e)&&("string"==typeof e.mappings||"string"==typeof e._mappings)},e}();n.default=l,t.exports=n.default}).call(this,e("buffer").Buffer)},{buffer:3,fs:2,path:168,"source-map":208}],183:[function(e,t,n){(function(r){n.__esModule=!0,n.default=void 0;var o,i=(o=e("./lazy-result"))&&o.__esModule?o:{default:o};function a(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&(this.nodes[1].raws.before=this.nodes[r].raws.before),t.prototype.removeChild.call(this,e)},a.normalize=function(e,n,r){var i=t.prototype.normalize.call(this,e);if(n)if("prepend"===r)this.nodes.length>1?n.raws.before=this.nodes[1].raws.before:delete n.raws.before;else if(this.first!==n)for(var a,s=o(i);!(a=s()).done;)a.value.raws.before=n.raws.before;return i},a.toResult=function(t){return void 0===t&&(t={}),new(e("./lazy-result"))(new(e("./processor")),this,t).stringify()},i}(((r=e("./container"))&&r.__esModule?r:{default:r}).default);n.default=a,t.exports=n.default},{"./container":171,"./lazy-result":175,"./processor":183}],186:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=i(e("./container")),o=i(e("./list"));function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){for(var n=0;n0&&"comment"===e.nodes[t].type;)t-=1;for(var n=this.raw(e,"semicolon"),r=0;r0&&void 0!==e.raws.after)return-1!==(t=e.raws.after).indexOf("\n")&&(t=t.replace(/[^\n]+$/,"")),!1})),t&&(t=t.replace(/[^\s]/g,"")),t},t.rawBeforeOpen=function(e){var t;return e.walk((function(e){if("decl"!==e.type&&void 0!==(t=e.raws.between))return!1})),t},t.rawColon=function(e){var t;return e.walkDecls((function(e){if(void 0!==e.raws.between)return t=e.raws.between.replace(/[^\s:]/g,""),!1})),t},t.beforeAfter=function(e,t){var n;n="decl"===e.type?this.raw(e,null,"beforeDecl"):"comment"===e.type?this.raw(e,null,"beforeComment"):"before"===t?this.raw(e,null,"beforeRule"):this.raw(e,null,"beforeClose");for(var r=e.parent,o=0;r&&"root"!==r.type;)o+=1,r=r.parent;if(-1!==n.indexOf("\n")){var i=this.raw(e,null,"indent");if(i.length)for(var a=0;a=U)){var t=!!e&&e.ignoreUnclosed;switch(((n=F.charCodeAt(H))===s||n===u||n===f&&F.charCodeAt(H+1)!==s)&&(V=H,z+=1),n){case s:case l:case c:case f:case u:j=H;do{j+=1,(n=F.charCodeAt(j))===s&&(V=j,z+=1)}while(n===l||n===s||n===c||n===f||n===u);I=["space",F.slice(H,j)],H=j-1;break;case d:case p:case g:case v:case _:case b:case m:var $=String.fromCharCode(n);I=[$,$,z,H-V];break;case h:if(D=W.length?W.pop()[1]:"",R=F.charCodeAt(H+1),"url"===D&&R!==r&&R!==o&&R!==l&&R!==s&&R!==c&&R!==u&&R!==f){j=H;do{if(M=!1,-1===(j=F.indexOf(")",j+1))){if(B||t){j=H;break}K("bracket")}for(L=j;F.charCodeAt(L-1)===i;)L-=1,M=!M}while(M);I=["brackets",F.slice(H,j+1),z,H-V,z,j-V],H=j}else j=F.indexOf(")",H+1),A=F.slice(H,j+1),-1===j||k.test(A)?I=["(","(",z,H-V]:(I=["brackets",A,z,H-V,z,j-V],H=j);break;case r:case o:E=n===r?"'":'"',j=H;do{if(M=!1,-1===(j=F.indexOf(E,j+1))){if(B||t){j=H+1;break}K("string")}for(L=j;F.charCodeAt(L-1)===i;)L-=1,M=!M}while(M);A=F.slice(H,j+1),C=A.split("\n"),(N=C.length-1)>0?(T=z+N,P=j-C[N].length):(T=z,P=V),I=["string",F.slice(H,j+1),z,H-V,T,j-P],V=P,z=T,H=j;break;case w:x.lastIndex=H+1,x.test(F),j=0===x.lastIndex?F.length-1:x.lastIndex-2,I=["at-word",F.slice(H,j+1),z,H-V,z,j-V],H=j;break;case i:for(j=H,q=!0;F.charCodeAt(j+1)===i;)j+=1,q=!q;if(n=F.charCodeAt(j+1),q&&n!==a&&n!==l&&n!==s&&n!==c&&n!==f&&n!==u&&(j+=1,S.test(F.charAt(j)))){for(;S.test(F.charAt(j+1));)j+=1;F.charCodeAt(j+1)===l&&(j+=1)}I=["word",F.slice(H,j+1),z,H-V,z,j-V],H=j;break;default:n===a&&F.charCodeAt(H+1)===y?(0===(j=F.indexOf("*/",H+2)+1)&&(B||t?j=F.length:K("comment")),A=F.slice(H,j+1),C=A.split("\n"),(N=C.length-1)>0?(T=z+N,P=j-C[N].length):(T=z,P=V),I=["comment",A,z,H-V,T,j-P],V=P,z=T,H=j):(O.lastIndex=H+1,O.test(F),j=0===O.lastIndex?F.length-1:O.lastIndex-2,I=["word",F.slice(H,j+1),z,H-V,z,j-V],W.push(I),H=j)}return H++,I}},endOfFile:function(){return 0===G.length&&H>=U},position:function(){return H}}};var r="'".charCodeAt(0),o='"'.charCodeAt(0),i="\\".charCodeAt(0),a="/".charCodeAt(0),s="\n".charCodeAt(0),l=" ".charCodeAt(0),u="\f".charCodeAt(0),c="\t".charCodeAt(0),f="\r".charCodeAt(0),d="[".charCodeAt(0),p="]".charCodeAt(0),h="(".charCodeAt(0),m=")".charCodeAt(0),g="{".charCodeAt(0),v="}".charCodeAt(0),b=";".charCodeAt(0),y="*".charCodeAt(0),_=":".charCodeAt(0),w="@".charCodeAt(0),x=/[ \n\t\r\f{}()'"\\;/[\]#]/g,O=/[ \n\t\r\f(){}:;@!'"\\\][#]|\/(?=\*)/g,k=/.[\\/("'\n]/,S=/[a-f0-9]/i;t.exports=n.default},{}],190:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r={prefix:function(e){var t=e.match(/^(-\w+-)/);return t?t[0]:""},unprefixed:function(e){return e.replace(/^-\w+-/,"")}};n.default=r,t.exports=n.default},{}],191:[function(e,t,n){n.__esModule=!0,n.default=function(e){r[e]||(r[e]=!0,"undefined"!=typeof console&&console.warn&&console.warn(e))};var r={};t.exports=n.default},{}],192:[function(e,t,n){n.__esModule=!0,n.default=void 0;var r=function(){function e(e,t){if(void 0===t&&(t={}),this.type="warning",this.text=e,t.node&&t.node.source){var n=t.node.positionBy(t);this.line=n.line,this.column=n.column}for(var r in t)this[r]=t[r]}return e.prototype.toString=function(){return this.node?this.node.error(this.text,{plugin:this.plugin,index:this.index,word:this.word}).message:this.plugin?this.plugin+": "+this.text:this.text},e}();n.default=r,t.exports=n.default},{}],193:[function(e,t,n){var r,o,i=t.exports={};function a(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function l(e){if(r===setTimeout)return setTimeout(e,0);if((r===a||!r)&&setTimeout)return r=setTimeout,setTimeout(e,0);try{return r(e,0)}catch(t){try{return r.call(null,e,0)}catch(t){return r.call(this,e,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:a}catch(e){r=a}try{o="function"==typeof clearTimeout?clearTimeout:s}catch(e){o=s}}();var u,c=[],f=!1,d=-1;function p(){f&&u&&(f=!1,u.length?c=u.concat(c):d=-1,c.length&&h())}function h(){if(!f){var e=l(p);f=!0;for(var t=c.length;t;){for(u=c,c=[];++d1)for(var n=1;n= 0x80 (not a basic code point)","invalid-input":"Invalid input"},m=Math.floor,g=String.fromCharCode;function v(e){throw new RangeError(h[e])}function b(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function y(e,t){var n=e.split("@"),r="";return n.length>1&&(r=n[0]+"@",e=n[1]),r+b((e=e.replace(p,".")).split("."),t).join(".")}function _(e){for(var t,n,r=[],o=0,i=e.length;o=55296&&t<=56319&&o65535&&(t+=g((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+=g(e)})).join("")}function x(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function O(e,t,n){var r=0;for(e=n?m(e/700):e>>1,e+=m(e/t);e>455;r+=36)e=m(e/35);return m(r+36*e/(e+38))}function k(e){var t,n,r,o,i,a,s,l,u,f,d,p=[],h=e.length,g=0,b=128,y=72;for((n=e.lastIndexOf("-"))<0&&(n=0),r=0;r=128&&v("not-basic"),p.push(e.charCodeAt(r));for(o=n>0?n+1:0;o=h&&v("invalid-input"),((l=(d=e.charCodeAt(o++))-48<10?d-22:d-65<26?d-65:d-97<26?d-97:36)>=36||l>m((c-g)/a))&&v("overflow"),g+=l*a,!(l<(u=s<=y?1:s>=y+26?26:s-y));s+=36)a>m(c/(f=36-u))&&v("overflow"),a*=f;y=O(g-i,t=p.length+1,0==i),m(g/t)>c-b&&v("overflow"),b+=m(g/t),g%=t,p.splice(g++,0,b)}return w(p)}function S(e){var t,n,r,o,i,a,s,l,u,f,d,p,h,b,y,w=[];for(p=(e=_(e)).length,t=128,n=0,i=72,a=0;a=t&&dm((c-n)/(h=r+1))&&v("overflow"),n+=(s-t)*h,t=s,a=0;ac&&v("overflow"),d==t){for(l=n,u=36;!(l<(f=u<=i?1:u>=i+26?26:u-i));u+=36)y=l-f,b=36-f,w.push(g(x(f+y%b,0))),l=m(y/b);w.push(g(x(l,0))),i=O(n,h,r==o),n=0,++r}++n,++t}return w.join("")}if(s={version:"1.4.1",ucs2:{decode:_,encode:w},decode:k,encode:S,toASCII:function(e){return y(e,(function(e){return d.test(e)?"xn--"+S(e):e}))},toUnicode:function(e){return y(e,(function(e){return f.test(e)?k(e.slice(4).toLowerCase()):e}))}},o&&i)if(t.exports==o)i.exports=s;else for(l in s)s.hasOwnProperty(l)&&(o[l]=s[l]);else n.punycode=s}(this)}).call(this,void 0!==n?n:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],195:[function(e,t,n){function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.exports=function(e,t,n,i){t=t||"&",n=n||"=";var a={};if("string"!=typeof e||0===e.length)return a;var s=/\+/g;e=e.split(t);var l=1e3;i&&"number"==typeof i.maxKeys&&(l=i.maxKeys);var u=e.length;l>0&&u>l&&(u=l);for(var c=0;c=0?(f=m.substr(0,g),d=m.substr(g+1)):(f=m,d=""),p=decodeURIComponent(f),h=decodeURIComponent(d),r(a,p)?o(a[p])?a[p].push(h):a[p]=[a[p],h]:a[p]=h}return a};var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},{}],196:[function(e,t,n){var r=function(e){switch(u(e)){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};t.exports=function(e,t,n,s){return t=t||"&",n=n||"=",null===e&&(e=void 0),"object"===u(e)?i(a(e),(function(a){var s=encodeURIComponent(r(a))+n;return o(e[a])?i(e[a],(function(e){return s+encodeURIComponent(r(e))})).join(t):s+encodeURIComponent(r(e[a]))})).join(t):s?encodeURIComponent(r(s))+n+encodeURIComponent(r(e)):""};var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};function i(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r=0)return t}else{var n=r.toSetString(e);if(o.call(this._set,n))return this._set[n]}throw new Error('"'+e+'" is not in the set.')},a.prototype.at=function(e){if(e>=0&&e>>=5)>0&&(t|=32),n+=r.encode(t)}while(o>0);return n},n.decode=function(e,t,n){var o,i,a,s,l=e.length,u=0,c=0;do{if(t>=l)throw new Error("Expected more digits in base 64 VLQ value.");if(-1===(i=r.decode(e.charCodeAt(t++))))throw new Error("Invalid base64 digit: "+e.charAt(t-1));o=!!(32&i),u+=(i&=31)<>1,1==(1&a)?-s:s),n.rest=t}},{"./base64":200}],200:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");n.encode=function(e){if(0<=e&&e0?r-l>1?e(l,r,o,i,a,s):s==n.LEAST_UPPER_BOUND?r1?e(t,l,o,i,a,s):s==n.LEAST_UPPER_BOUND?l:t<0?-1:t}(-1,t.length,e,t,r,o||n.GREATEST_LOWER_BOUND);if(i<0)return-1;for(;i-1>=0&&0===r(t[i],t[i-1],!0);)--i;return i}},{}],202:[function(e,t,n){var r=e("./util");function o(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}o.prototype.unsortedForEach=function(e,t){this._array.forEach(e,t)},o.prototype.add=function(e){var t,n,o,i,a,s;t=this._last,n=e,o=t.generatedLine,i=n.generatedLine,a=t.generatedColumn,s=n.generatedColumn,i>o||i==o&&s>=a||r.compareByGeneratedPositionsInflated(t,n)<=0?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},o.prototype.toArray=function(){return this._sorted||(this._array.sort(r.compareByGeneratedPositionsInflated),this._sorted=!0),this._array},n.MappingList=o},{"./util":207}],203:[function(e,t,n){function r(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function o(e,t,n,i){if(n=0){var s=this._originalMappings[a];if(void 0===e.column)for(var l=s.originalLine;s&&s.originalLine===l;)i.push({line:r.getArg(s,"generatedLine",null),column:r.getArg(s,"generatedColumn",null),lastColumn:r.getArg(s,"lastGeneratedColumn",null)}),s=this._originalMappings[++a];else for(var u=s.originalColumn;s&&s.originalLine===t&&s.originalColumn==u;)i.push({line:r.getArg(s,"generatedLine",null),column:r.getArg(s,"generatedColumn",null),lastColumn:r.getArg(s,"lastGeneratedColumn",null)}),s=this._originalMappings[++a]}return i},n.SourceMapConsumer=l,u.prototype=Object.create(l.prototype),u.prototype.consumer=l,u.prototype._findSourceIndex=function(e){var t,n=e;if(null!=this.sourceRoot&&(n=r.relative(this.sourceRoot,n)),this._sources.has(n))return this._sources.indexOf(n);for(t=0;t1&&(n.source=m+i[1],m+=i[1],n.originalLine=p+i[2],p=n.originalLine,n.originalLine+=1,n.originalColumn=h+i[3],h=n.originalColumn,i.length>4&&(n.name=g+i[4],g+=i[4])),x.push(n),"number"==typeof n.originalLine&&w.push(n)}s(x,r.compareByGeneratedPositionsDeflated),this.__generatedMappings=x,s(w,r.compareByOriginalPositions),this.__originalMappings=w},u.prototype._findMapping=function(e,t,n,r,i,a){if(e[n]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[n]);if(e[r]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[r]);return o.search(e,t,i,a)},u.prototype.computeColumnSpans=function(){for(var e=0;e=0){var o=this._generatedMappings[n];if(o.generatedLine===t.generatedLine){var i=r.getArg(o,"source",null);null!==i&&(i=this._sources.at(i),i=r.computeSourceURL(this.sourceRoot,i,this._sourceMapURL));var a=r.getArg(o,"name",null);return null!==a&&(a=this._names.at(a)),{source:i,line:r.getArg(o,"originalLine",null),column:r.getArg(o,"originalColumn",null),name:a}}}return{source:null,line:null,column:null,name:null}},u.prototype.hasContentsOfAllSources=function(){return!!this.sourcesContent&&this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return null==e}))},u.prototype.sourceContentFor=function(e,t){if(!this.sourcesContent)return null;var n=this._findSourceIndex(e);if(n>=0)return this.sourcesContent[n];var o,i=e;if(null!=this.sourceRoot&&(i=r.relative(this.sourceRoot,i)),null!=this.sourceRoot&&(o=r.urlParse(this.sourceRoot))){var a=i.replace(/^file:\/\//,"");if("file"==o.scheme&&this._sources.has(a))return this.sourcesContent[this._sources.indexOf(a)];if((!o.path||"/"==o.path)&&this._sources.has("/"+i))return this.sourcesContent[this._sources.indexOf("/"+i)]}if(t)return null;throw new Error('"'+i+'" is not in the SourceMap.')},u.prototype.generatedPositionFor=function(e){var t=r.getArg(e,"source");if((t=this._findSourceIndex(t))<0)return{line:null,column:null,lastColumn:null};var n={source:t,originalLine:r.getArg(e,"line"),originalColumn:r.getArg(e,"column")},o=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",r.compareByOriginalPositions,r.getArg(e,"bias",l.GREATEST_LOWER_BOUND));if(o>=0){var i=this._originalMappings[o];if(i.source===n.source)return{line:r.getArg(i,"generatedLine",null),column:r.getArg(i,"generatedColumn",null),lastColumn:r.getArg(i,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},n.BasicSourceMapConsumer=u,f.prototype=Object.create(l.prototype),f.prototype.constructor=l,f.prototype._version=3,Object.defineProperty(f.prototype,"sources",{get:function(){for(var e=[],t=0;t0&&e.column>=0)||t||n||r)&&!(e&&"line"in e&&"column"in e&&t&&"line"in t&&"column"in t&&e.line>0&&e.column>=0&&t.line>0&&t.column>=0&&n))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:t,name:r}))},s.prototype._serializeMappings=function(){for(var e,t,n,i,a=0,s=1,l=0,u=0,c=0,f=0,d="",p=this._mappings.toArray(),h=0,m=p.length;h0){if(!o.compareByGeneratedPositionsInflated(t,p[h-1]))continue;e+=","}e+=r.encode(t.generatedColumn-a),a=t.generatedColumn,null!=t.source&&(i=this._sources.indexOf(t.source),e+=r.encode(i-f),f=i,e+=r.encode(t.originalLine-1-u),u=t.originalLine-1,e+=r.encode(t.originalColumn-l),l=t.originalColumn,null!=t.name&&(n=this._names.indexOf(t.name),e+=r.encode(n-c),c=n)),d+=e}return d},s.prototype._generateSourcesContent=function(e,t){return e.map((function(e){if(!this._sourcesContents)return null;null!=t&&(e=o.relative(t,e));var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)},s.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},s.prototype.toString=function(){return JSON.stringify(this.toJSON())},n.SourceMapGenerator=s},{"./array-set":198,"./base64-vlq":199,"./mapping-list":202,"./util":207}],206:[function(e,t,n){var r=e("./source-map-generator").SourceMapGenerator,o=e("./util"),i=/(\r?\n)/,a="$$$isSourceNode$$$";function s(e,t,n,r,o){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==t?null:t,this.source=null==n?null:n,this.name=null==o?null:o,this[a]=!0,null!=r&&this.add(r)}s.fromStringWithSourceMap=function(e,t,n){var r=new s,a=e.split(i),l=0,u=function(){return e()+(e()||"");function e(){return l=0;t--)this.prepend(e[t]);else{if(!e[a]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},s.prototype.walk=function(e){for(var t,n=0,r=this.children.length;n0){for(t=[],n=0;n=0;c--)"."===(o=l[c])?l.splice(c,1):".."===o?u++:u>0&&(""===o?(l.splice(c+1,u),u=0):(l.splice(c,2),u--));return""===(t=l.join("/"))&&(t=s?"/":"."),r?(r.path=t,a(r)):t}function l(e,t){""===e&&(e="."),""===t&&(t=".");var n=i(t),r=i(e);if(r&&(e=r.path||"/"),n&&!n.scheme)return r&&(n.scheme=r.scheme),a(n);if(n||t.match(o))return t;if(r&&!r.host&&!r.path)return r.host=t,a(r);var l="/"===t.charAt(0)?t:s(e.replace(/\/+$/,"")+"/"+t);return r?(r.path=l,a(r)):l}n.urlParse=i,n.urlGenerate=a,n.normalize=s,n.join=l,n.isAbsolute=function(e){return"/"===e.charAt(0)||r.test(e)},n.relative=function(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");for(var n=0;0!==t.indexOf(e+"/");){var r=e.lastIndexOf("/");if(r<0)return t;if((e=e.slice(0,r)).match(/^([^\/]+:\/)?\/*$/))return t;++n}return Array(n+1).join("../")+t.substr(e.length+1)};var u=!("__proto__"in Object.create(null));function c(e){return e}function f(e){if(!e)return!1;var t=e.length;if(t<9)return!1;if(95!==e.charCodeAt(t-1)||95!==e.charCodeAt(t-2)||111!==e.charCodeAt(t-3)||116!==e.charCodeAt(t-4)||111!==e.charCodeAt(t-5)||114!==e.charCodeAt(t-6)||112!==e.charCodeAt(t-7)||95!==e.charCodeAt(t-8)||95!==e.charCodeAt(t-9))return!1;for(var n=t-10;n>=0;n--)if(36!==e.charCodeAt(n))return!1;return!0}function d(e,t){return e===t?0:null===e?1:null===t?-1:e>t?1:-1}n.toSetString=u?c:function(e){return f(e)?"$"+e:e},n.fromSetString=u?c:function(e){return f(e)?e.slice(1):e},n.compareByOriginalPositions=function(e,t,n){var r=d(e.source,t.source);return 0!==r||0!=(r=e.originalLine-t.originalLine)||0!=(r=e.originalColumn-t.originalColumn)||n||0!=(r=e.generatedColumn-t.generatedColumn)||0!=(r=e.generatedLine-t.generatedLine)?r:d(e.name,t.name)},n.compareByGeneratedPositionsDeflated=function(e,t,n){var r=e.generatedLine-t.generatedLine;return 0!==r||0!=(r=e.generatedColumn-t.generatedColumn)||n||0!==(r=d(e.source,t.source))||0!=(r=e.originalLine-t.originalLine)||0!=(r=e.originalColumn-t.originalColumn)?r:d(e.name,t.name)},n.compareByGeneratedPositionsInflated=function(e,t){var n=e.generatedLine-t.generatedLine;return 0!==n||0!=(n=e.generatedColumn-t.generatedColumn)||0!==(n=d(e.source,t.source))||0!=(n=e.originalLine-t.originalLine)||0!=(n=e.originalColumn-t.originalColumn)?n:d(e.name,t.name)},n.parseSourceMapInput=function(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))},n.computeSourceURL=function(e,t,n){if(t=t||"",e&&("/"!==e[e.length-1]&&"/"!==t[0]&&(e+="/"),t=e+t),n){var r=i(n);if(!r)throw new Error("sourceMapURL could not be parsed");if(r.path){var o=r.path.lastIndexOf("/");o>=0&&(r.path=r.path.substring(0,o+1))}t=l(a(r),t)}return s(t)}},{}],208:[function(e,t,n){n.SourceMapGenerator=e("./lib/source-map-generator").SourceMapGenerator,n.SourceMapConsumer=e("./lib/source-map-consumer").SourceMapConsumer,n.SourceNode=e("./lib/source-node").SourceNode},{"./lib/source-map-consumer":204,"./lib/source-map-generator":205,"./lib/source-node":206}],209:[function(e,t,n){var r=e("punycode"),o=e("./util");function i(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}n.parse=_,n.resolve=function(e,t){return _(e,!1,!0).resolve(t)},n.resolveObject=function(e,t){return e?_(e,!1,!0).resolveObject(t):t},n.format=function(e){return o.isString(e)&&(e=_(e)),e instanceof i?e.format():i.prototype.format.call(e)},n.Url=i;var a=/^([a-z0-9.+-]+:)/i,s=/:[0-9]*$/,l=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),f=["'"].concat(c),d=["%","/","?",";","#"].concat(f),p=["/","?","#"],h=/^[+a-z0-9A-Z_-]{0,63}$/,m=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,g={javascript:!0,"javascript:":!0},v={javascript:!0,"javascript:":!0},b={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},y=e("querystring");function _(e,t,n){if(e&&o.isObject(e)&&e instanceof i)return e;var r=new i;return r.parse(e,t,n),r}i.prototype.parse=function(e,t,n){if(!o.isString(e))throw new TypeError("Parameter 'url' must be a string, not "+u(e));var i=e.indexOf("?"),s=-1!==i&&i127?M+="x":M+=P[L];if(!M.match(h)){var R=q.slice(0,C),I=q.slice(C+1),F=P.match(m);F&&(R.push(F[1]),I.unshift(F[2])),I.length&&(_="/"+I.join(".")+_),this.hostname=R.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),A||(this.hostname=r.toASCII(this.hostname));var B=this.port?":"+this.port:"",U=this.hostname||"";this.host=U+B,this.href+=this.host,A&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==_[0]&&(_="/"+_))}if(!g[O])for(C=0,T=f.length;C0)&&n.host.split("@"))&&(n.auth=N.shift(),n.host=n.hostname=N.shift())),n.search=e.search,n.query=e.query,o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.href=n.format(),n;if(!O.length)return n.pathname=null,n.search?n.path="/"+n.search:n.path=null,n.href=n.format(),n;for(var S=O.slice(-1)[0],j=(n.host||e.host||O.length>1)&&("."===S||".."===S)||""===S,E=0,C=O.length;C>=0;C--)"."===(S=O[C])?O.splice(C,1):".."===S?(O.splice(C,1),E++):E&&(O.splice(C,1),E--);if(!w&&!x)for(;E--;E)O.unshift("..");!w||""===O[0]||O[0]&&"/"===O[0].charAt(0)||O.unshift(""),j&&"/"!==O.join("/").substr(-1)&&O.push("");var N,A=""===O[0]||O[0]&&"/"===O[0].charAt(0);return k&&(n.hostname=n.host=A?"":O.length?O.shift():"",(N=!!(n.host&&n.host.indexOf("@")>0)&&n.host.split("@"))&&(n.auth=N.shift(),n.host=n.hostname=N.shift())),(w=w||n.host&&O.length)&&!A&&O.unshift(""),O.length?n.pathname=O.join("/"):(n.pathname=null,n.path=null),o.isNull(n.pathname)&&o.isNull(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},i.prototype.parseHost=function(){var e=this.host,t=s.exec(e);t&&(":"!==(t=t[0])&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},{"./util":210,punycode:194,querystring:197}],210:[function(e,t,n){t.exports={isString:function(e){return"string"==typeof e},isObject:function(e){return"object"===u(e)&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},{}],211:[function(e,t,n){var r=e("htmlparser2"),o=e("lodash/escapeRegExp"),i=e("lodash/cloneDeep"),a=e("lodash/mergeWith"),l=e("lodash/isString"),u=e("lodash/isPlainObject"),c=e("parse-srcset"),f=e("postcss"),d=e("url"),p=["img","audio","video","picture","svg","object","map","iframe","embed"],h=["script","style"];function m(e,t){e&&Object.keys(e).forEach((function(n){t(e[n],n)}))}function g(e,t){return{}.hasOwnProperty.call(e,t)}function v(e,t){var n=[];return m(e,(function(e){t(e)&&n.push(e)})),n}t.exports=y;var b=/^[^\0\t\n\f\r /<=>]+$/;function y(e,t,n){var w="",x="";function O(e,t){var n=this;this.tag=e,this.attribs=t||{},this.tagPosition=w.length,this.text="",this.mediaChildren=[],this.updateParentNodeText=function(){A.length&&(A[A.length-1].text+=n.text)},this.updateParentNodeMediaChildren=function(){A.length&&p.indexOf(this.tag)>-1&&A[A.length-1].mediaChildren.push(this.tag)}}t?(t=Object.assign({},y.defaults,t)).parser?t.parser=Object.assign({},_,t.parser):t.parser=_:(t=y.defaults).parser=_,h.forEach((function(e){t.allowedTags&&t.allowedTags.indexOf(e)>-1&&!t.allowVulnerableTags&&console.warn("\n\nโš ๏ธ Your `allowedTags` option includes, `".concat(e,"`, which is inherently\nvulnerable to XSS attacks. Please remove it from `allowedTags`.\nOr, to disable this warning, add the `allowVulnerableTags` option\nand ensure you are accounting for this risk.\n\n"))}));var k,S,j=t.nonTextTags||["script","style","textarea","option"];t.allowedAttributes&&(k={},S={},m(t.allowedAttributes,(function(e,t){k[t]=[];var n=[];e.forEach((function(e){l(e)&&e.indexOf("*")>=0?n.push(o(e).replace(/\\\*/g,".*")):k[t].push(e)})),S[t]=new RegExp("^("+n.join("|")+")$")})));var E={};m(t.allowedClasses,(function(e,t){k&&(g(k,t)||(k[t]=[]),k[t].push("class")),E[t]=e}));var C,N,A,q,T,P,M,L={};m(t.transformTags,(function(e,t){var n;"function"==typeof e?n=e:"string"==typeof e&&(n=y.simpleTransform(e)),"*"===t?C=n:L[t]=n}));var D=!1;I();var R=new r.Parser({onopentag:function(e,n){if(t.enforceHtmlBoundary&&"html"===e&&I(),P)M++;else{var r=new O(e,n);A.push(r);var o,l=!1,p=!!r.text;if(g(L,e)&&(o=L[e](e,n),r.attribs=n=o.attribs,void 0!==o.text&&(r.innerText=o.text),e!==o.tagName&&(r.name=e=o.tagName,T[N]=o.tagName)),C&&(o=C(e,n),r.attribs=n=o.attribs,e!==o.tagName&&(r.name=e=o.tagName,T[N]=o.tagName)),(t.allowedTags&&-1===t.allowedTags.indexOf(e)||"recursiveEscape"===t.disallowedTagsMode&&!function(e){for(var t in e)if(g(e,t))return!1;return!0}(q))&&(l=!0,q[N]=!0,"discard"===t.disallowedTagsMode&&-1!==j.indexOf(e)&&(P=!0,M=1),q[N]=!0),N++,l){if("discard"===t.disallowedTagsMode)return;x=w,w=""}w+="<"+e,(!k||g(k,e)||k["*"])&&m(n,(function(n,o){if(b.test(o)){var l,p=!1;if(!k||g(k,e)&&-1!==k[e].indexOf(o)||k["*"]&&-1!==k["*"].indexOf(o)||g(S,e)&&S[e].test(o)||S["*"]&&S["*"].test(o))p=!0;else if(k&&k[e]){var h,y=s(k[e]);try{for(y.s();!(h=y.n()).done;){var _=h.value;if(u(_)&&_.name&&_.name===o){p=!0;var x="";if(!0===_.multiple){var O,j=s(n.split(" "));try{for(j.s();!(O=j.n()).done;){var C=O.value;-1!==_.values.indexOf(C)&&(""===x?x=C:x+=" "+C)}}catch(e){j.e(e)}finally{j.f()}}else _.values.indexOf(n)>=0&&(x=n);n=x}}}catch(e){y.e(e)}finally{y.f()}}if(p){if(-1!==t.allowedSchemesAppliedToAttributes.indexOf(o)&&B(e,n))return void delete r.attribs[o];if("iframe"===e&&"src"===o){var N=!0;try{if((l=d.parse(n,!1,!0))&&null===l.host&&null===l.protocol)N=g(t,"allowIframeRelativeUrls")?t.allowIframeRelativeUrls:!t.allowedIframeHostnames&&!t.allowedIframeDomains;else if(t.allowedIframeHostnames||t.allowedIframeDomains){var A=(t.allowedIframeHostnames||[]).find((function(e){return e===l.hostname})),q=(t.allowedIframeDomains||[]).find((function(e){return l.hostname===e||l.hostname.endsWith(".".concat(e))}));N=A||q}}catch(e){N=!1}if(!N)return void delete r.attribs[o]}if("srcset"===o)try{if(m(l=c(n),(function(e){B("srcset",e.url)&&(e.evil=!0)})),!(l=v(l,(function(e){return!e.evil}))).length)return void delete r.attribs[o];n=v(l,(function(e){return!e.evil})).map((function(e){if(!e.url)throw new Error("URL missing");return e.url+(e.w?" ".concat(e.w,"w"):"")+(e.h?" ".concat(e.h,"h"):"")+(e.d?" ".concat(e.d,"x"):"")})).join(", "),r.attribs[o]=n}catch(e){return void delete r.attribs[o]}if("class"===o&&!(n=function(e,t){return t?(e=e.split(/\s+/)).filter((function(e){return-1!==t.indexOf(e)})).join(" "):e}(n,E[e])).length)return void delete r.attribs[o];if("style"===o)try{if(0===(n=function(e){return e.nodes[0].nodes.reduce((function(e,t){return e.push(t.prop+":"+t.value),e}),[]).join(";")}(function(e,t){if(!t)return e;var n,r=i(e),o=e.nodes[0];return(n=t[o.selector]&&t["*"]?a(i(t[o.selector]),t["*"],(function(e,t){if(Array.isArray(e))return e.concat(t)})):t[o.selector]||t["*"])&&(r.nodes[0].nodes=o.nodes.reduce(function(e){return function(t,n){return g(e,n.prop)&&e[n.prop].some((function(e){return e.test(n.value)}))&&t.push(n),t}}(n),[])),r}(f.parse(e+" {"+n+"}"),t.allowedStyles))).length)return void delete r.attribs[o]}catch(e){return void delete r.attribs[o]}w+=" "+o,n&&n.length&&(w+='="'+F(n,!0)+'"')}else delete r.attribs[o]}else delete r.attribs[o]})),-1!==t.selfClosing.indexOf(e)?w+=" />":(w+=">",!r.innerText||p||t.textFilter||(w+=r.innerText,D=!0)),l&&(w=x+F(w),x="")}},ontext:function(e){if(!P){var n,r=A[A.length-1];if(r&&(n=r.tag,e=void 0!==r.innerText?r.innerText:e),"discard"!==t.disallowedTagsMode||"script"!==n&&"style"!==n){var o=F(e,!1);t.textFilter&&!D?w+=t.textFilter(o,n):D||(w+=o)}else w+=e;A.length&&(A[A.length-1].text+=e)}},onclosetag:function(e){if(P){if(--M)return;P=!1}var n=A.pop();if(n){P=!!t.enforceHtmlBoundary&&"html"===e,N--;var r=q[N];if(r){if(delete q[N],"discard"===t.disallowedTagsMode)return void n.updateParentNodeText();x=w,w=""}T[N]&&(e=T[N],delete T[N]),t.exclusiveFilter&&t.exclusiveFilter(n)?w=w.substr(0,n.tagPosition):(n.updateParentNodeMediaChildren(),n.updateParentNodeText(),-1===t.selfClosing.indexOf(e)?(w+="",r&&(w=x+F(w),x="")):r&&(w=x,x=""))}}},t.parser);return R.write(e),R.end(),w;function I(){w="",N=0,A=[],q={},T={},P=!1,M=0}function F(e,n){return"string"!=typeof e&&(e+=""),t.parser.decodeEntities&&(e=e.replace(/&/g,"&").replace(//g,">"),n&&(e=e.replace(/\"/g,"""))),e=e.replace(/&(?![a-zA-Z0-9#]{1,20};)/g,"&").replace(//g,">"),n&&(e=e.replace(/\"/g,""")),e}function B(e,n){var r=(n=(n=n.replace(/[\x00-\x20]+/g,"")).replace(/<\!\-\-.*?\-\-\>/g,"")).match(/^([a-zA-Z]+)\:/);if(!r)return!!n.match(/^[\/\\]{2}/)&&!t.allowProtocolRelative;var o=r[1].toLowerCase();return g(t.allowedSchemesByTag,e)?-1===t.allowedSchemesByTag[e].indexOf(o):!t.allowedSchemes||-1===t.allowedSchemes.indexOf(o)}}var _={decodeEntities:!0};y.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","abbr","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre","iframe"],disallowedTagsMode:"discard",allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{},allowedSchemesAppliedToAttributes:["href","src","cite"],allowProtocolRelative:!0,enforceHtmlBoundary:!1},y.simpleTransform=function(e,t,n){return n=void 0===n||n,t=t||{},function(r,o){var i;if(n)for(i in t)o[i]=t[i];else o=t;return{tagName:e,attribs:o}}}},{htmlparser2:31,"lodash/cloneDeep":140,"lodash/escapeRegExp":143,"lodash/isPlainObject":155,"lodash/isString":157,"lodash/mergeWith":162,"parse-srcset":167,postcss:181,url:209}]},{},[211])(211)},"object"===u(t)&&void 0!==e?e.exports=a():(o=[],void 0===(i="function"==typeof(r=a)?r.apply(t,o):r)||(e.exports=i))}).call(this,n(42))},function(e,t,n){"use strict";n.d(t,"b",(function(){return r})),n.d(t,"c",(function(){return o})),n.d(t,"d",(function(){return i})),n.d(t,"a",(function(){return a}));var r={allowedTags:["blockquote","caption","div","figcaption","figure","h1","h2","h3","h4","h5","h6","hr","li","ol","p","pre","section","table","tbody","td","th","thead","tr","ul","a","abbr","acronym","audio","b","bdi","bdo","big","br","button","canvas","cite","code","data","datalist","del","dfn","em","embed","i","iframe","img","input","ins","kbd","label","map","mark","meter","noscript","object","output","picture","progress","q","ruby","s","samp","select","slot","small","span","strong","sub","sup","svg","template","textarea","time","u","tt","var","video","wbr"],allowedAttributes:{"*":["class","id","data-*","style"],iframe:["*"],a:["href","name","target"],img:["src","srcset","sizes","alt","width","height"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{},allowProtocolRelative:!0},o={allowedTags:["a","abbr","acronym","audio","b","bdi","bdo","big","br","button","canvas","cite","code","data","datalist","del","dfn","em","embed","i","iframe","img","input","ins","kbd","label","map","mark","meter","noscript","object","output","picture","progress","q","ruby","s","samp","select","slot","small","span","strong","sub","sup","svg","template","textarea","time","u","tt","var","video","wbr"],allowedAttributes:{"*":["class","id","data-*","style"],a:["href","name","target"],img:["src","srcset","sizes","alt","width","height"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{},allowProtocolRelative:!0},i={allowedTags:["h1","h2","h3","h4","h5","h6","blockquote","p","ul","ol","nl","li","b","i","strong","em","strike","code","cite","hr","br","div","table","thead","caption","tbody","tr","th","td","pre","img","figure","figcaption","iframe","section"],allowedAttributes:{"*":["class","id","data-*","style"],iframe:["*"],img:["src","srcset","sizes","alt","width","height"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"]},a={allowedTags:[],allowedAttributes:{}}},function(e,t,n){"use strict";n.d(t,"a",(function(){return r})),n.d(t,"b",(function(){return o}));function r(e,t,n){var r="";return n.split(" ").forEach((function(n){void 0!==e[n]?t.push(e[n]+";"):r+=n+" "})),r}var o=function(e,t,n){var r=e.key+"-"+t.name;if(!1===n&&void 0===e.registered[r]&&(e.registered[r]=t.styles),void 0===e.inserted[t.name]){var o=t;do{e.insert(t===o?"."+r:"",o,e.sheet,!0);o=o.next}while(void 0!==o)}}},function(e,t){!function(){e.exports=this.wp.element}()},function(e,t,n){"use strict";n.d(t,"a",(function(){return m}));var r=function(e){for(var t,n=0,r=0,o=e.length;o>=4;++r,o-=4)t=1540483477*(65535&(t=255&e.charCodeAt(r)|(255&e.charCodeAt(++r))<<8|(255&e.charCodeAt(++r))<<16|(255&e.charCodeAt(++r))<<24))+(59797*(t>>>16)<<16),n=1540483477*(65535&(t^=t>>>24))+(59797*(t>>>16)<<16)^1540483477*(65535&n)+(59797*(n>>>16)<<16);switch(o){case 3:n^=(255&e.charCodeAt(r+2))<<16;case 2:n^=(255&e.charCodeAt(r+1))<<8;case 1:n=1540483477*(65535&(n^=255&e.charCodeAt(r)))+(59797*(n>>>16)<<16)}return(((n=1540483477*(65535&(n^=n>>>13))+(59797*(n>>>16)<<16))^n>>>15)>>>0).toString(36)},o={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},i=n(34),a=/[A-Z]|^ms/g,s=/_EMO_([^_]+?)_([^]*?)_EMO_/g,l=function(e){return 45===e.charCodeAt(1)},u=function(e){return null!=e&&"boolean"!=typeof e},c=Object(i.a)((function(e){return l(e)?e:e.replace(a,"-$&").toLowerCase()})),f=function(e,t){switch(e){case"animation":case"animationName":if("string"==typeof t)return t.replace(s,(function(e,t,n){return p={name:t,styles:n,next:p},t}))}return 1===o[e]||l(e)||"number"!=typeof t||0===t?t:t+"px"};function d(e,t,n){if(null==n)return"";if(void 0!==n.__emotion_styles)return n;switch(typeof n){case"boolean":return"";case"object":if(1===n.anim)return p={name:n.name,styles:n.styles,next:p},n.name;if(void 0!==n.styles){var r=n.next;if(void 0!==r)for(;void 0!==r;)p={name:r.name,styles:r.styles,next:p},r=r.next;return n.styles+";"}return function(e,t,n){var r="";if(Array.isArray(n))for(var o=0;oe.length)&&(t=e.length);for(var n=0,r=new Array(t);n0,m=c-d-u,g=!1;m>t&&s.current&&(r&&r(e),s.current=!1),h&&l.current&&(a&&a(e),l.current=!1),h&&t>m?(n&&!s.current&&n(e),p.scrollTop=c,g=!0,s.current=!0):!h&&-t>u&&(i&&!l.current&&i(e),p.scrollTop=0,g=!0,l.current=!0),g&&function(e){e.preventDefault(),e.stopPropagation()}(e)}}),[]),p=Object(c.useCallback)((function(e){d(e,e.deltaY)}),[d]),h=Object(c.useCallback)((function(e){u.current=e.changedTouches[0].clientY}),[]),m=Object(c.useCallback)((function(e){var t=u.current-e.changedTouches[0].clientY;d(e,t)}),[d]),g=Object(c.useCallback)((function(e){if(e){var t=!!o.B&&{passive:!1};"function"==typeof e.addEventListener&&e.addEventListener("wheel",p,t),"function"==typeof e.addEventListener&&e.addEventListener("touchstart",h,t),"function"==typeof e.addEventListener&&e.addEventListener("touchmove",m,t)}}),[m,h,p]),v=Object(c.useCallback)((function(e){e&&("function"==typeof e.removeEventListener&&e.removeEventListener("wheel",p,!1),"function"==typeof e.removeEventListener&&e.removeEventListener("touchstart",h,!1),"function"==typeof e.removeEventListener&&e.removeEventListener("touchmove",m,!1))}),[m,h,p]);return Object(c.useEffect)((function(){if(t){var e=f.current;return g(e),function(){v(e)}}}),[t,g,v]),function(e){f.current=e}}({isEnabled:void 0===r||r,onBottomArrive:e.onBottomArrive,onBottomLeave:e.onBottomLeave,onTopArrive:e.onTopArrive,onTopLeave:e.onTopLeave}),a=function(e){var t=e.isEnabled,n=e.accountForScrollbars,r=void 0===n||n,o=Object(c.useRef)({}),i=Object(c.useRef)(null),a=Object(c.useCallback)((function(e){if(D){var t=document.body,n=t&&t.style;if(r&&A.forEach((function(e){var t=n&&n[e];o.current[e]=t})),r&&R<1){var i=parseInt(o.current.paddingRight,10)||0,a=document.body?document.body.clientWidth:0,s=window.innerWidth-a+i||0;Object.keys(q).forEach((function(e){var t=q[e];n&&(n[e]=t)})),n&&(n.paddingRight="".concat(s,"px"))}t&&L()&&(t.addEventListener("touchmove",T,I),e&&(e.addEventListener("touchstart",M,I),e.addEventListener("touchmove",P,I))),R+=1}}),[]),s=Object(c.useCallback)((function(e){if(D){var t=document.body,n=t&&t.style;R=Math.max(R-1,0),r&&R<1&&A.forEach((function(e){var t=o.current[e];n&&(n[e]=t)})),t&&L()&&(t.removeEventListener("touchmove",T,I),e&&(e.removeEventListener("touchstart",M,I),e.removeEventListener("touchmove",P,I)))}}),[]);return Object(c.useEffect)((function(){if(t){var e=i.current;return a(e),function(){s(e)}}}),[t,a,s]),function(e){i.current=e}}({isEnabled:n});return Object(d.c)(f.a.Fragment,null,n&&Object(d.c)("div",{onClick:F,css:B}),t((function(e){i(e),a(e)})))}var V={clearIndicator:o.l,container:o.m,control:o.n,dropdownIndicator:o.o,group:o.p,groupHeading:o.q,indicatorsContainer:o.r,indicatorSeparator:o.s,input:o.t,loadingIndicator:o.u,loadingMessage:o.v,menu:o.w,menuList:o.x,menuPortal:o.y,multiValue:o.z,multiValueLabel:o.A,multiValueRemove:o.C,noOptionsMessage:o.D,option:o.E,placeholder:o.F,singleValue:o.G,valueContainer:o.H};var z,H={borderRadius:4,colors:{primary:"#2684FF",primary75:"#4C9AFF",primary50:"#B2D4FF",primary25:"#DEEBFF",danger:"#DE350B",dangerLight:"#FFBDAD",neutral0:"hsl(0, 0%, 100%)",neutral5:"hsl(0, 0%, 95%)",neutral10:"hsl(0, 0%, 90%)",neutral20:"hsl(0, 0%, 80%)",neutral30:"hsl(0, 0%, 70%)",neutral40:"hsl(0, 0%, 60%)",neutral50:"hsl(0, 0%, 50%)",neutral60:"hsl(0, 0%, 40%)",neutral70:"hsl(0, 0%, 30%)",neutral80:"hsl(0, 0%, 20%)",neutral90:"hsl(0, 0%, 10%)"},spacing:{baseUnit:4,controlHeight:38,menuGutter:8}},W={"aria-live":"polite",backspaceRemovesValue:!0,blurInputOnSelect:Object(o.I)(),captureMenuScroll:!Object(o.I)(),closeMenuOnSelect:!0,closeMenuOnScroll:!1,components:{},controlShouldRenderValue:!0,escapeClearsValue:!1,filterOption:function(e,t){var n=Object(o.k)({ignoreCase:!0,ignoreAccents:!0,stringify:C,trim:!0,matchFrom:"any"},z),r=n.ignoreCase,i=n.ignoreAccents,a=n.stringify,s=n.trim,l=n.matchFrom,u=s?E(t):t,c=s?E(a(e)):a(e);return r&&(u=u.toLowerCase(),c=c.toLowerCase()),i&&(u=j(u),c=S(c)),"start"===l?c.substr(0,u.length)===u:c.indexOf(u)>-1},formatGroupLabel:function(e){return e.label},getOptionLabel:function(e){return e.label},getOptionValue:function(e){return e.value},isDisabled:!1,isLoading:!1,isMulti:!1,isRtl:!1,isSearchable:!0,isOptionDisabled:function(e){return!!e.isDisabled},loadingMessage:function(){return"Loading..."},maxMenuHeight:300,minMenuHeight:140,menuIsOpen:!1,menuPlacement:"bottom",menuPosition:"absolute",menuShouldBlockScroll:!1,menuShouldScrollIntoView:!Object(o.a)(),noOptionsMessage:function(){return"No options"},openMenuOnFocus:!1,openMenuOnClick:!0,options:[],pageSize:5,placeholder:"Select...",screenReaderStatus:function(e){var t=e.count;return"".concat(t," result").concat(1!==t?"s":""," available")},styles:{},tabIndex:"0",tabSelectsValue:!0};function G(e,t,n,r){return{type:"option",data:t,isDisabled:J(e,t,n),isSelected:Q(e,t,n),label:X(e,t),value:Z(e,t),index:r}}function K(e,t){return e.options.map((function(n,r){if(n.options){var o=n.options.map((function(n,r){return G(e,n,t,r)})).filter((function(t){return Y(e,t)}));return o.length>0?{type:"group",data:n,options:o,index:r}:void 0}var i=G(e,n,t,r);return Y(e,i)?i:void 0})).filter((function(e){return!!e}))}function $(e){return e.reduce((function(e,t){return"group"===t.type?e.push.apply(e,u(t.options.map((function(e){return e.data})))):e.push(t.data),e}),[])}function Y(e,t){var n=e.inputValue,r=void 0===n?"":n,o=t.data,i=t.isSelected,a=t.label,s=t.value;return(!te(e)||!i)&&ee(e,{label:a,value:s,data:o},r)}var X=function(e,t){return e.getOptionLabel(t)},Z=function(e,t){return e.getOptionValue(t)};function J(e,t,n){return"function"==typeof e.isOptionDisabled&&e.isOptionDisabled(t,n)}function Q(e,t,n){if(n.indexOf(t)>-1)return!0;if("function"==typeof e.isOptionSelected)return e.isOptionSelected(t,n);var r=Z(e,t);return n.some((function(t){return Z(e,t)===r}))}function ee(e,t,n){return!e.filterOption||e.filterOption(t,n)}var te=function(e){var t=e.hideSelectedOptions,n=e.isMulti;return void 0===t?n:t},ne=1,re=function(e){Object(s.a)(n,e);var t=Object(o.j)(n);function n(e){var r;return Object(i.a)(this,n),(r=t.call(this,e)).state={ariaSelection:null,focusedOption:null,focusedValue:null,inputIsHidden:!1,isFocused:!1,selectValue:[],clearFocusValueOnUpdate:!1,inputIsHiddenAfterUpdate:void 0,prevProps:void 0},r.blockOptionHover=!1,r.isComposing=!1,r.commonProps=void 0,r.initialTouchX=0,r.initialTouchY=0,r.instancePrefix="",r.openAfterFocus=!1,r.scrollToFocusedOptionOnUpdate=!1,r.userIsDragging=void 0,r.controlRef=null,r.getControlRef=function(e){r.controlRef=e},r.focusedOptionRef=null,r.getFocusedOptionRef=function(e){r.focusedOptionRef=e},r.menuListRef=null,r.getMenuListRef=function(e){r.menuListRef=e},r.inputRef=null,r.getInputRef=function(e){r.inputRef=e},r.focus=r.focusInput,r.blur=r.blurInput,r.onChange=function(e,t){var n=r.props,o=n.onChange,i=n.name;t.name=i,r.ariaOnChange(e,t),o(e,t)},r.setValue=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"set-value",n=arguments.length>2?arguments[2]:void 0,o=r.props,i=o.closeMenuOnSelect,a=o.isMulti;r.onInputChange("",{action:"set-value"}),i&&(r.setState({inputIsHiddenAfterUpdate:!a}),r.onMenuClose()),r.setState({clearFocusValueOnUpdate:!0}),r.onChange(e,{action:t,option:n})},r.selectOption=function(e){var t=r.props,n=t.blurInputOnSelect,o=t.isMulti,i=t.name,a=r.state.selectValue,s=o&&r.isOptionSelected(e,a),l=r.isOptionDisabled(e,a);if(s){var c=r.getOptionValue(e);r.setValue(a.filter((function(e){return r.getOptionValue(e)!==c})),"deselect-option",e)}else{if(l)return void r.ariaOnChange(e,{action:"select-option",name:i});o?r.setValue([].concat(u(a),[e]),"select-option",e):r.setValue(e,"select-option")}n&&r.blurInput()},r.removeValue=function(e){var t=r.props.isMulti,n=r.state.selectValue,o=r.getOptionValue(e),i=n.filter((function(e){return r.getOptionValue(e)!==o})),a=t?i:i[0]||null;r.onChange(a,{action:"remove-value",removedValue:e}),r.focusInput()},r.clearValue=function(){var e=r.state.selectValue;r.onChange(r.props.isMulti?[]:null,{action:"clear",removedValues:e})},r.popValue=function(){var e=r.props.isMulti,t=r.state.selectValue,n=t[t.length-1],o=t.slice(0,t.length-1),i=e?o:o[0]||null;r.onChange(i,{action:"pop-value",removedValue:n})},r.getValue=function(){return r.state.selectValue},r.cx=function(){for(var e=arguments.length,t=new Array(e),n=0;n5||i>5}},r.onTouchEnd=function(e){r.userIsDragging||(r.controlRef&&!r.controlRef.contains(e.target)&&r.menuListRef&&!r.menuListRef.contains(e.target)&&r.blurInput(),r.initialTouchX=0,r.initialTouchY=0)},r.onControlTouchEnd=function(e){r.userIsDragging||r.onControlMouseDown(e)},r.onClearIndicatorTouchEnd=function(e){r.userIsDragging||r.onClearIndicatorMouseDown(e)},r.onDropdownIndicatorTouchEnd=function(e){r.userIsDragging||r.onDropdownIndicatorMouseDown(e)},r.handleInputChange=function(e){var t=e.currentTarget.value;r.setState({inputIsHiddenAfterUpdate:!1}),r.onInputChange(t,{action:"input-change"}),r.props.menuIsOpen||r.onMenuOpen()},r.onInputFocus=function(e){r.props.onFocus&&r.props.onFocus(e),r.setState({inputIsHiddenAfterUpdate:!1,isFocused:!0}),(r.openAfterFocus||r.props.openMenuOnFocus)&&r.openMenu("first"),r.openAfterFocus=!1},r.onInputBlur=function(e){r.menuListRef&&r.menuListRef.contains(document.activeElement)?r.inputRef.focus():(r.props.onBlur&&r.props.onBlur(e),r.onInputChange("",{action:"input-blur"}),r.onMenuClose(),r.setState({focusedValue:null,isFocused:!1}))},r.onOptionHover=function(e){r.blockOptionHover||r.state.focusedOption===e||r.setState({focusedOption:e})},r.shouldHideSelectedOptions=function(){return te(r.props)},r.onKeyDown=function(e){var t=r.props,n=t.isMulti,o=t.backspaceRemovesValue,i=t.escapeClearsValue,a=t.inputValue,s=t.isClearable,l=t.isDisabled,u=t.menuIsOpen,c=t.onKeyDown,f=t.tabSelectsValue,d=t.openMenuOnFocus,p=r.state,h=p.focusedOption,m=p.focusedValue,g=p.selectValue;if(!(l||"function"==typeof c&&(c(e),e.defaultPrevented))){switch(r.blockOptionHover=!0,e.key){case"ArrowLeft":if(!n||a)return;r.focusValue("previous");break;case"ArrowRight":if(!n||a)return;r.focusValue("next");break;case"Delete":case"Backspace":if(a)return;if(m)r.removeValue(m);else{if(!o)return;n?r.popValue():s&&r.clearValue()}break;case"Tab":if(r.isComposing)return;if(e.shiftKey||!u||!f||!h||d&&r.isOptionSelected(h,g))return;r.selectOption(h);break;case"Enter":if(229===e.keyCode)break;if(u){if(!h)return;if(r.isComposing)return;r.selectOption(h);break}return;case"Escape":u?(r.setState({inputIsHiddenAfterUpdate:!1}),r.onInputChange("",{action:"menu-close"}),r.onMenuClose()):s&&i&&r.clearValue();break;case" ":if(a)return;if(!u){r.openMenu("first");break}if(!h)return;r.selectOption(h);break;case"ArrowUp":u?r.focusOption("up"):r.openMenu("last");break;case"ArrowDown":u?r.focusOption("down"):r.openMenu("first");break;case"PageUp":if(!u)return;r.focusOption("pageup");break;case"PageDown":if(!u)return;r.focusOption("pagedown");break;case"Home":if(!u)return;r.focusOption("first");break;case"End":if(!u)return;r.focusOption("last");break;default:return}e.preventDefault()}},r.instancePrefix="react-select-"+(r.props.instanceId||++ne),r.state.selectValue=Object(o.e)(e.value),r}return Object(a.a)(n,[{key:"componentDidMount",value:function(){this.startListeningComposition(),this.startListeningToTouch(),this.props.closeMenuOnScroll&&document&&document.addEventListener&&document.addEventListener("scroll",this.onScroll,!0),this.props.autoFocus&&this.focusInput()}},{key:"componentDidUpdate",value:function(e){var t=this.props,n=t.isDisabled,r=t.menuIsOpen,i=this.state.isFocused;(i&&!n&&e.isDisabled||i&&r&&!e.menuIsOpen)&&this.focusInput(),i&&n&&!e.isDisabled&&this.setState({isFocused:!1},this.onMenuClose),this.menuListRef&&this.focusedOptionRef&&this.scrollToFocusedOptionOnUpdate&&(Object(o.f)(this.menuListRef,this.focusedOptionRef),this.scrollToFocusedOptionOnUpdate=!1)}},{key:"componentWillUnmount",value:function(){this.stopListeningComposition(),this.stopListeningToTouch(),document.removeEventListener("scroll",this.onScroll,!0)}},{key:"onMenuOpen",value:function(){this.props.onMenuOpen()}},{key:"onMenuClose",value:function(){this.onInputChange("",{action:"menu-close"}),this.props.onMenuClose()}},{key:"onInputChange",value:function(e,t){this.props.onInputChange(e,t)}},{key:"focusInput",value:function(){this.inputRef&&this.inputRef.focus()}},{key:"blurInput",value:function(){this.inputRef&&this.inputRef.blur()}},{key:"openMenu",value:function(e){var t=this,n=this.state,r=n.selectValue,o=n.isFocused,i=this.buildFocusableOptions(),a="first"===e?0:i.length-1;if(!this.props.isMulti){var s=i.indexOf(r[0]);s>-1&&(a=s)}this.scrollToFocusedOptionOnUpdate=!(o&&this.menuListRef),this.setState({inputIsHiddenAfterUpdate:!1,focusedValue:null,focusedOption:i[a]},(function(){return t.onMenuOpen()}))}},{key:"focusValue",value:function(e){var t=this.state,n=t.selectValue,r=t.focusedValue;if(this.props.isMulti){this.setState({focusedOption:null});var o=n.indexOf(r);r||(o=-1);var i=n.length-1,a=-1;if(n.length){switch(e){case"previous":a=0===o?0:-1===o?i:o-1;break;case"next":o>-1&&o0&&void 0!==arguments[0]?arguments[0]:"first",t=this.props.pageSize,n=this.state.focusedOption,r=this.getFocusableOptions();if(r.length){var o=0,i=r.indexOf(n);n||(i=-1),"up"===e?o=i>0?i-1:r.length-1:"down"===e?o=(i+1)%r.length:"pageup"===e?(o=i-t)<0&&(o=0):"pagedown"===e?(o=i+t)>r.length-1&&(o=r.length-1):"last"===e&&(o=r.length-1),this.scrollToFocusedOptionOnUpdate=!0,this.setState({focusedOption:r[o],focusedValue:null})}}},{key:"getTheme",value:function(){return this.props.theme?"function"==typeof this.props.theme?this.props.theme(H):Object(o.k)(Object(o.k)({},H),this.props.theme):H}},{key:"getCommonProps",value:function(){var e=this.clearValue,t=this.cx,n=this.getStyles,r=this.getValue,o=this.selectOption,i=this.setValue,a=this.props,s=a.isMulti,l=a.isRtl,u=a.options;return{clearValue:e,cx:t,getStyles:n,getValue:r,hasValue:this.hasValue(),isMulti:s,isRtl:l,options:u,selectOption:o,selectProps:a,setValue:i,theme:this.getTheme()}}},{key:"hasValue",value:function(){return this.state.selectValue.length>0}},{key:"hasOptions",value:function(){return!!this.getFocusableOptions().length}},{key:"isClearable",value:function(){var e=this.props,t=e.isClearable,n=e.isMulti;return void 0===t?n:t}},{key:"isOptionDisabled",value:function(e,t){return J(this.props,e,t)}},{key:"isOptionSelected",value:function(e,t){return Q(this.props,e,t)}},{key:"filterOption",value:function(e,t){return ee(this.props,e,t)}},{key:"formatOptionLabel",value:function(e,t){if("function"==typeof this.props.formatOptionLabel){var n=this.props.inputValue,r=this.state.selectValue;return this.props.formatOptionLabel(e,{context:t,inputValue:n,selectValue:r})}return this.getOptionLabel(e)}},{key:"formatGroupLabel",value:function(e){return this.props.formatGroupLabel(e)}},{key:"startListeningComposition",value:function(){document&&document.addEventListener&&(document.addEventListener("compositionstart",this.onCompositionStart,!1),document.addEventListener("compositionend",this.onCompositionEnd,!1))}},{key:"stopListeningComposition",value:function(){document&&document.removeEventListener&&(document.removeEventListener("compositionstart",this.onCompositionStart),document.removeEventListener("compositionend",this.onCompositionEnd))}},{key:"startListeningToTouch",value:function(){document&&document.addEventListener&&(document.addEventListener("touchstart",this.onTouchStart,!1),document.addEventListener("touchmove",this.onTouchMove,!1),document.addEventListener("touchend",this.onTouchEnd,!1))}},{key:"stopListeningToTouch",value:function(){document&&document.removeEventListener&&(document.removeEventListener("touchstart",this.onTouchStart),document.removeEventListener("touchmove",this.onTouchMove),document.removeEventListener("touchend",this.onTouchEnd))}},{key:"renderInput",value:function(){var e=this.props,t=e.isDisabled,n=e.isSearchable,i=e.inputId,a=e.inputValue,s=e.tabIndex,l=e.form,u=this.getComponents().Input,c=this.state.inputIsHidden,d=this.commonProps,p=i||this.getElementId("input"),h={"aria-autocomplete":"list","aria-label":this.props["aria-label"],"aria-labelledby":this.props["aria-labelledby"]};return n?f.a.createElement(u,Object(r.a)({},d,{autoCapitalize:"none",autoComplete:"off",autoCorrect:"off",id:p,innerRef:this.getInputRef,isDisabled:t,isHidden:c,onBlur:this.onInputBlur,onChange:this.handleInputChange,onFocus:this.onInputFocus,spellCheck:"false",tabIndex:s,form:l,type:"text",value:a},h)):f.a.createElement(N,Object(r.a)({id:p,innerRef:this.getInputRef,onBlur:this.onInputBlur,onChange:o.g,onFocus:this.onInputFocus,readOnly:!0,disabled:t,tabIndex:s,form:l,value:""},h))}},{key:"renderPlaceholderOrValue",value:function(){var e=this,t=this.getComponents(),n=t.MultiValue,o=t.MultiValueContainer,i=t.MultiValueLabel,a=t.MultiValueRemove,s=t.SingleValue,l=t.Placeholder,u=this.commonProps,c=this.props,d=c.controlShouldRenderValue,p=c.isDisabled,h=c.isMulti,m=c.inputValue,g=c.placeholder,v=this.state,b=v.selectValue,y=v.focusedValue,_=v.isFocused;if(!this.hasValue()||!d)return m?null:f.a.createElement(l,Object(r.a)({},u,{key:"placeholder",isDisabled:p,isFocused:_}),g);if(h)return b.map((function(t,s){var l=t===y;return f.a.createElement(n,Object(r.a)({},u,{components:{Container:o,Label:i,Remove:a},isFocused:l,isDisabled:p,key:"".concat(e.getOptionValue(t)).concat(s),index:s,removeProps:{onClick:function(){return e.removeValue(t)},onTouchEnd:function(){return e.removeValue(t)},onMouseDown:function(e){e.preventDefault(),e.stopPropagation()}},data:t}),e.formatOptionLabel(t,"value"))}));if(m)return null;var w=b[0];return f.a.createElement(s,Object(r.a)({},u,{data:w,isDisabled:p}),this.formatOptionLabel(w,"value"))}},{key:"renderClearIndicator",value:function(){var e=this.getComponents().ClearIndicator,t=this.commonProps,n=this.props,o=n.isDisabled,i=n.isLoading,a=this.state.isFocused;if(!this.isClearable()||!e||o||!this.hasValue()||i)return null;var s={onMouseDown:this.onClearIndicatorMouseDown,onTouchEnd:this.onClearIndicatorTouchEnd,"aria-hidden":"true"};return f.a.createElement(e,Object(r.a)({},t,{innerProps:s,isFocused:a}))}},{key:"renderLoadingIndicator",value:function(){var e=this.getComponents().LoadingIndicator,t=this.commonProps,n=this.props,o=n.isDisabled,i=n.isLoading,a=this.state.isFocused;if(!e||!i)return null;return f.a.createElement(e,Object(r.a)({},t,{innerProps:{"aria-hidden":"true"},isDisabled:o,isFocused:a}))}},{key:"renderIndicatorSeparator",value:function(){var e=this.getComponents(),t=e.DropdownIndicator,n=e.IndicatorSeparator;if(!t||!n)return null;var o=this.commonProps,i=this.props.isDisabled,a=this.state.isFocused;return f.a.createElement(n,Object(r.a)({},o,{isDisabled:i,isFocused:a}))}},{key:"renderDropdownIndicator",value:function(){var e=this.getComponents().DropdownIndicator;if(!e)return null;var t=this.commonProps,n=this.props.isDisabled,o=this.state.isFocused,i={onMouseDown:this.onDropdownIndicatorMouseDown,onTouchEnd:this.onDropdownIndicatorTouchEnd,"aria-hidden":"true"};return f.a.createElement(e,Object(r.a)({},t,{innerProps:i,isDisabled:n,isFocused:o}))}},{key:"renderMenu",value:function(){var e=this,t=this.getComponents(),n=t.Group,i=t.GroupHeading,a=t.Menu,s=t.MenuList,l=t.MenuPortal,u=t.LoadingMessage,c=t.NoOptionsMessage,d=t.Option,p=this.commonProps,h=this.state.focusedOption,m=this.props,g=m.captureMenuScroll,v=m.inputValue,b=m.isLoading,y=m.loadingMessage,_=m.minMenuHeight,w=m.maxMenuHeight,x=m.menuIsOpen,O=m.menuPlacement,k=m.menuPosition,S=m.menuPortalTarget,j=m.menuShouldBlockScroll,E=m.menuShouldScrollIntoView,C=m.noOptionsMessage,N=m.onMenuScrollToTop,A=m.onMenuScrollToBottom;if(!x)return null;var q,T=function(t,n){var o=t.type,i=t.data,a=t.isDisabled,s=t.isSelected,l=t.label,u=t.value,c=h===i,m=a?void 0:function(){return e.onOptionHover(i)},g=a?void 0:function(){return e.selectOption(i)},v="".concat(e.getElementId("option"),"-").concat(n),b={id:v,onClick:g,onMouseMove:m,onMouseOver:m,tabIndex:-1};return f.a.createElement(d,Object(r.a)({},p,{innerProps:b,data:i,isDisabled:a,isSelected:s,key:v,label:l,type:o,value:u,isFocused:c,innerRef:c?e.getFocusedOptionRef:void 0}),e.formatOptionLabel(t.data,"menu"))};if(this.hasOptions())q=this.getCategorizedOptions().map((function(t){if("group"===t.type){var o=t.data,a=t.options,s=t.index,l="".concat(e.getElementId("group"),"-").concat(s),u="".concat(l,"-heading");return f.a.createElement(n,Object(r.a)({},p,{key:l,data:o,options:a,Heading:i,headingProps:{id:u,data:t.data},label:e.formatGroupLabel(t.data)}),t.options.map((function(e){return T(e,"".concat(s,"-").concat(e.index))})))}if("option"===t.type)return T(t,"".concat(t.index))}));else if(b){var P=y({inputValue:v});if(null===P)return null;q=f.a.createElement(u,p,P)}else{var M=C({inputValue:v});if(null===M)return null;q=f.a.createElement(c,p,M)}var L={minMenuHeight:_,maxMenuHeight:w,menuPlacement:O,menuPosition:k,menuShouldScrollIntoView:E},D=f.a.createElement(o.i,Object(r.a)({},p,L),(function(t){var n=t.ref,o=t.placerProps,i=o.placement,l=o.maxHeight;return f.a.createElement(a,Object(r.a)({},p,L,{innerRef:n,innerProps:{onMouseDown:e.onMenuMouseDown,onMouseMove:e.onMenuMouseMove},isLoading:b,placement:i}),f.a.createElement(U,{captureEnabled:g,onTopArrive:N,onBottomArrive:A,lockEnabled:j},(function(t){return f.a.createElement(s,Object(r.a)({},p,{innerRef:function(n){e.getMenuListRef(n),t(n)},isLoading:b,maxHeight:l,focusedOption:h}),q)})))}));return S||"fixed"===k?f.a.createElement(l,Object(r.a)({},p,{appendTo:S,controlElement:this.controlRef,menuPlacement:O,menuPosition:k}),D):D}},{key:"renderFormField",value:function(){var e=this,t=this.props,n=t.delimiter,r=t.isDisabled,o=t.isMulti,i=t.name,a=this.state.selectValue;if(i&&!r){if(o){if(n){var s=a.map((function(t){return e.getOptionValue(t)})).join(n);return f.a.createElement("input",{name:i,type:"hidden",value:s})}var l=a.length>0?a.map((function(t,n){return f.a.createElement("input",{key:"i-".concat(n),name:i,type:"hidden",value:e.getOptionValue(t)})})):f.a.createElement("input",{name:i,type:"hidden"});return f.a.createElement("div",null,l)}var u=a[0]?this.getOptionValue(a[0]):"";return f.a.createElement("input",{name:i,type:"hidden",value:u})}}},{key:"renderLiveRegion",value:function(){var e=this.commonProps,t=this.state,n=t.ariaSelection,o=t.focusedOption,i=t.focusedValue,a=t.isFocused,s=t.selectValue,l=this.getFocusableOptions();return f.a.createElement(b,Object(r.a)({},e,{ariaSelection:n,focusedOption:o,focusedValue:i,isFocused:a,selectValue:s,focusableOptions:l}))}},{key:"render",value:function(){var e=this.getComponents(),t=e.Control,n=e.IndicatorsContainer,o=e.SelectContainer,i=e.ValueContainer,a=this.props,s=a.className,l=a.id,u=a.isDisabled,c=a.menuIsOpen,d=this.state.isFocused,p=this.commonProps=this.getCommonProps();return f.a.createElement(o,Object(r.a)({},p,{className:s,innerProps:{id:l,onKeyDown:this.onKeyDown},isDisabled:u,isFocused:d}),this.renderLiveRegion(),f.a.createElement(t,Object(r.a)({},p,{innerRef:this.getControlRef,innerProps:{onMouseDown:this.onControlMouseDown,onTouchEnd:this.onControlTouchEnd},isDisabled:u,isFocused:d,menuIsOpen:c}),f.a.createElement(i,Object(r.a)({},p,{isDisabled:u}),this.renderPlaceholderOrValue(),this.renderInput()),f.a.createElement(n,Object(r.a)({},p,{isDisabled:u}),this.renderClearIndicator(),this.renderLoadingIndicator(),this.renderIndicatorSeparator(),this.renderDropdownIndicator())),this.renderMenu(),this.renderFormField())}}],[{key:"getDerivedStateFromProps",value:function(e,t){var n=t.prevProps,r=t.clearFocusValueOnUpdate,i=t.inputIsHiddenAfterUpdate,a=e.options,s=e.value,l=e.menuIsOpen,u=e.inputValue,c={};if(n&&(s!==n.value||a!==n.options||l!==n.menuIsOpen||u!==n.inputValue)){var f=Object(o.e)(s),d=l?function(e,t){return $(K(e,t))}(e,f):[],p=r?function(e,t){var n=e.focusedValue,r=e.selectValue.indexOf(n);if(r>-1){if(t.indexOf(n)>-1)return n;if(r-1?n:t[0]}(t,d),focusedValue:p,clearFocusValueOnUpdate:!1}}var h=null!=i&&e!==n?{inputIsHidden:i,inputIsHiddenAfterUpdate:void 0}:{};return Object(o.k)(Object(o.k)(Object(o.k)({},c),h),{},{prevProps:e})}}]),n}(c.Component);re.defaultProps=W},function(e,t,n){"use strict";n.d(t,"a",(function(){return r}));var r=function(){function e(e){var t=this;this._insertTag=function(e){var n;n=0===t.tags.length?t.prepend?t.container.firstChild:t.before:t.tags[t.tags.length-1].nextSibling,t.container.insertBefore(e,n),t.tags.push(e)},this.isSpeedy=void 0===e.speedy||e.speedy,this.tags=[],this.ctr=0,this.nonce=e.nonce,this.key=e.key,this.container=e.container,this.prepend=e.prepend,this.before=null}var t=e.prototype;return t.hydrate=function(e){e.forEach(this._insertTag)},t.insert=function(e){this.ctr%(this.isSpeedy?65e3:1)==0&&this._insertTag(function(e){var t=document.createElement("style");return t.setAttribute("data-emotion",e.key),void 0!==e.nonce&&t.setAttribute("nonce",e.nonce),t.appendChild(document.createTextNode("")),t.setAttribute("data-s",""),t}(this));var t=this.tags[this.tags.length-1];if(this.isSpeedy){var n=function(e){if(e.sheet)return e.sheet;for(var t=0;t2),g=/Android/.test(e),v=m||g||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(e),b=m||/Mac/.test(t),y=/\bCrOS\b/.test(e),_=/win/i.test(t),w=f&&e.match(/Version\/(\d*\.\d*)/);w&&(w=Number(w[1])),w&&w>=15&&(f=!1,l=!0);var x=b&&(u||f&&(null==w||w<12.11)),O=n||a&&s>=9;function k(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var S,j=function(e,t){var n=e.className,r=k(t).exec(n);if(r){var o=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(o?r[1]+o:"")}};function E(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function C(e,t){return E(e).appendChild(t)}function N(e,t,n,r){var o=document.createElement(e);if(n&&(o.className=n),r&&(o.style.cssText=r),"string"==typeof t)o.appendChild(document.createTextNode(t));else if(t)for(var i=0;i=t)return a+(t-i);a+=s-i,a+=n-a%n,i=s+1}}m?L=function(e){e.selectionStart=0,e.selectionEnd=e.value.length}:a&&(L=function(e){try{e.select()}catch(e){}});var F=function(){this.id=null,this.f=null,this.time=0,this.handler=D(this.onTimeout,this)};function B(e,t){for(var n=0;n=t)return r+Math.min(a,t-o);if(o+=i-r,r=i+1,(o+=n-o%n)>=t)return r}}var G=[""];function K(e){for(;G.length<=e;)G.push($(G)+" ");return G[e]}function $(e){return e[e.length-1]}function Y(e,t){for(var n=[],r=0;r"ย€"&&(e.toUpperCase()!=e.toLowerCase()||J.test(e))}function ee(e,t){return t?!!(t.source.indexOf("\\w")>-1&&Q(e))||t.test(e):Q(e)}function te(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var ne=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function re(e){return e.charCodeAt(0)>=768&&ne.test(e)}function oe(e,t,n){for(;(n<0?t>0:tn?-1:1;;){if(t==n)return t;var o=(t+n)/2,i=r<0?Math.ceil(o):Math.floor(o);if(i==t)return e(i)?t:n;e(i)?n=i:t=i+r}}var ae=null;function se(e,t,n){var r;ae=null;for(var o=0;ot)return o;i.to==t&&(i.from!=i.to&&"before"==n?r=o:ae=o),i.from==t&&(i.from!=i.to&&"before"!=n?r=o:ae=o)}return null!=r?r:ae}var le=function(){var e=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,t=/[stwN]/,n=/[LRr]/,r=/[Lb1n]/,o=/[1n]/;function i(e,t,n){this.level=e,this.from=t,this.to=n}return function(a,s){var l="ltr"==s?"L":"R";if(0==a.length||"ltr"==s&&!e.test(a))return!1;for(var u,c=a.length,f=[],d=0;d-1&&(r[t]=o.slice(0,i).concat(o.slice(i+1)))}}}function he(e,t){var n=de(e,t);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),o=0;o0}function be(e){e.prototype.on=function(e,t){fe(this,e,t)},e.prototype.off=function(e,t){pe(this,e,t)}}function ye(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function _e(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function we(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.returnValue}function xe(e){ye(e),_e(e)}function Oe(e){return e.target||e.srcElement}function ke(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t=3:4&e.button&&(t=2)),b&&e.ctrlKey&&1==t&&(t=3),t}var Se,je,Ee=function(){if(a&&s<9)return!1;var e=N("div");return"draggable"in e||"dragDrop"in e}();function Ce(e){if(null==Se){var t=N("span","โ€‹");C(e,N("span",[t,document.createTextNode("x")])),0!=e.firstChild.offsetHeight&&(Se=t.offsetWidth<=1&&t.offsetHeight>2&&!(a&&s<8))}var n=Se?N("span","โ€‹"):N("span","ย ",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}function Ne(e){if(null!=je)return je;var t=C(e,document.createTextNode("AุฎA")),n=S(t,0,1).getBoundingClientRect(),r=S(t,1,2).getBoundingClientRect();return E(e),!(!n||n.left==n.right)&&(je=r.right-n.right<3)}var Ae,qe=3!="\n\nb".split(/\n/).length?function(e){for(var t=0,n=[],r=e.length;t<=r;){var o=e.indexOf("\n",t);-1==o&&(o=e.length);var i=e.slice(t,"\r"==e.charAt(o-1)?o-1:o),a=i.indexOf("\r");-1!=a?(n.push(i.slice(0,a)),t+=a+1):(n.push(i),t=o+1)}return n}:function(e){return e.split(/\r\n?|\n/)},Te=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(e){return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch(e){}return!(!t||t.parentElement()!=e)&&0!=t.compareEndPoints("StartToEnd",t)},Pe="oncopy"in(Ae=N("div"))||(Ae.setAttribute("oncopy","return;"),"function"==typeof Ae.oncopy),Me=null,Le={},De={};function Re(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),Le[e]=t}function Ie(e){if("string"==typeof e&&De.hasOwnProperty(e))e=De[e];else if(e&&"string"==typeof e.name&&De.hasOwnProperty(e.name)){var t=De[e.name];"string"==typeof t&&(t={name:t}),(e=Z(t,e)).name=t.name}else{if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return Ie("application/xml");if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return Ie("application/json")}return"string"==typeof e?{name:e}:e||{name:"null"}}function Fe(e,t){t=Ie(t);var n=Le[t.name];if(!n)return Fe(e,"text/plain");var r=n(e,t);if(Be.hasOwnProperty(t.name)){var o=Be[t.name];for(var i in o)o.hasOwnProperty(i)&&(r.hasOwnProperty(i)&&(r["_"+i]=r[i]),r[i]=o[i])}if(r.name=t.name,t.helperType&&(r.helperType=t.helperType),t.modeProps)for(var a in t.modeProps)r[a]=t.modeProps[a];return r}var Be={};function Ue(e,t){R(t,Be.hasOwnProperty(e)?Be[e]:Be[e]={})}function Ve(e,t){if(!0===t)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var o=t[r];o instanceof Array&&(o=o.concat([])),n[r]=o}return n}function ze(e,t){for(var n;e.innerMode&&(n=e.innerMode(t))&&n.mode!=e;)t=n.state,e=n.mode;return n||{mode:e,state:t}}function He(e,t,n){return!e.startState||e.startState(t,n)}var We=function(e,t,n){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=n};function Ge(e,t){if((t-=e.first)<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var o=n.children[r],i=o.chunkSize();if(t=e.first&&tn?et(n,Ge(e,n).text.length):function(e,t){var n=e.ch;return null==n||n>t?et(e.line,t):n<0?et(e.line,0):e}(t,Ge(e,t.line).text.length)}function lt(e,t){for(var n=[],r=0;r=this.string.length},We.prototype.sol=function(){return this.pos==this.lineStart},We.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},We.prototype.next=function(){if(this.post},We.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},We.prototype.skipToEnd=function(){this.pos=this.string.length},We.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},We.prototype.backUp=function(e){this.pos-=e},We.prototype.column=function(){return this.lastColumnPos0?null:(r&&!1!==t&&(this.pos+=r[0].length),r)}var o=function(e){return n?e.toLowerCase():e};if(o(this.string.substr(this.pos,e.length))==o(e))return!1!==t&&(this.pos+=e.length),!0},We.prototype.current=function(){return this.string.slice(this.start,this.pos)},We.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},We.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},We.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};var ut=function(e,t){this.state=e,this.lookAhead=t},ct=function(e,t,n,r){this.state=t,this.doc=e,this.line=n,this.maxLookAhead=r||0,this.baseTokens=null,this.baseTokenPos=1};function ft(e,t,n,r){var o=[e.state.modeGen],i={};_t(e,t.text,e.doc.mode,n,(function(e,t){return o.push(e,t)}),i,r);for(var a=n.state,s=function(r){n.baseTokens=o;var s=e.state.overlays[r],l=1,u=0;n.state=!0,_t(e,t.text,s.mode,n,(function(e,t){for(var n=l;ue&&o.splice(l,1,e,o[l+1],r),l+=2,u=Math.min(e,r)}if(t)if(s.opaque)o.splice(n,l-n,e,"overlay "+t),l=n+2;else for(;ne.options.maxHighlightLength&&Ve(e.doc.mode,r.state),i=ft(e,t,r);o&&(r.state=o),t.stateAfter=r.save(!o),t.styles=i.styles,i.classes?t.styleClasses=i.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function pt(e,t,n){var r=e.doc,o=e.display;if(!r.mode.startState)return new ct(r,!0,t);var i=function(e,t,n){for(var r,o,i=e.doc,a=n?-1:t-(e.doc.mode.innerMode?1e3:100),s=t;s>a;--s){if(s<=i.first)return i.first;var l=Ge(i,s-1),u=l.stateAfter;if(u&&(!n||s+(u instanceof ut?u.lookAhead:0)<=i.modeFrontier))return s;var c=I(l.text,null,e.options.tabSize);(null==o||r>c)&&(o=s-1,r=c)}return o}(e,t,n),a=i>r.first&&Ge(r,i-1).stateAfter,s=a?ct.fromSaved(r,a,i):new ct(r,He(r.mode),i);return r.iter(i,t,(function(n){ht(e,n.text,s);var r=s.line;n.stateAfter=r==t-1||r%5==0||r>=o.viewFrom&&rt.start)return i}throw new Error("Mode "+e.name+" failed to advance stream.")}ct.prototype.lookAhead=function(e){var t=this.doc.getLine(this.line+e);return null!=t&&e>this.maxLookAhead&&(this.maxLookAhead=e),t},ct.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},ct.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},ct.fromSaved=function(e,t,n){return t instanceof ut?new ct(e,Ve(e.mode,t.state),n,t.lookAhead):new ct(e,Ve(e.mode,t),n)},ct.prototype.save=function(e){var t=!1!==e?Ve(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new ut(t,this.maxLookAhead):t};var vt=function(e,t,n){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=n};function bt(e,t,n,r){var o,i,a=e.doc,s=a.mode,l=Ge(a,(t=st(a,t)).line),u=pt(e,t.line,n),c=new We(l.text,e.options.tabSize,u);for(r&&(i=[]);(r||c.pose.options.maxHighlightLength?(s=!1,a&&ht(e,t,r,f.pos),f.pos=t.length,l=null):l=yt(gt(n,f,r.state,d),i),d){var p=d[0].name;p&&(l="m-"+(l?p+" "+l:p))}if(!s||c!=l){for(;u=t:i.to>t);(r||(r=[])).push(new Ot(a,i.from,s?null:i.to))}}return r}(n,o,a),l=function(e,t,n){var r;if(e)for(var o=0;o=t:i.to>t)||i.from==t&&"bookmark"==a.type&&(!n||i.marker.insertLeft)){var s=null==i.from||(a.inclusiveLeft?i.from<=t:i.from0&&s)for(var y=0;yt)&&(!n||Tt(n,i.marker)<0)&&(n=i.marker)}return n}function Rt(e,t,n,r,o){var i=Ge(e,t),a=xt&&i.markedSpans;if(a)for(var s=0;s=0&&f<=0||c<=0&&f>=0)&&(c<=0&&(l.marker.inclusiveRight&&o.inclusiveLeft?tt(u.to,n)>=0:tt(u.to,n)>0)||c>=0&&(l.marker.inclusiveRight&&o.inclusiveLeft?tt(u.from,r)<=0:tt(u.from,r)<0)))return!0}}}function It(e){for(var t;t=Mt(e);)e=t.find(-1,!0).line;return e}function Ft(e,t){var n=Ge(e,t),r=It(n);return n==r?t:Xe(r)}function Bt(e,t){if(t>e.lastLine())return t;var n,r=Ge(e,t);if(!Ut(e,r))return t;for(;n=Lt(r);)r=n.find(1,!0).line;return Xe(r)+1}function Ut(e,t){var n=xt&&t.markedSpans;if(n)for(var r=void 0,o=0;ot.maxLineLength&&(t.maxLineLength=n,t.maxLine=e)}))}var Gt=function(e,t,n){this.text=e,Nt(this,t),this.height=n?n(this):1};function Kt(e){e.parent=null,Ct(e)}Gt.prototype.lineNo=function(){return Xe(this)},be(Gt);var $t={},Yt={};function Xt(e,t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass?Yt:$t;return n[e]||(n[e]=e.replace(/\S+/g,"cm-$&"))}function Zt(e,t){var n=A("span",null,null,l?"padding-right: .1px":null),r={pre:A("pre",[n],"CodeMirror-line"),content:n,col:0,pos:0,cm:e,trailingSpace:!1,splitSpaces:e.getOption("lineWrapping")};t.measure={};for(var o=0;o<=(t.rest?t.rest.length:0);o++){var i=o?t.rest[o-1]:t.line,a=void 0;r.pos=0,r.addToken=Qt,Ne(e.display.measure)&&(a=ue(i,e.doc.direction))&&(r.addToken=en(r.addToken,a)),r.map=[],nn(i,r,dt(e,i,t!=e.display.externalMeasured&&Xe(i))),i.styleClasses&&(i.styleClasses.bgClass&&(r.bgClass=M(i.styleClasses.bgClass,r.bgClass||"")),i.styleClasses.textClass&&(r.textClass=M(i.styleClasses.textClass,r.textClass||""))),0==r.map.length&&r.map.push(0,0,r.content.appendChild(Ce(e.display.measure))),0==o?(t.measure.map=r.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(r.map),(t.measure.caches||(t.measure.caches=[])).push({}))}if(l){var s=r.content.lastChild;(/\bcm-tab\b/.test(s.className)||s.querySelector&&s.querySelector(".cm-tab"))&&(r.content.className="cm-tab-wrap-hack")}return he(e,"renderLine",e,t.line,r.pre),r.pre.className&&(r.textClass=M(r.pre.className,r.textClass||"")),r}function Jt(e){var t=N("span","โ€ข","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function Qt(e,t,n,r,o,i,l){if(t){var u,c=e.splitSpaces?function(e,t){if(e.length>1&&!/ /.test(e))return e;for(var n=t,r="",o=0;ou&&f.from<=u);d++);if(f.to>=c)return e(n,r,o,i,a,s,l);e(n,r.slice(0,f.to-u),o,i,null,s,l),i=null,r=r.slice(f.to-u),u=f.to}}}function tn(e,t,n,r){var o=!r&&n.widgetNode;o&&e.map.push(e.pos,e.pos+t,o),!r&&e.cm.display.input.needsContentAttribute&&(o||(o=e.content.appendChild(document.createElement("span"))),o.setAttribute("cm-marker",n.id)),o&&(e.cm.display.input.setUneditable(o),e.content.appendChild(o)),e.pos+=t,e.trailingSpace=!1}function nn(e,t,n){var r=e.markedSpans,o=e.text,i=0;if(r)for(var a,s,l,u,c,f,d,p=o.length,h=0,m=1,g="",v=0;;){if(v==h){l=u=c=s="",d=null,f=null,v=1/0;for(var b=[],y=void 0,_=0;_h||x.collapsed&&w.to==h&&w.from==h)){if(null!=w.to&&w.to!=h&&v>w.to&&(v=w.to,u=""),x.className&&(l+=" "+x.className),x.css&&(s=(s?s+";":"")+x.css),x.startStyle&&w.from==h&&(c+=" "+x.startStyle),x.endStyle&&w.to==v&&(y||(y=[])).push(x.endStyle,w.to),x.title&&((d||(d={})).title=x.title),x.attributes)for(var O in x.attributes)(d||(d={}))[O]=x.attributes[O];x.collapsed&&(!f||Tt(f.marker,x)<0)&&(f=w)}else w.from>h&&v>w.from&&(v=w.from)}if(y)for(var k=0;k=p)break;for(var j=Math.min(p,v);;){if(g){var E=h+g.length;if(!f){var C=E>j?g.slice(0,j-h):g;t.addToken(t,C,a?a+l:l,c,h+C.length==v?u:"",s,d)}if(E>=j){g=g.slice(j-h),h=j;break}h=E,c=""}g=o.slice(i,i=n[m++]),a=Xt(n[m++],t.cm.options)}}else for(var N=1;Nn)return{map:e.measure.maps[o],cache:e.measure.caches[o],before:!0}}function An(e,t,n,r){return Pn(e,Tn(e,t),n,r)}function qn(e,t){if(t>=e.display.viewFrom&&t=n.lineN&&t2&&i.push((l.bottom+u.top)/2-n.top)}}i.push(n.bottom-n.top)}}(e,t.view,t.rect),t.hasHeights=!0),(i=function(e,t,n,r){var o,i=Dn(t.map,n,r),l=i.node,u=i.start,c=i.end,f=i.collapse;if(3==l.nodeType){for(var d=0;d<4;d++){for(;u&&re(t.line.text.charAt(i.coverStart+u));)--u;for(;i.coverStart+c1}(e))return t;var n=screen.logicalXDPI/screen.deviceXDPI,r=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*n,right:t.right*n,top:t.top*r,bottom:t.bottom*r}}(e.display.measure,o))}else{var p;u>0&&(f=r="right"),o=e.options.lineWrapping&&(p=l.getClientRects()).length>1?p["right"==r?p.length-1:0]:l.getBoundingClientRect()}if(a&&s<9&&!u&&(!o||!o.left&&!o.right)){var h=l.parentNode.getClientRects()[0];o=h?{left:h.left,right:h.left+or(e.display),top:h.top,bottom:h.bottom}:Ln}for(var m=o.top-t.rect.top,g=o.bottom-t.rect.top,v=(m+g)/2,b=t.view.measure.heights,y=0;yt)&&(o=(i=l-s)-1,t>=l&&(a="right")),null!=o){if(r=e[u+2],s==l&&n==(r.insertLeft?"left":"right")&&(a=n),"left"==n&&0==o)for(;u&&e[u-2]==e[u-3]&&e[u-1].insertLeft;)r=e[2+(u-=3)],a="left";if("right"==n&&o==l-s)for(;u=0&&(n=e[o]).left==n.right;o--);return n}function In(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t=r.text.length?(l=r.text.length,u="before"):l<=0&&(l=0,u="after"),!s)return a("before"==u?l-1:l,"before"==u);function c(e,t,n){return a(n?e-1:e,1==s[t].level!=n)}var f=se(s,l,u),d=ae,p=c(l,f,"before"==u);return null!=d&&(p.other=c(l,d,"before"!=u)),p}function $n(e,t){var n=0;t=st(e.doc,t),e.options.lineWrapping||(n=or(e.display)*t.ch);var r=Ge(e.doc,t.line),o=zt(r)+On(e.display);return{left:n,right:n,top:o,bottom:o+r.height}}function Yn(e,t,n,r,o){var i=et(e,t,n);return i.xRel=o,r&&(i.outside=r),i}function Xn(e,t,n){var r=e.doc;if((n+=e.display.viewOffset)<0)return Yn(r.first,0,null,-1,-1);var o=Ze(r,n),i=r.first+r.size-1;if(o>i)return Yn(r.first+r.size-1,Ge(r,i).text.length,null,1,1);t<0&&(t=0);for(var a=Ge(r,o);;){var s=er(e,a,o,t,n),l=Dt(a,s.ch+(s.xRel>0||s.outside>0?1:0));if(!l)return s;var u=l.find(1);if(u.line==o)return u;a=Ge(r,o=u.line)}}function Zn(e,t,n,r){r-=zn(t);var o=t.text.length,i=ie((function(t){return Pn(e,n,t-1).bottom<=r}),o,0);return{begin:i,end:o=ie((function(t){return Pn(e,n,t).top>r}),i,o)}}function Jn(e,t,n,r){return n||(n=Tn(e,t)),Zn(e,t,n,Hn(e,t,Pn(e,n,r),"line").top)}function Qn(e,t,n,r){return!(e.bottom<=n)&&(e.top>n||(r?e.left:e.right)>t)}function er(e,t,n,r,o){o-=zt(t);var i=Tn(e,t),a=zn(t),s=0,l=t.text.length,u=!0,c=ue(t,e.doc.direction);if(c){var f=(e.options.lineWrapping?nr:tr)(e,t,n,i,c,r,o);s=(u=1!=f.level)?f.from:f.to-1,l=u?f.to:f.from-1}var d,p,h=null,m=null,g=ie((function(t){var n=Pn(e,i,t);return n.top+=a,n.bottom+=a,!!Qn(n,r,o,!1)&&(n.top<=o&&n.left<=r&&(h=t,m=n),!0)}),s,l),v=!1;if(m){var b=r-m.left=_.bottom?1:0}return Yn(n,g=oe(t.text,g,1),p,v,r-d)}function tr(e,t,n,r,o,i,a){var s=ie((function(s){var l=o[s],u=1!=l.level;return Qn(Kn(e,et(n,u?l.to:l.from,u?"before":"after"),"line",t,r),i,a,!0)}),0,o.length-1),l=o[s];if(s>0){var u=1!=l.level,c=Kn(e,et(n,u?l.from:l.to,u?"after":"before"),"line",t,r);Qn(c,i,a,!0)&&c.top>a&&(l=o[s-1])}return l}function nr(e,t,n,r,o,i,a){var s=Zn(e,t,r,a),l=s.begin,u=s.end;/\s/.test(t.text.charAt(u-1))&&u--;for(var c=null,f=null,d=0;d=u||p.to<=l)){var h=Pn(e,r,1!=p.level?Math.min(u,p.to)-1:Math.max(l,p.from)).right,m=hm)&&(c=p,f=m)}}return c||(c=o[o.length-1]),c.fromu&&(c={from:c.from,to:u,level:c.level}),c}function rr(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==Mn){Mn=N("pre",null,"CodeMirror-line-like");for(var t=0;t<49;++t)Mn.appendChild(document.createTextNode("x")),Mn.appendChild(N("br"));Mn.appendChild(document.createTextNode("x"))}C(e.measure,Mn);var n=Mn.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),E(e.measure),n||1}function or(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=N("span","xxxxxxxxxx"),n=N("pre",[t],"CodeMirror-line-like");C(e.measure,n);var r=t.getBoundingClientRect(),o=(r.right-r.left)/10;return o>2&&(e.cachedCharWidth=o),o||10}function ir(e){for(var t=e.display,n={},r={},o=t.gutters.clientLeft,i=t.gutters.firstChild,a=0;i;i=i.nextSibling,++a){var s=e.display.gutterSpecs[a].className;n[s]=i.offsetLeft+i.clientLeft+o,r[s]=i.clientWidth}return{fixedPos:ar(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function ar(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function sr(e){var t=rr(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/or(e.display)-3);return function(o){if(Ut(e.doc,o))return 0;var i=0;if(o.widgets)for(var a=0;a0&&(l=Ge(e.doc,u.line).text).length==u.ch){var c=I(l,l.length,e.options.tabSize)-l.length;u=et(u.line,Math.max(0,Math.round((i-Sn(e.display).left)/or(e.display))-c))}return u}function cr(e,t){if(t>=e.display.viewTo)return null;if((t-=e.display.viewFrom)<0)return null;for(var n=e.display.view,r=0;rt)&&(o.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=o.viewTo)xt&&Ft(e.doc,t)o.viewFrom?pr(e):(o.viewFrom+=r,o.viewTo+=r);else if(t<=o.viewFrom&&n>=o.viewTo)pr(e);else if(t<=o.viewFrom){var i=hr(e,n,n+r,1);i?(o.view=o.view.slice(i.index),o.viewFrom=i.lineN,o.viewTo+=r):pr(e)}else if(n>=o.viewTo){var a=hr(e,t,t,-1);a?(o.view=o.view.slice(0,a.index),o.viewTo=a.lineN):pr(e)}else{var s=hr(e,t,t,-1),l=hr(e,n,n+r,1);s&&l?(o.view=o.view.slice(0,s.index).concat(on(e,s.lineN,l.lineN)).concat(o.view.slice(l.index)),o.viewTo+=r):pr(e)}var u=o.externalMeasured;u&&(n=o.lineN&&t=r.viewTo)){var i=r.view[cr(e,t)];if(null!=i.node){var a=i.changes||(i.changes=[]);-1==B(a,n)&&a.push(n)}}}function pr(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function hr(e,t,n,r){var o,i=cr(e,t),a=e.display.view;if(!xt||n==e.doc.first+e.doc.size)return{index:i,lineN:n};for(var s=e.display.viewFrom,l=0;l0){if(i==a.length-1)return null;o=s+a[i].size-t,i++}else o=s-t;t+=o,n+=o}for(;Ft(e.doc,n)!=n;){if(i==(r<0?0:a.length-1))return null;n+=r*a[i-(r<0?1:0)].size,i+=r}return{index:i,lineN:n}}function mr(e){for(var t=e.display.view,n=0,r=0;r=e.display.viewTo||s.to().linet||t==n&&a.to==t)&&(r(Math.max(a.from,t),Math.min(a.to,n),1==a.level?"rtl":"ltr",i),o=!0)}o||r(t,n,"ltr")}(m,n||0,null==r?d:r,(function(e,t,o,f){var g="ltr"==o,v=p(e,g?"left":"right"),b=p(t-1,g?"right":"left"),y=null==n&&0==e,_=null==r&&t==d,w=0==f,x=!m||f==m.length-1;if(b.top-v.top<=3){var O=(u?_:y)&&x,k=(u?y:_)&&w?s:(g?v:b).left,S=O?l:(g?b:v).right;c(k,v.top,S-k,v.bottom)}else{var j,E,C,N;g?(j=u&&y&&w?s:v.left,E=u?l:h(e,o,"before"),C=u?s:h(t,o,"after"),N=u&&_&&x?l:b.right):(j=u?h(e,o,"before"):s,E=!u&&y&&w?l:v.right,C=!u&&_&&x?s:b.left,N=u?h(t,o,"after"):l),c(j,v.top,E-j,v.bottom),v.bottom0?t.blinker=setInterval((function(){e.hasFocus()||Sr(e),t.cursorDiv.style.visibility=(n=!n)?"":"hidden"}),e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function xr(e){e.hasFocus()||(e.display.input.focus(),e.state.focused||kr(e))}function Or(e){e.state.delayingBlurEvent=!0,setTimeout((function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,e.state.focused&&Sr(e))}),100)}function kr(e,t){e.state.delayingBlurEvent&&!e.state.draggingText&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(he(e,"focus",e,t),e.state.focused=!0,P(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),l&&setTimeout((function(){return e.display.input.reset(!0)}),20)),e.display.input.receivedFocus()),wr(e))}function Sr(e,t){e.state.delayingBlurEvent||(e.state.focused&&(he(e,"blur",e,t),e.state.focused=!1,j(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout((function(){e.state.focused||(e.display.shift=!1)}),150))}function jr(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=0;r.005||d<-.005)&&(Ye(o.line,l),Er(o.line),o.rest))for(var p=0;pe.display.sizerWidth){var h=Math.ceil(u/or(e.display));h>e.display.maxLineLength&&(e.display.maxLineLength=h,e.display.maxLine=o.line,e.display.maxLineChanged=!0)}}}}function Er(e){if(e.widgets)for(var t=0;t=a&&(i=Ze(t,zt(Ge(t,l))-e.wrapper.clientHeight),a=l)}return{from:i,to:Math.max(a,i+1)}}function Nr(e,t){var n=e.display,r=rr(e.display);t.top<0&&(t.top=0);var o=e.curOp&&null!=e.curOp.scrollTop?e.curOp.scrollTop:n.scroller.scrollTop,i=Cn(e),a={};t.bottom-t.top>i&&(t.bottom=t.top+i);var s=e.doc.height+kn(n),l=t.tops-r;if(t.topo+i){var c=Math.min(t.top,(u?s:t.bottom)-i);c!=o&&(a.scrollTop=c)}var f=e.options.fixedGutter?0:n.gutters.offsetWidth,d=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:n.scroller.scrollLeft-f,p=En(e)-n.gutters.offsetWidth,h=t.right-t.left>p;return h&&(t.right=t.left+p),t.left<10?a.scrollLeft=0:t.leftp+d-3&&(a.scrollLeft=t.right+(h?0:10)-p),a}function Ar(e,t){null!=t&&(Pr(e),e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+t)}function qr(e){Pr(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function Tr(e,t,n){null==t&&null==n||Pr(e),null!=t&&(e.curOp.scrollLeft=t),null!=n&&(e.curOp.scrollTop=n)}function Pr(e){var t=e.curOp.scrollToPos;t&&(e.curOp.scrollToPos=null,Mr(e,$n(e,t.from),$n(e,t.to),t.margin))}function Mr(e,t,n,r){var o=Nr(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});Tr(e,o.scrollLeft,o.scrollTop)}function Lr(e,t){Math.abs(e.doc.scrollTop-t)<2||(n||lo(e,{top:t}),Dr(e,t,!0),n&&lo(e),ro(e,100))}function Dr(e,t,n){t=Math.max(0,Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t)),(e.display.scroller.scrollTop!=t||n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Rr(e,t,n,r){t=Math.max(0,Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth)),(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r||(e.doc.scrollLeft=t,fo(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function Ir(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+kn(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+jn(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}var Fr=function(e,t,n){this.cm=n;var r=this.vert=N("div",[N("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),o=this.horiz=N("div",[N("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");r.tabIndex=o.tabIndex=-1,e(r),e(o),fe(r,"scroll",(function(){r.clientHeight&&t(r.scrollTop,"vertical")})),fe(o,"scroll",(function(){o.clientWidth&&t(o.scrollLeft,"horizontal")})),this.checkedZeroWidth=!1,a&&s<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Fr.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var o=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+o)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var i=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+i)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(0==r&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},Fr.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Fr.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Fr.prototype.zeroWidthHack=function(){var e=b&&!p?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new F,this.disableVert=new F},Fr.prototype.enableZeroWidthBar=function(e,t,n){e.style.pointerEvents="auto",t.set(1e3,(function r(){var o=e.getBoundingClientRect();("vert"==n?document.elementFromPoint(o.right-1,(o.top+o.bottom)/2):document.elementFromPoint((o.right+o.left)/2,o.bottom-1))!=e?e.style.pointerEvents="none":t.set(1e3,r)}))},Fr.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var Br=function(){};function Ur(e,t){t||(t=Ir(e));var n=e.display.barWidth,r=e.display.barHeight;Vr(e,t);for(var o=0;o<4&&n!=e.display.barWidth||r!=e.display.barHeight;o++)n!=e.display.barWidth&&e.options.lineWrapping&&jr(e),Vr(e,Ir(e)),n=e.display.barWidth,r=e.display.barHeight}function Vr(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}Br.prototype.update=function(){return{bottom:0,right:0}},Br.prototype.setScrollLeft=function(){},Br.prototype.setScrollTop=function(){},Br.prototype.clear=function(){};var zr={native:Fr,null:Br};function Hr(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&j(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new zr[e.options.scrollbarStyle]((function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),fe(t,"mousedown",(function(){e.state.focused&&setTimeout((function(){return e.display.input.focus()}),0)})),t.setAttribute("cm-not-content","true")}),(function(t,n){"horizontal"==n?Rr(e,t):Lr(e,t)}),e),e.display.scrollbars.addClass&&P(e.display.wrapper,e.display.scrollbars.addClass)}var Wr=0;function Gr(e){var t;e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:0,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Wr,markArrays:null},t=e.curOp,an?an.ops.push(t):t.ownsGroup=an={ops:[t],delayedCallbacks:[]}}function Kr(e){var t=e.curOp;t&&function(e,t){var n=e.ownsGroup;if(n)try{!function(e){var t=e.delayedCallbacks,n=0;do{for(;n=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new io(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Yr(e){e.updatedDisplay=e.mustUpdate&&ao(e.cm,e.update)}function Xr(e){var t=e.cm,n=t.display;e.updatedDisplay&&jr(t),e.barMeasure=Ir(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=An(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+jn(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-En(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Zr(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft(window.innerHeight||document.documentElement.clientHeight)&&(o=!1),null!=o&&!h){var i=N("div","โ€‹",null,"position: absolute;\n top: "+(t.top-n.viewOffset-On(e.display))+"px;\n height: "+(t.bottom-t.top+jn(e)+n.barHeight)+"px;\n left: "+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(i),i.scrollIntoView(o),e.display.lineSpace.removeChild(i)}}}(t,function(e,t,n,r){var o;null==r&&(r=0),e.options.lineWrapping||t!=n||(n="before"==t.sticky?et(t.line,t.ch+1,"before"):t,t=t.ch?et(t.line,"before"==t.sticky?t.ch-1:t.ch,"after"):t);for(var i=0;i<5;i++){var a=!1,s=Kn(e,t),l=n&&n!=t?Kn(e,n):s,u=Nr(e,o={left:Math.min(s.left,l.left),top:Math.min(s.top,l.top)-r,right:Math.max(s.left,l.left),bottom:Math.max(s.bottom,l.bottom)+r}),c=e.doc.scrollTop,f=e.doc.scrollLeft;if(null!=u.scrollTop&&(Lr(e,u.scrollTop),Math.abs(e.doc.scrollTop-c)>1&&(a=!0)),null!=u.scrollLeft&&(Rr(e,u.scrollLeft),Math.abs(e.doc.scrollLeft-f)>1&&(a=!0)),!a)break}return o}(t,st(r,e.scrollToPos.from),st(r,e.scrollToPos.to),e.scrollToPos.margin));var o=e.maybeHiddenMarkers,i=e.maybeUnhiddenMarkers;if(o)for(var a=0;a=e.display.viewTo)){var n=+new Date+e.options.workTime,r=pt(e,t.highlightFrontier),o=[];t.iter(r.line,Math.min(t.first+t.size,e.display.viewTo+500),(function(i){if(r.line>=e.display.viewFrom){var a=i.styles,s=i.text.length>e.options.maxHighlightLength?Ve(t.mode,r.state):null,l=ft(e,i,r,!0);s&&(r.state=s),i.styles=l.styles;var u=i.styleClasses,c=l.classes;c?i.styleClasses=c:u&&(i.styleClasses=null);for(var f=!a||a.length!=i.styles.length||u!=c&&(!u||!c||u.bgClass!=c.bgClass||u.textClass!=c.textClass),d=0;!f&&dn)return ro(e,e.options.workDelay),!0})),t.highlightFrontier=r.line,t.modeFrontier=Math.max(t.modeFrontier,r.line),o.length&&Qr(e,(function(){for(var t=0;t=n.viewFrom&&t.visible.to<=n.viewTo&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&0==mr(e))return!1;po(e)&&(pr(e),t.dims=ir(e));var o=r.first+r.size,i=Math.max(t.visible.from-e.options.viewportMargin,r.first),a=Math.min(o,t.visible.to+e.options.viewportMargin);n.viewFroma&&n.viewTo-a<20&&(a=Math.min(o,n.viewTo)),xt&&(i=Ft(e.doc,i),a=Bt(e.doc,a));var s=i!=n.viewFrom||a!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;!function(e,t,n){var r=e.display;0==r.view.length||t>=r.viewTo||n<=r.viewFrom?(r.view=on(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=on(e,t,r.viewFrom).concat(r.view):r.viewFromn&&(r.view=r.view.slice(0,cr(e,n)))),r.viewTo=n}(e,i,a),n.viewOffset=zt(Ge(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var u=mr(e);if(!s&&0==u&&!t.force&&n.renderedView==n.view&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo))return!1;var c=function(e){if(e.hasFocus())return null;var t=T();if(!t||!q(e.display.lineDiv,t))return null;var n={activeElt:t};if(window.getSelection){var r=window.getSelection();r.anchorNode&&r.extend&&q(e.display.lineDiv,r.anchorNode)&&(n.anchorNode=r.anchorNode,n.anchorOffset=r.anchorOffset,n.focusNode=r.focusNode,n.focusOffset=r.focusOffset)}return n}(e);return u>4&&(n.lineDiv.style.display="none"),function(e,t,n){var r=e.display,o=e.options.lineNumbers,i=r.lineDiv,a=i.firstChild;function s(t){var n=t.nextSibling;return l&&b&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),n}for(var u=r.view,c=r.viewFrom,f=0;f-1&&(p=!1),cn(e,d,c,n)),p&&(E(d.lineNumber),d.lineNumber.appendChild(document.createTextNode(Qe(e.options,c)))),a=d.node.nextSibling}else{var h=vn(e,d,c,n);i.insertBefore(h,a)}c+=d.size}for(;a;)a=s(a)}(e,n.updateLineNumbers,t.dims),u>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,function(e){if(e&&e.activeElt&&e.activeElt!=T()&&(e.activeElt.focus(),!/^(INPUT|TEXTAREA)$/.test(e.activeElt.nodeName)&&e.anchorNode&&q(document.body,e.anchorNode)&&q(document.body,e.focusNode))){var t=window.getSelection(),n=document.createRange();n.setEnd(e.anchorNode,e.anchorOffset),n.collapse(!1),t.removeAllRanges(),t.addRange(n),t.extend(e.focusNode,e.focusOffset)}}(c),E(n.cursorDiv),E(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,s&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,ro(e,400)),n.updateLineNumbers=null,!0}function so(e,t){for(var n=t.viewport,r=!0;;r=!1){if(r&&e.options.lineWrapping&&t.oldDisplayWidth!=En(e))r&&(t.visible=Cr(e.display,e.doc,n));else if(n&&null!=n.top&&(n={top:Math.min(e.doc.height+kn(e.display)-Cn(e),n.top)}),t.visible=Cr(e.display,e.doc,n),t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)break;if(!ao(e,t))break;jr(e);var o=Ir(e);gr(e),Ur(e,o),co(e,o),t.force=!1}t.signal(e,"update",e),e.display.viewFrom==e.display.reportedViewFrom&&e.display.viewTo==e.display.reportedViewTo||(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function lo(e,t){var n=new io(e,t);if(ao(e,n)){jr(e),so(e,n);var r=Ir(e);gr(e),Ur(e,r),co(e,r),n.finish()}}function uo(e){var t=e.gutters.offsetWidth;e.sizer.style.marginLeft=t+"px",ln(e,"gutterChanged",e)}function co(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+jn(e)+"px"}function fo(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var r=ar(t)-t.scroller.scrollLeft+e.doc.scrollLeft,o=t.gutters.offsetWidth,i=r+"px",a=0;as.clientWidth,c=s.scrollHeight>s.clientHeight;if(o&&u||i&&c){if(i&&b&&l)e:for(var d=t.target,p=a.view;d!=s;d=d.parentNode)for(var h=0;h=0&&tt(e,r.to())<=0)return n}return-1};var ko=function(e,t){this.anchor=e,this.head=t};function So(e,t,n){var r=e&&e.options.selectionsMayTouch,o=t[n];t.sort((function(e,t){return tt(e.from(),t.from())})),n=B(t,o);for(var i=1;i0:l>=0){var u=it(s.from(),a.from()),c=ot(s.to(),a.to()),f=s.empty()?a.from()==a.head:s.from()==s.head;i<=n&&--n,t.splice(--i,2,new ko(f?c:u,f?u:c))}}return new Oo(t,n)}function jo(e,t){return new Oo([new ko(e,t||e)],0)}function Eo(e){return e.text?et(e.from.line+e.text.length-1,$(e.text).length+(1==e.text.length?e.from.ch:0)):e.to}function Co(e,t){if(tt(e,t.from)<0)return e;if(tt(e,t.to)<=0)return Eo(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=Eo(t).ch-t.to.ch),et(n,r)}function No(e,t){for(var n=[],r=0;r1&&e.remove(s.line+1,h-1),e.insert(s.line+1,v)}ln(e,"change",e,t)}function Lo(e,t,n){!function e(r,o,i){if(r.linked)for(var a=0;as-(e.cm?e.cm.options.historyEventDelay:500)||"*"==t.origin.charAt(0)))&&(i=function(e,t){return t?(Bo(e.done),$(e.done)):e.done.length&&!$(e.done).ranges?$(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),$(e.done)):void 0}(o,o.lastOp==r)))a=$(i.changes),0==tt(t.from,t.to)&&0==tt(t.from,a.to)?a.to=Eo(t):i.changes.push(Fo(e,t));else{var l=$(o.done);for(l&&l.ranges||zo(e.sel,o.done),i={changes:[Fo(e,t)],generation:o.generation},o.done.push(i);o.done.length>o.undoDepth;)o.done.shift(),o.done[0].ranges||o.done.shift()}o.done.push(n),o.generation=++o.maxGeneration,o.lastModTime=o.lastSelTime=s,o.lastOp=o.lastSelOp=r,o.lastOrigin=o.lastSelOrigin=t.origin,a||he(e,"historyAdded")}function Vo(e,t,n,r){var o=e.history,i=r&&r.origin;n==o.lastSelOp||i&&o.lastSelOrigin==i&&(o.lastModTime==o.lastSelTime&&o.lastOrigin==i||function(e,t,n,r){var o=t.charAt(0);return"*"==o||"+"==o&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}(e,i,$(o.done),t))?o.done[o.done.length-1]=t:zo(t,o.done),o.lastSelTime=+new Date,o.lastSelOrigin=i,o.lastSelOp=n,r&&!1!==r.clearRedo&&Bo(o.undone)}function zo(e,t){var n=$(t);n&&n.ranges&&n.equals(e)||t.push(e)}function Ho(e,t,n,r){var o=t["spans_"+e.id],i=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),(function(n){n.markedSpans&&((o||(o=t["spans_"+e.id]={}))[i]=n.markedSpans),++i}))}function Wo(e){if(!e)return null;for(var t,n=0;n-1&&($(s)[f]=u[f],delete u[f])}}}return r}function $o(e,t,n,r){if(r){var o=e.anchor;if(n){var i=tt(t,o)<0;i!=tt(n,o)<0?(o=t,t=n):i!=tt(t,n)<0&&(t=n)}return new ko(o,t)}return new ko(n||t,t)}function Yo(e,t,n,r,o){null==o&&(o=e.cm&&(e.cm.display.shift||e.extend)),ei(e,new Oo([$o(e.sel.primary(),t,n,o)],0),r)}function Xo(e,t,n){for(var r=[],o=e.cm&&(e.cm.display.shift||e.extend),i=0;i=t.ch:s.to>t.ch))){if(o&&(he(l,"beforeCursorEnter"),l.explicitlyCleared)){if(i.markedSpans){--a;continue}break}if(!l.atomic)continue;if(n){var f=l.find(r<0?1:-1),d=void 0;if((r<0?c:u)&&(f=si(e,f,-r,f&&f.line==t.line?i:null)),f&&f.line==t.line&&(d=tt(f,n))&&(r<0?d<0:d>0))return ii(e,f,t,r,o)}var p=l.find(r<0?-1:1);return(r<0?u:c)&&(p=si(e,p,r,p.line==t.line?i:null)),p?ii(e,p,t,r,o):null}}return t}function ai(e,t,n,r,o){var i=r||1,a=ii(e,t,n,i,o)||!o&&ii(e,t,n,i,!0)||ii(e,t,n,-i,o)||!o&&ii(e,t,n,-i,!0);return a||(e.cantEdit=!0,et(e.first,0))}function si(e,t,n,r){return n<0&&0==t.ch?t.line>e.first?st(e,et(t.line-1)):null:n>0&&t.ch==(r||Ge(e,t.line)).text.length?t.line0)){var c=[l,1],f=tt(u.from,s.from),d=tt(u.to,s.to);(f<0||!a.inclusiveLeft&&!f)&&c.push({from:u.from,to:s.from}),(d>0||!a.inclusiveRight&&!d)&&c.push({from:s.to,to:u.to}),o.splice.apply(o,c),l+=c.length-3}}return o}(e,t.from,t.to);if(r)for(var o=r.length-1;o>=0;--o)fi(e,{from:r[o].from,to:r[o].to,text:o?[""]:t.text,origin:t.origin});else fi(e,t)}}function fi(e,t){if(1!=t.text.length||""!=t.text[0]||0!=tt(t.from,t.to)){var n=No(e,t);Uo(e,t,n,e.cm?e.cm.curOp.id:NaN),hi(e,t,n,jt(e,t));var r=[];Lo(e,(function(e,n){n||-1!=B(r,e.history)||(bi(e.history,t),r.push(e.history)),hi(e,t,null,jt(e,t))}))}}function di(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!r||n){for(var o,i=e.history,a=e.sel,s="undo"==t?i.done:i.undone,l="undo"==t?i.undone:i.done,u=0;u=0;--p){var h=d(p);if(h)return h.v}}}}function pi(e,t){if(0!=t&&(e.first+=t,e.sel=new Oo(Y(e.sel.ranges,(function(e){return new ko(et(e.anchor.line+t,e.anchor.ch),et(e.head.line+t,e.head.ch))})),e.sel.primIndex),e.cm)){fr(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;re.lastLine())){if(t.from.linei&&(t={from:t.from,to:et(i,Ge(e,i).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Ke(e,t.from,t.to),n||(n=No(e,t)),e.cm?function(e,t,n){var r=e.doc,o=e.display,i=t.from,a=t.to,s=!1,l=i.line;e.options.lineWrapping||(l=Xe(It(Ge(r,i.line))),r.iter(l,a.line+1,(function(e){if(e==o.maxLine)return s=!0,!0}))),r.sel.contains(t.from,t.to)>-1&&ge(e),Mo(r,t,n,sr(e)),e.options.lineWrapping||(r.iter(l,i.line+t.text.length,(function(e){var t=Ht(e);t>o.maxLineLength&&(o.maxLine=e,o.maxLineLength=t,o.maxLineChanged=!0,s=!1)})),s&&(e.curOp.updateMaxLine=!0)),function(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontiern;r--){var o=Ge(e,r).stateAfter;if(o&&(!(o instanceof ut)||r+o.lookAhead1||!(this.children[0]instanceof _i))){var s=[];this.collapse(s),this.children=[new _i(s)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var a=o.lines.length%25+25,s=a;s10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;r0||0==a&&!1!==i.clearWhenEmpty)return i;if(i.replacedWith&&(i.collapsed=!0,i.widgetNode=A("span",[i.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||i.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(i.widgetNode.insertLeft=!0)),i.collapsed){if(Rt(e,t.line,t,n,i)||t.line!=n.line&&Rt(e,n.line,t,n,i))throw new Error("Inserting collapsed marker partially overlapping an existing one");xt=!0}i.addToHistory&&Uo(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var s,l=t.line,u=e.cm;if(e.iter(l,n.line+1,(function(r){u&&i.collapsed&&!u.options.lineWrapping&&It(r)==u.display.maxLine&&(s=!0),i.collapsed&&l!=t.line&&Ye(r,0),function(e,t,n){var r=n&&window.WeakSet&&(n.markedSpans||(n.markedSpans=new WeakSet));r&&r.has(e.markedSpans)?e.markedSpans.push(t):(e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],r&&r.add(e.markedSpans)),t.marker.attachLine(e)}(r,new Ot(i,l==t.line?t.ch:null,l==n.line?n.ch:null),e.cm&&e.cm.curOp),++l})),i.collapsed&&e.iter(t.line,n.line+1,(function(t){Ut(e,t)&&Ye(t,0)})),i.clearOnEnter&&fe(i,"beforeCursorEnter",(function(){return i.clear()})),i.readOnly&&(wt=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),i.collapsed&&(i.id=++ki,i.atomic=!0),u){if(s&&(u.curOp.updateMaxLine=!0),i.collapsed)fr(u,t.line,n.line+1);else if(i.className||i.startStyle||i.endStyle||i.css||i.attributes||i.title)for(var c=t.line;c<=n.line;c++)dr(u,c,"text");i.atomic&&ri(u.doc),ln(u,"markerAdded",u,i)}return i}Si.prototype.clear=function(){if(!this.explicitlyCleared){var e=this.doc.cm,t=e&&!e.curOp;if(t&&Gr(e),ve(this,"clear")){var n=this.find();n&&ln(this,"clear",n.from,n.to)}for(var r=null,o=null,i=0;ie.display.maxLineLength&&(e.display.maxLine=u,e.display.maxLineLength=c,e.display.maxLineChanged=!0)}null!=r&&e&&this.collapsed&&fr(e,r,o+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&ri(e.doc)),e&&ln(e,"markerCleared",e,this,r,o),t&&Kr(e),this.parent&&this.parent.clear()}},Si.prototype.find=function(e,t){var n,r;null==e&&"bookmark"==this.type&&(e=1);for(var o=0;o=0;l--)ci(this,r[l]);s?Qo(this,s):this.cm&&qr(this.cm)})),undo:no((function(){di(this,"undo")})),redo:no((function(){di(this,"redo")})),undoSelection:no((function(){di(this,"undo",!0)})),redoSelection:no((function(){di(this,"redo",!0)})),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r=e.ch)&&t.push(o.marker.parent||o.marker)}return t},findMarks:function(e,t,n){e=st(this,e),t=st(this,t);var r=[],o=e.line;return this.iter(e.line,t.line+1,(function(i){var a=i.markedSpans;if(a)for(var s=0;s=l.to||null==l.from&&o!=e.line||null!=l.from&&o==t.line&&l.from>=t.ch||n&&!n(l.marker)||r.push(l.marker.parent||l.marker)}++o})),r},getAllMarks:function(){var e=[];return this.iter((function(t){var n=t.markedSpans;if(n)for(var r=0;re)return t=e,!0;e-=i,++n})),st(this,et(n,t))},indexFromPos:function(e){var t=(e=st(this,e)).ch;if(e.linet&&(t=e.from),null!=e.to&&e.to-1)return t.state.draggingText(e),void setTimeout((function(){return t.display.input.focus()}),20);try{var f=e.dataTransfer.getData("Text");if(f){var d;if(t.state.draggingText&&!t.state.draggingText.copy&&(d=t.listSelections()),ti(t.doc,jo(n,n)),d)for(var p=0;p=0;t--)mi(e.doc,"",r[t].from,r[t].to,"+delete");qr(e)}))}function Ji(e,t,n){var r=oe(e.text,t+n,n);return r<0||r>e.text.length?null:r}function Qi(e,t,n){var r=Ji(e,t.ch,n);return null==r?null:new et(t.line,r,n<0?"after":"before")}function ea(e,t,n,r,o){if(e){"rtl"==t.doc.direction&&(o=-o);var i=ue(n,t.doc.direction);if(i){var a,s=o<0?$(i):i[0],l=o<0==(1==s.level)?"after":"before";if(s.level>0||"rtl"==t.doc.direction){var u=Tn(t,n);a=o<0?n.text.length-1:0;var c=Pn(t,u,a).top;a=ie((function(e){return Pn(t,u,e).top==c}),o<0==(1==s.level)?s.from:s.to-1,a),"before"==l&&(a=Ji(n,a,1))}else a=o<0?s.to:s.from;return new et(r,a,l)}}return new et(r,o<0?n.text.length:0,o<0?"before":"after")}zi.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},zi.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},zi.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars","Ctrl-O":"openLine"},zi.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},zi.default=b?zi.macDefault:zi.pcDefault;var ta={selectAll:li,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),V)},killLine:function(e){return Zi(e,(function(t){if(t.empty()){var n=Ge(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line0)o=new et(o.line,o.ch+1),e.replaceRange(i.charAt(o.ch-1)+i.charAt(o.ch-2),et(o.line,o.ch-2),o,"+transpose");else if(o.line>e.doc.first){var a=Ge(e.doc,o.line-1).text;a&&(o=new et(o.line,1),e.replaceRange(i.charAt(0)+e.doc.lineSeparator()+a.charAt(a.length-1),et(o.line-1,a.length-1),o,"+transpose"))}n.push(new ko(o,o))}e.setSelections(n)}))},newlineAndIndent:function(e){return Qr(e,(function(){for(var t=e.listSelections(),n=t.length-1;n>=0;n--)e.replaceRange(e.doc.lineSeparator(),t[n].anchor,t[n].head,"+input");t=e.listSelections();for(var r=0;r-1&&(tt((o=u.ranges[o]).from(),t)<0||t.xRel>0)&&(tt(o.to(),t)>0||t.xRel<0)?function(e,t,n,r){var o=e.display,i=!1,u=eo(e,(function(t){l&&(o.scroller.draggable=!1),e.state.draggingText=!1,e.state.delayingBlurEvent&&(e.hasFocus()?e.state.delayingBlurEvent=!1:Or(e)),pe(o.wrapper.ownerDocument,"mouseup",u),pe(o.wrapper.ownerDocument,"mousemove",c),pe(o.scroller,"dragstart",f),pe(o.scroller,"drop",u),i||(ye(t),r.addNew||Yo(e.doc,n,null,null,r.extend),l&&!d||a&&9==s?setTimeout((function(){o.wrapper.ownerDocument.body.focus({preventScroll:!0}),o.input.focus()}),20):o.input.focus())})),c=function(e){i=i||Math.abs(t.clientX-e.clientX)+Math.abs(t.clientY-e.clientY)>=10},f=function(){return i=!0};l&&(o.scroller.draggable=!0),e.state.draggingText=u,u.copy=!r.moveOnDrag,fe(o.wrapper.ownerDocument,"mouseup",u),fe(o.wrapper.ownerDocument,"mousemove",c),fe(o.scroller,"dragstart",f),fe(o.scroller,"drop",u),e.state.delayingBlurEvent=!0,setTimeout((function(){return o.input.focus()}),20),o.scroller.dragDrop&&o.scroller.dragDrop()}(e,r,t,i):function(e,t,n,r){a&&Or(e);var o=e.display,i=e.doc;ye(t);var s,l,u=i.sel,c=u.ranges;if(r.addNew&&!r.extend?(l=i.sel.contains(n),s=l>-1?c[l]:new ko(n,n)):(s=i.sel.primary(),l=i.sel.primIndex),"rectangle"==r.unit)r.addNew||(s=new ko(n,n)),n=ur(e,t,!0,!0),l=-1;else{var f=va(e,n,r.unit);s=r.extend?$o(s,f.anchor,f.head,r.extend):f}r.addNew?-1==l?(l=c.length,ei(i,So(e,c.concat([s]),l),{scroll:!1,origin:"*mouse"})):c.length>1&&c[l].empty()&&"char"==r.unit&&!r.extend?(ei(i,So(e,c.slice(0,l).concat(c.slice(l+1)),0),{scroll:!1,origin:"*mouse"}),u=i.sel):Zo(i,l,s,z):(l=0,ei(i,new Oo([s],0),z),u=i.sel);var d=n;function p(t){if(0!=tt(d,t))if(d=t,"rectangle"==r.unit){for(var o=[],a=e.options.tabSize,c=I(Ge(i,n.line).text,n.ch,a),f=I(Ge(i,t.line).text,t.ch,a),p=Math.min(c,f),h=Math.max(c,f),m=Math.min(n.line,t.line),g=Math.min(e.lastLine(),Math.max(n.line,t.line));m<=g;m++){var v=Ge(i,m).text,b=W(v,p,a);p==h?o.push(new ko(et(m,b),et(m,b))):v.length>b&&o.push(new ko(et(m,b),et(m,W(v,h,a))))}o.length||o.push(new ko(n,n)),ei(i,So(e,u.ranges.slice(0,l).concat(o),l),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var y,_=s,w=va(e,t,r.unit),x=_.anchor;tt(w.anchor,x)>0?(y=w.head,x=it(_.from(),w.anchor)):(y=w.anchor,x=ot(_.to(),w.head));var O=u.ranges.slice(0);O[l]=function(e,t){var n=t.anchor,r=t.head,o=Ge(e.doc,n.line);if(0==tt(n,r)&&n.sticky==r.sticky)return t;var i=ue(o);if(!i)return t;var a=se(i,n.ch,n.sticky),s=i[a];if(s.from!=n.ch&&s.to!=n.ch)return t;var l,u=a+(s.from==n.ch==(1!=s.level)?0:1);if(0==u||u==i.length)return t;if(r.line!=n.line)l=(r.line-n.line)*("ltr"==e.doc.direction?1:-1)>0;else{var c=se(i,r.ch,r.sticky),f=c-a||(r.ch-n.ch)*(1==s.level?-1:1);l=c==u-1||c==u?f<0:f>0}var d=i[u+(l?-1:0)],p=l==(1==d.level),h=p?d.from:d.to,m=p?"after":"before";return n.ch==h&&n.sticky==m?t:new ko(new et(n.line,h,m),r)}(e,new ko(st(i,x),y)),ei(i,So(e,O,l),z)}}var h=o.wrapper.getBoundingClientRect(),m=0;function g(t){e.state.selectingText=!1,m=1/0,t&&(ye(t),o.input.focus()),pe(o.wrapper.ownerDocument,"mousemove",v),pe(o.wrapper.ownerDocument,"mouseup",b),i.history.lastSelOrigin=null}var v=eo(e,(function(t){0!==t.buttons&&ke(t)?function t(n){var a=++m,s=ur(e,n,!0,"rectangle"==r.unit);if(s)if(0!=tt(s,d)){e.curOp.focus=T(),p(s);var l=Cr(o,i);(s.line>=l.to||s.lineh.bottom?20:0;u&&setTimeout(eo(e,(function(){m==a&&(o.scroller.scrollTop+=u,t(n))})),50)}}(t):g(t)})),b=eo(e,g);e.state.selectingText=b,fe(o.wrapper.ownerDocument,"mousemove",v),fe(o.wrapper.ownerDocument,"mouseup",b)}(e,r,t,i)}(t,r,i,e):Oe(e)==n.scroller&&ye(e):2==o?(r&&Yo(t.doc,r),setTimeout((function(){return n.input.focus()}),20)):3==o&&(O?t.display.input.onContextMenu(e):Or(t)))}}function va(e,t,n){if("char"==n)return new ko(t,t);if("word"==n)return e.findWordAt(t);if("line"==n)return new ko(et(t.line,0),st(e.doc,et(t.line+1,0)));var r=n(e,t);return new ko(r.from,r.to)}function ba(e,t,n,r){var o,i;if(t.touches)o=t.touches[0].clientX,i=t.touches[0].clientY;else try{o=t.clientX,i=t.clientY}catch(e){return!1}if(o>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&ye(t);var a=e.display,s=a.lineDiv.getBoundingClientRect();if(i>s.bottom||!ve(e,n))return we(t);i-=s.top-a.viewOffset;for(var l=0;l=o)return he(e,n,e,Ze(e.doc,i),e.display.gutterSpecs[l].className,t),we(t)}}function ya(e,t){return ba(e,t,"gutterClick",!0)}function _a(e,t){xn(e.display,t)||function(e,t){return!!ve(e,"gutterContextMenu")&&ba(e,t,"gutterContextMenu",!1)}(e,t)||me(e,t,"contextmenu")||O||e.display.input.onContextMenu(t)}function wa(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),Bn(e)}ma.prototype.compare=function(e,t,n){return this.time+400>e&&0==tt(t,this.pos)&&n==this.button};var xa={toString:function(){return"CodeMirror.Init"}},Oa={},ka={};function Sa(e,t,n){if(!t!=!(n&&n!=xa)){var r=e.display.dragFunctions,o=t?fe:pe;o(e.display.scroller,"dragstart",r.start),o(e.display.scroller,"dragenter",r.enter),o(e.display.scroller,"dragover",r.over),o(e.display.scroller,"dragleave",r.leave),o(e.display.scroller,"drop",r.drop)}}function ja(e){e.options.lineWrapping?(P(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(j(e.display.wrapper,"CodeMirror-wrap"),Wt(e)),lr(e),fr(e),Bn(e),setTimeout((function(){return Ur(e)}),100)}function Ea(e,t){var n=this;if(!(this instanceof Ea))return new Ea(e,t);this.options=t=t?R(t):{},R(Oa,t,!1);var r=t.value;"string"==typeof r?r=new qi(r,t.mode,null,t.lineSeparator,t.direction):t.mode&&(r.modeOption=t.mode),this.doc=r;var o=new Ea.inputStyles[t.inputStyle](this),i=this.display=new vo(e,r,o,t);for(var u in i.wrapper.CodeMirror=this,wa(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),Hr(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:-1,cutIncoming:-1,selectingText:!1,draggingText:!1,highlight:new F,keySeq:null,specialChars:null},t.autofocus&&!v&&i.input.focus(),a&&s<11&&setTimeout((function(){return n.display.input.reset(!0)}),20),function(e){var t=e.display;fe(t.scroller,"mousedown",eo(e,ga)),fe(t.scroller,"dblclick",a&&s<11?eo(e,(function(t){if(!me(e,t)){var n=ur(e,t);if(n&&!ya(e,t)&&!xn(e.display,t)){ye(t);var r=e.findWordAt(n);Yo(e.doc,r.anchor,r.head)}}})):function(t){return me(e,t)||ye(t)}),fe(t.scroller,"contextmenu",(function(t){return _a(e,t)})),fe(t.input.getField(),"contextmenu",(function(n){t.scroller.contains(n.target)||_a(e,n)}));var n,r={end:0};function o(){t.activeTouch&&(n=setTimeout((function(){return t.activeTouch=null}),1e3),(r=t.activeTouch).end=+new Date)}function i(e,t){if(null==t.left)return!0;var n=t.left-e.left,r=t.top-e.top;return n*n+r*r>400}fe(t.scroller,"touchstart",(function(o){if(!me(e,o)&&!function(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}(o)&&!ya(e,o)){t.input.ensurePolled(),clearTimeout(n);var i=+new Date;t.activeTouch={start:i,moved:!1,prev:i-r.end<=300?r:null},1==o.touches.length&&(t.activeTouch.left=o.touches[0].pageX,t.activeTouch.top=o.touches[0].pageY)}})),fe(t.scroller,"touchmove",(function(){t.activeTouch&&(t.activeTouch.moved=!0)})),fe(t.scroller,"touchend",(function(n){var r=t.activeTouch;if(r&&!xn(t,n)&&null!=r.left&&!r.moved&&new Date-r.start<300){var a,s=e.coordsChar(t.activeTouch,"page");a=!r.prev||i(r,r.prev)?new ko(s,s):!r.prev.prev||i(r,r.prev.prev)?e.findWordAt(s):new ko(et(s.line,0),st(e.doc,et(s.line+1,0))),e.setSelection(a.anchor,a.head),e.focus(),ye(n)}o()})),fe(t.scroller,"touchcancel",o),fe(t.scroller,"scroll",(function(){t.scroller.clientHeight&&(Lr(e,t.scroller.scrollTop),Rr(e,t.scroller.scrollLeft,!0),he(e,"scroll",e))})),fe(t.scroller,"mousewheel",(function(t){return xo(e,t)})),fe(t.scroller,"DOMMouseScroll",(function(t){return xo(e,t)})),fe(t.wrapper,"scroll",(function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0})),t.dragFunctions={enter:function(t){me(e,t)||xe(t)},over:function(t){me(e,t)||(function(e,t){var n=ur(e,t);if(n){var r=document.createDocumentFragment();br(e,n,r),e.display.dragCursor||(e.display.dragCursor=N("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),e.display.lineSpace.insertBefore(e.display.dragCursor,e.display.cursorDiv)),C(e.display.dragCursor,r)}}(e,t),xe(t))},start:function(t){return function(e,t){if(a&&(!e.state.draggingText||+new Date-Ti<100))xe(t);else if(!me(e,t)&&!xn(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.effectAllowed="copyMove",t.dataTransfer.setDragImage&&!d)){var n=N("img",null,null,"position: fixed; left: 0; top: 0;");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",f&&(n.width=n.height=1,e.display.wrapper.appendChild(n),n._top=n.offsetTop),t.dataTransfer.setDragImage(n,0,0),f&&n.parentNode.removeChild(n)}}(e,t)},drop:eo(e,Pi),leave:function(t){me(e,t)||Mi(e)}};var l=t.input.getField();fe(l,"keyup",(function(t){return fa.call(e,t)})),fe(l,"keydown",eo(e,ca)),fe(l,"keypress",eo(e,da)),fe(l,"focus",(function(t){return kr(e,t)})),fe(l,"blur",(function(t){return Sr(e,t)}))}(this),Ri(),Gr(this),this.curOp.forceUpdate=!0,Do(this,r),t.autofocus&&!v||this.hasFocus()?setTimeout((function(){n.hasFocus()&&!n.state.focused&&kr(n)}),20):Sr(this),ka)ka.hasOwnProperty(u)&&ka[u](this,t[u],xa);po(this),t.finishInit&&t.finishInit(this);for(var c=0;c150)){if(!r)return;n="prev"}}else u=0,n="not";"prev"==n?u=t>i.first?I(Ge(i,t-1).text,null,a):0:"add"==n?u=l+e.options.indentUnit:"subtract"==n?u=l-e.options.indentUnit:"number"==typeof n&&(u=l+n),u=Math.max(0,u);var f="",d=0;if(e.options.indentWithTabs)for(var p=Math.floor(u/a);p;--p)d+=a,f+="\t";if(da,l=qe(t),u=null;if(s&&r.ranges.length>1)if(Aa&&Aa.text.join("\n")==t){if(r.ranges.length%Aa.text.length==0){u=[];for(var c=0;c=0;d--){var p=r.ranges[d],h=p.from(),m=p.to();p.empty()&&(n&&n>0?h=et(h.line,h.ch-n):e.state.overwrite&&!s?m=et(m.line,Math.min(Ge(i,m.line).text.length,m.ch+$(l).length)):s&&Aa&&Aa.lineWise&&Aa.text.join("\n")==l.join("\n")&&(h=m=et(h.line,0)));var g={from:h,to:m,text:u?u[d%u.length]:l,origin:o||(s?"paste":e.state.cutIncoming>a?"cut":"+input")};ci(e.doc,g),ln(e,"inputRead",e,g)}t&&!s&&Ma(e,t),qr(e),e.curOp.updateInput<2&&(e.curOp.updateInput=f),e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=-1}function Pa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");if(n)return e.preventDefault(),t.isReadOnly()||t.options.disableInput||Qr(t,(function(){return Ta(t,n,0,null,"paste")})),!0}function Ma(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var o=n.ranges[r];if(!(o.head.ch>100||r&&n.ranges[r-1].head.line==o.head.line)){var i=e.getModeAt(o.head),a=!1;if(i.electricChars){for(var s=0;s-1){a=Na(e,o.head.line,"smart");break}}else i.electricInput&&i.electricInput.test(Ge(e.doc,o.head.line).text.slice(0,o.head.ch))&&(a=Na(e,o.head.line,"smart"));a&&ln(e,"electricInput",e,o.head.line)}}}function La(e){for(var t=[],n=[],r=0;r0?0:-1));if(isNaN(c))a=null;else{var f=n>0?c>=55296&&c<56320:c>=56320&&c<57343;a=new et(t.line,Math.max(0,Math.min(s.text.length,t.ch+n*(f?2:1))),-n)}}else a=o?function(e,t,n,r){var o=ue(t,e.doc.direction);if(!o)return Qi(t,n,r);n.ch>=t.text.length?(n.ch=t.text.length,n.sticky="before"):n.ch<=0&&(n.ch=0,n.sticky="after");var i=se(o,n.ch,n.sticky),a=o[i];if("ltr"==e.doc.direction&&a.level%2==0&&(r>0?a.to>n.ch:a.from=a.from&&d>=c.begin)){var p=f?"before":"after";return new et(n.line,d,p)}}var h=function(e,t,r){for(var i=function(e,t){return t?new et(n.line,l(e,1),"before"):new et(n.line,e,"after")};e>=0&&e0==(1!=a.level),u=s?r.begin:l(r.end,-1);if(a.from<=u&&u0?c.end:l(c.begin,-1);return null==g||r>0&&g==t.text.length||!(m=h(r>0?0:o.length-1,r,u(g)))?null:m}(e.cm,s,t,n):Qi(s,t,n);if(null==a){if(i||(u=t.line+l)=e.first+e.size||(t=new et(u,t.ch,t.sticky),!(s=Ge(e,u))))return!1;t=ea(o,e.cm,s,t.line,l)}else t=a;return!0}if("char"==r||"codepoint"==r)u();else if("column"==r)u(!0);else if("word"==r||"group"==r)for(var c=null,f="group"==r,d=e.cm&&e.cm.getHelper(t,"wordChars"),p=!0;!(n<0)||u(!p);p=!1){var h=s.text.charAt(t.ch)||"\n",m=ee(h,d)?"w":f&&"\n"==h?"n":!f||/\s/.test(h)?null:"p";if(!f||p||m||(m="s"),c&&c!=m){n<0&&(n=1,u(),t.sticky="after");break}if(m&&(c=m),n>0&&!u(!p))break}var g=ai(e,t,i,a,!0);return nt(i,g)&&(g.hitSide=!0),g}function Fa(e,t,n,r){var o,i,a=e.doc,s=t.left;if("page"==r){var l=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight),u=Math.max(l-.5*rr(e.display),3);o=(n>0?t.bottom:t.top)+n*u}else"line"==r&&(o=n>0?t.bottom+3:t.top-3);for(;(i=Xn(e,s,o)).outside;){if(n<0?o<=0:o>=a.height){i.hitSide=!0;break}o+=5*n}return i}var Ba=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new F,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};function Ua(e,t){var n=qn(e,t.line);if(!n||n.hidden)return null;var r=Ge(e.doc,t.line),o=Nn(n,r,t.line),i=ue(r,e.doc.direction),a="left";i&&(a=se(i,t.ch)%2?"right":"left");var s=Dn(o.map,t.ch,a);return s.offset="right"==s.collapse?s.end:s.start,s}function Va(e,t){return t&&(e.bad=!0),e}function za(e,t,n){var r;if(t==e.display.lineDiv){if(!(r=e.display.lineDiv.childNodes[n]))return Va(e.clipPos(et(e.display.viewTo-1)),!0);t=null,n=0}else for(r=t;;r=r.parentNode){if(!r||r==e.display.lineDiv)return null;if(r.parentNode&&r.parentNode==e.display.lineDiv)break}for(var o=0;o=t.display.viewTo||i.line=t.display.viewFrom&&Ua(t,o)||{node:l[0].measure.map[2],offset:0},c=i.liner.firstLine()&&(a=et(a.line-1,Ge(r.doc,a.line-1).length)),s.ch==Ge(r.doc,s.line).text.length&&s.lineo.viewTo-1)return!1;a.line==o.viewFrom||0==(e=cr(r,a.line))?(t=Xe(o.view[0].line),n=o.view[0].node):(t=Xe(o.view[e].line),n=o.view[e-1].node.nextSibling);var l,u,c=cr(r,s.line);if(c==o.view.length-1?(l=o.viewTo-1,u=o.lineDiv.lastChild):(l=Xe(o.view[c+1].line)-1,u=o.view[c+1].node.previousSibling),!n)return!1;for(var f=r.doc.splitLines(function(e,t,n,r,o){var i="",a=!1,s=e.doc.lineSeparator(),l=!1;function u(){a&&(i+=s,l&&(i+=s),a=l=!1)}function c(e){e&&(u(),i+=e)}function f(t){if(1==t.nodeType){var n=t.getAttribute("cm-text");if(n)return void c(n);var i,d=t.getAttribute("cm-marker");if(d){var p=e.findMarks(et(r,0),et(o+1,0),(g=+d,function(e){return e.id==g}));return void(p.length&&(i=p[0].find(0))&&c(Ke(e.doc,i.from,i.to).join(s)))}if("false"==t.getAttribute("contenteditable"))return;var h=/^(pre|div|p|li|table|br)$/i.test(t.nodeName);if(!/^br$/i.test(t.nodeName)&&0==t.textContent.length)return;h&&u();for(var m=0;m1&&d.length>1;)if($(f)==$(d))f.pop(),d.pop(),l--;else{if(f[0]!=d[0])break;f.shift(),d.shift(),t++}for(var p=0,h=0,m=f[0],g=d[0],v=Math.min(m.length,g.length);pa.ch&&b.charCodeAt(b.length-h-1)==y.charCodeAt(y.length-h-1);)p--,h++;f[f.length-1]=b.slice(0,b.length-h).replace(/^\u200b+/,""),f[0]=f[0].slice(p).replace(/\u200b+$/,"");var w=et(t,p),x=et(l,d.length?$(d).length-h:0);return f.length>1||f[0]||tt(w,x)?(mi(r.doc,f,w,x,"+input"),!0):void 0},Ba.prototype.ensurePolled=function(){this.forceCompositionEnd()},Ba.prototype.reset=function(){this.forceCompositionEnd()},Ba.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},Ba.prototype.readFromDOMSoon=function(){var e=this;null==this.readDOMTimeout&&(this.readDOMTimeout=setTimeout((function(){if(e.readDOMTimeout=null,e.composing){if(!e.composing.done)return;e.composing=null}e.updateFromDOM()}),80))},Ba.prototype.updateFromDOM=function(){var e=this;!this.cm.isReadOnly()&&this.pollContent()||Qr(this.cm,(function(){return fr(e.cm)}))},Ba.prototype.setUneditable=function(e){e.contentEditable="false"},Ba.prototype.onKeyPress=function(e){0==e.charCode||this.composing||(e.preventDefault(),this.cm.isReadOnly()||eo(this.cm,Ta)(this.cm,String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),0))},Ba.prototype.readOnlyChanged=function(e){this.div.contentEditable=String("nocursor"!=e)},Ba.prototype.onContextMenu=function(){},Ba.prototype.resetPosition=function(){},Ba.prototype.needsContentAttribute=!0;var Wa=function(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new F,this.hasSelection=!1,this.composing=null};Wa.prototype.init=function(e){var t=this,n=this,r=this.cm;this.createField(e);var o=this.textarea;function i(e){if(!me(r,e)){if(r.somethingSelected())qa({lineWise:!1,text:r.getSelections()});else{if(!r.options.lineWiseCopyCut)return;var t=La(r);qa({lineWise:!0,text:t.text}),"cut"==e.type?r.setSelections(t.ranges,null,V):(n.prevInput="",o.value=t.text.join("\n"),L(o))}"cut"==e.type&&(r.state.cutIncoming=+new Date)}}e.wrapper.insertBefore(this.wrapper,e.wrapper.firstChild),m&&(o.style.width="0px"),fe(o,"input",(function(){a&&s>=9&&t.hasSelection&&(t.hasSelection=null),n.poll()})),fe(o,"paste",(function(e){me(r,e)||Pa(e,r)||(r.state.pasteIncoming=+new Date,n.fastPoll())})),fe(o,"cut",i),fe(o,"copy",i),fe(e.scroller,"paste",(function(t){if(!xn(e,t)&&!me(r,t)){if(!o.dispatchEvent)return r.state.pasteIncoming=+new Date,void n.focus();var i=new Event("paste");i.clipboardData=t.clipboardData,o.dispatchEvent(i)}})),fe(e.lineSpace,"selectstart",(function(t){xn(e,t)||ye(t)})),fe(o,"compositionstart",(function(){var e=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:e,range:r.markText(e,r.getCursor("to"),{className:"CodeMirror-composing"})}})),fe(o,"compositionend",(function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)}))},Wa.prototype.createField=function(e){this.wrapper=Ra(),this.textarea=this.wrapper.firstChild},Wa.prototype.screenReaderLabelChanged=function(e){e?this.textarea.setAttribute("aria-label",e):this.textarea.removeAttribute("aria-label")},Wa.prototype.prepareSelection=function(){var e=this.cm,t=e.display,n=e.doc,r=vr(e);if(e.options.moveInputWithCursor){var o=Kn(e,n.sel.primary().head,"div"),i=t.wrapper.getBoundingClientRect(),a=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,o.top+a.top-i.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,o.left+a.left-i.left))}return r},Wa.prototype.showSelection=function(e){var t=this.cm.display;C(t.cursorDiv,e.cursors),C(t.selectionDiv,e.selection),null!=e.teTop&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},Wa.prototype.reset=function(e){if(!this.contextMenuPending&&!this.composing){var t=this.cm;if(t.somethingSelected()){this.prevInput="";var n=t.getSelection();this.textarea.value=n,t.state.focused&&L(this.textarea),a&&s>=9&&(this.hasSelection=n)}else e||(this.prevInput=this.textarea.value="",a&&s>=9&&(this.hasSelection=null))}},Wa.prototype.getField=function(){return this.textarea},Wa.prototype.supportsTouch=function(){return!1},Wa.prototype.focus=function(){if("nocursor"!=this.cm.options.readOnly&&(!v||T()!=this.textarea))try{this.textarea.focus()}catch(e){}},Wa.prototype.blur=function(){this.textarea.blur()},Wa.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},Wa.prototype.receivedFocus=function(){this.slowPoll()},Wa.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,(function(){e.poll(),e.cm.state.focused&&e.slowPoll()}))},Wa.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0,t.polling.set(20,(function n(){t.poll()||e?(t.pollingFast=!1,t.slowPoll()):(e=!0,t.polling.set(60,n))}))},Wa.prototype.poll=function(){var e=this,t=this.cm,n=this.textarea,r=this.prevInput;if(this.contextMenuPending||!t.state.focused||Te(n)&&!r&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var o=n.value;if(o==r&&!t.somethingSelected())return!1;if(a&&s>=9&&this.hasSelection===o||b&&/[\uf700-\uf7ff]/.test(o))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var i=o.charCodeAt(0);if(8203!=i||r||(r="โ€‹"),8666==i)return this.reset(),this.cm.execCommand("undo")}for(var l=0,u=Math.min(r.length,o.length);l1e3||o.indexOf("\n")>-1?n.value=e.prevInput="":e.prevInput=o,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))})),!0},Wa.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},Wa.prototype.onKeyPress=function(){a&&s>=9&&(this.hasSelection=null),this.fastPoll()},Wa.prototype.onContextMenu=function(e){var t=this,n=t.cm,r=n.display,o=t.textarea;t.contextMenuPending&&t.contextMenuPending();var i=ur(n,e),u=r.scroller.scrollTop;if(i&&!f){n.options.resetSelectionOnContextMenu&&-1==n.doc.sel.contains(i)&&eo(n,ei)(n.doc,jo(i),V);var c,d=o.style.cssText,p=t.wrapper.style.cssText,h=t.wrapper.offsetParent.getBoundingClientRect();if(t.wrapper.style.cssText="position: static",o.style.cssText="position: absolute; width: 30px; height: 30px;\n top: "+(e.clientY-h.top-5)+"px; left: "+(e.clientX-h.left-5)+"px;\n z-index: 1000; background: "+(a?"rgba(255, 255, 255, .05)":"transparent")+";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",l&&(c=window.scrollY),r.input.focus(),l&&window.scrollTo(null,c),r.input.reset(),n.somethingSelected()||(o.value=t.prevInput=" "),t.contextMenuPending=v,r.selForContextMenu=n.doc.sel,clearTimeout(r.detectingSelectAll),a&&s>=9&&g(),O){xe(e);var m=function(){pe(window,"mouseup",m),setTimeout(v,20)};fe(window,"mouseup",m)}else setTimeout(v,50)}function g(){if(null!=o.selectionStart){var e=n.somethingSelected(),i="โ€‹"+(e?o.value:"");o.value="โ‡š",o.value=i,t.prevInput=e?"":"โ€‹",o.selectionStart=1,o.selectionEnd=i.length,r.selForContextMenu=n.doc.sel}}function v(){if(t.contextMenuPending==v&&(t.contextMenuPending=!1,t.wrapper.style.cssText=p,o.style.cssText=d,a&&s<9&&r.scrollbars.setScrollTop(r.scroller.scrollTop=u),null!=o.selectionStart)){(!a||a&&s<9)&&g();var e=0,i=function(){r.selForContextMenu==n.doc.sel&&0==o.selectionStart&&o.selectionEnd>0&&"โ€‹"==t.prevInput?eo(n,li)(n):e++<10?r.detectingSelectAll=setTimeout(i,500):(r.selForContextMenu=null,r.input.reset())};r.detectingSelectAll=setTimeout(i,200)}}},Wa.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled="nocursor"==e,this.textarea.readOnly=!!e},Wa.prototype.setUneditable=function(){},Wa.prototype.needsContentAttribute=!1,function(e){var t=e.optionHandlers;function n(n,r,o,i){e.defaults[n]=r,o&&(t[n]=i?function(e,t,n){n!=xa&&o(e,t,n)}:o)}e.defineOption=n,e.Init=xa,n("value","",(function(e,t){return e.setValue(t)}),!0),n("mode",null,(function(e,t){e.doc.modeOption=t,qo(e)}),!0),n("indentUnit",2,qo,!0),n("indentWithTabs",!1),n("smartIndent",!0),n("tabSize",4,(function(e){To(e),Bn(e),fr(e)}),!0),n("lineSeparator",null,(function(e,t){if(e.doc.lineSep=t,t){var n=[],r=e.doc.first;e.doc.iter((function(e){for(var o=0;;){var i=e.text.indexOf(t,o);if(-1==i)break;o=i+t.length,n.push(et(r,i))}r++}));for(var o=n.length-1;o>=0;o--)mi(e.doc,t,n[o],et(n[o].line,n[o].ch+t.length))}})),n("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g,(function(e,t,n){e.state.specialChars=new RegExp(t.source+(t.test("\t")?"":"|\t"),"g"),n!=xa&&e.refresh()})),n("specialCharPlaceholder",Jt,(function(e){return e.refresh()}),!0),n("electricChars",!0),n("inputStyle",v?"contenteditable":"textarea",(function(){throw new Error("inputStyle can not (yet) be changed in a running editor")}),!0),n("spellcheck",!1,(function(e,t){return e.getInputField().spellcheck=t}),!0),n("autocorrect",!1,(function(e,t){return e.getInputField().autocorrect=t}),!0),n("autocapitalize",!1,(function(e,t){return e.getInputField().autocapitalize=t}),!0),n("rtlMoveVisually",!_),n("wholeLineUpdateBefore",!0),n("theme","default",(function(e){wa(e),go(e)}),!0),n("keyMap","default",(function(e,t,n){var r=Xi(t),o=n!=xa&&Xi(n);o&&o.detach&&o.detach(e,r),r.attach&&r.attach(e,o||null)})),n("extraKeys",null),n("configureMouse",null),n("lineWrapping",!1,ja,!0),n("gutters",[],(function(e,t){e.display.gutterSpecs=ho(t,e.options.lineNumbers),go(e)}),!0),n("fixedGutter",!0,(function(e,t){e.display.gutters.style.left=t?ar(e.display)+"px":"0",e.refresh()}),!0),n("coverGutterNextToScrollbar",!1,(function(e){return Ur(e)}),!0),n("scrollbarStyle","native",(function(e){Hr(e),Ur(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)}),!0),n("lineNumbers",!1,(function(e,t){e.display.gutterSpecs=ho(e.options.gutters,t),go(e)}),!0),n("firstLineNumber",1,go,!0),n("lineNumberFormatter",(function(e){return e}),go,!0),n("showCursorWhenSelecting",!1,gr,!0),n("resetSelectionOnContextMenu",!0),n("lineWiseCopyCut",!0),n("pasteLinesPerSelection",!0),n("selectionsMayTouch",!1),n("readOnly",!1,(function(e,t){"nocursor"==t&&(Sr(e),e.display.input.blur()),e.display.input.readOnlyChanged(t)})),n("screenReaderLabel",null,(function(e,t){t=""===t?null:t,e.display.input.screenReaderLabelChanged(t)})),n("disableInput",!1,(function(e,t){t||e.display.input.reset()}),!0),n("dragDrop",!0,Sa),n("allowDropFileTypes",null),n("cursorBlinkRate",530),n("cursorScrollMargin",0),n("cursorHeight",1,gr,!0),n("singleCursorHeightPerLine",!0,gr,!0),n("workTime",100),n("workDelay",100),n("flattenSpans",!0,To,!0),n("addModeClass",!1,To,!0),n("pollInterval",100),n("undoDepth",200,(function(e,t){return e.doc.history.undoDepth=t})),n("historyEventDelay",1250),n("viewportMargin",10,(function(e){return e.refresh()}),!0),n("maxHighlightLength",1e4,To,!0),n("moveInputWithCursor",!0,(function(e,t){t||e.display.input.resetPosition()})),n("tabindex",null,(function(e,t){return e.display.input.getField().tabIndex=t||""})),n("autofocus",null),n("direction","ltr",(function(e,t){return e.doc.setDirection(t)}),!0),n("phrases",null)}(Ea),function(e){var t=e.optionHandlers,n=e.helpers={};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,n){var r=this.options,o=r[e];r[e]==n&&"mode"!=e||(r[e]=n,t.hasOwnProperty(e)&&eo(this,t[e])(this,n,o),he(this,"optionChange",this,e))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"](Xi(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,n=0;nn&&(Na(this,o.head.line,e,!0),n=o.head.line,r==this.doc.sel.primIndex&&qr(this));else{var i=o.from(),a=o.to(),s=Math.max(n,i.line);n=Math.min(this.lastLine(),a.line-(a.ch?0:1))+1;for(var l=s;l0&&Zo(this.doc,r,new ko(i,u[r].to()),V)}}})),getTokenAt:function(e,t){return bt(this,e,t)},getLineTokens:function(e,t){return bt(this,et(e),t,!0)},getTokenTypeAt:function(e){e=st(this.doc,e);var t,n=dt(this,Ge(this.doc,e.line)),r=0,o=(n.length-1)/2,i=e.ch;if(0==i)t=n[2];else for(;;){var a=r+o>>1;if((a?n[2*a-1]:0)>=i)o=a;else{if(!(n[2*a+1]i&&(e=i,o=!0),r=Ge(this.doc,e)}else r=e;return Hn(this,r,{top:0,left:0},t||"page",n||o).top+(o?this.doc.height-zt(r):0)},defaultTextHeight:function(){return rr(this.display)},defaultCharWidth:function(){return or(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(e,t,n,r,o){var i,a,s,l=this.display,u=(e=Kn(this,st(this.doc,e))).bottom,c=e.left;if(t.style.position="absolute",t.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(t),l.sizer.appendChild(t),"over"==r)u=e.top;else if("above"==r||"near"==r){var f=Math.max(l.wrapper.clientHeight,this.doc.height),d=Math.max(l.sizer.clientWidth,l.lineSpace.clientWidth);("above"==r||e.bottom+t.offsetHeight>f)&&e.top>t.offsetHeight?u=e.top-t.offsetHeight:e.bottom+t.offsetHeight<=f&&(u=e.bottom),c+t.offsetWidth>d&&(c=d-t.offsetWidth)}t.style.top=u+"px",t.style.left=t.style.right="","right"==o?(c=l.sizer.clientWidth-t.offsetWidth,t.style.right="0px"):("left"==o?c=0:"middle"==o&&(c=(l.sizer.clientWidth-t.offsetWidth)/2),t.style.left=c+"px"),n&&(i=this,a={left:c,top:u,right:c+t.offsetWidth,bottom:u+t.offsetHeight},null!=(s=Nr(i,a)).scrollTop&&Lr(i,s.scrollTop),null!=s.scrollLeft&&Rr(i,s.scrollLeft))},triggerOnKeyDown:to(ca),triggerOnKeyPress:to(da),triggerOnKeyUp:fa,triggerOnMouseDown:to(ga),execCommand:function(e){if(ta.hasOwnProperty(e))return ta[e].call(null,this)},triggerElectric:to((function(e){Ma(this,e)})),findPosH:function(e,t,n,r){var o=1;t<0&&(o=-1,t=-t);for(var i=st(this.doc,e),a=0;a0&&a(t.charAt(n-1));)--n;for(;r.5||this.options.lineWrapping)&&lr(this),he(this,"refresh",this)})),swapDoc:to((function(e){var t=this.doc;return t.cm=null,this.state.selectingText&&this.state.selectingText(),Do(this,e),Bn(this),this.display.input.reset(),Tr(this,e.scrollLeft,e.scrollTop),this.curOp.forceScroll=!0,ln(this,"swapDoc",this,t),t})),phrase:function(e){var t=this.options.phrases;return t&&Object.prototype.hasOwnProperty.call(t,e)?t[e]:e},getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},be(e),e.registerHelper=function(t,r,o){n.hasOwnProperty(t)||(n[t]=e[t]={_global:[]}),n[t][r]=o},e.registerGlobalHelper=function(t,r,o,i){e.registerHelper(t,r,i),n[t]._global.push({pred:o,val:i})}}(Ea);var Ga="iter insert remove copy getEditor constructor".split(" ");for(var Ka in qi.prototype)qi.prototype.hasOwnProperty(Ka)&&B(Ga,Ka)<0&&(Ea.prototype[Ka]=function(e){return function(){return e.apply(this.doc,arguments)}}(qi.prototype[Ka]));return be(qi),Ea.inputStyles={textarea:Wa,contenteditable:Ba},Ea.defineMode=function(e){Ea.defaults.mode||"null"==e||(Ea.defaults.mode=e),Re.apply(this,arguments)},Ea.defineMIME=function(e,t){De[e]=t},Ea.defineMode("null",(function(){return{token:function(e){return e.skipToEnd()}}})),Ea.defineMIME("text/plain","null"),Ea.defineExtension=function(e,t){Ea.prototype[e]=t},Ea.defineDocExtension=function(e,t){qi.prototype[e]=t},Ea.fromTextArea=function(e,t){if((t=t?R(t):{}).value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),null==t.autofocus){var n=T();t.autofocus=n==e||null!=e.getAttribute("autofocus")&&n==document.body}function r(){e.value=s.getValue()}var o;if(e.form&&(fe(e.form,"submit",r),!t.leaveSubmitMethodAlone)){var i=e.form;o=i.submit;try{var a=i.submit=function(){r(),i.submit=o,i.submit(),i.submit=a}}catch(e){}}t.finishInit=function(n){n.save=r,n.getTextArea=function(){return e},n.toTextArea=function(){n.toTextArea=isNaN,r(),e.parentNode.removeChild(n.getWrapperElement()),e.style.display="",e.form&&(pe(e.form,"submit",r),t.leaveSubmitMethodAlone||"function"!=typeof e.form.submit||(e.form.submit=o))}},e.style.display="none";var s=Ea((function(t){return e.parentNode.insertBefore(t,e.nextSibling)}),t);return s},function(e){e.off=pe,e.on=fe,e.wheelEventPixels=wo,e.Doc=qi,e.splitLines=qe,e.countColumn=I,e.findColumn=W,e.isWordChar=Q,e.Pass=U,e.signal=he,e.Line=Gt,e.changeEnd=Eo,e.scrollbarModel=zr,e.Pos=et,e.cmpPos=tt,e.modes=Le,e.mimeModes=De,e.resolveMode=Ie,e.getMode=Fe,e.modeExtensions=Be,e.extendMode=Ue,e.copyState=Ve,e.startState=He,e.innerMode=ze,e.commands=ta,e.keyMap=zi,e.keyName=Yi,e.isModifierKey=Ki,e.lookupKey=Gi,e.normalizeKeyMap=Wi,e.StringStream=We,e.SharedTextMarker=Ei,e.TextMarker=Si,e.LineWidget=xi,e.e_preventDefault=ye,e.e_stopPropagation=_e,e.e_stop=xe,e.addClass=P,e.contains=q,e.rmClass=j,e.keyNames=Fi}(Ea),Ea.version="5.62.0",Ea}()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=Object.assign||function(e){for(var t=1;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(this.props,[]);return function(e){c.forEach((function(t){return delete e[t]}))}(o),o.className=this.props.inputClassName,o.id=this.state.inputId,o.style=n,a.default.createElement("div",{className:this.props.className,style:t},this.renderStyles(),a.default.createElement("input",r({},o,{ref:this.inputRef})),a.default.createElement("div",{ref:this.sizerRef,style:u},e),this.props.placeholder?a.default.createElement("div",{ref:this.placeHolderSizerRef,style:u},this.props.placeholder):null)}}]),t}(i.Component);h.propTypes={className:s.default.string,defaultValue:s.default.any,extraWidth:s.default.oneOfType([s.default.number,s.default.string]),id:s.default.string,injectStyles:s.default.bool,inputClassName:s.default.string,inputRef:s.default.func,inputStyle:s.default.object,minWidth:s.default.oneOfType([s.default.number,s.default.string]),onAutosize:s.default.func,onChange:s.default.func,placeholder:s.default.string,placeholderIsMinWidth:s.default.bool,style:s.default.object,value:s.default.any},h.defaultProps={minWidth:1,injectStyles:!0},t.default=h},function(e,t,n){"use strict";var r=n(33),o=n(7),i=(n(27),n(34),function(e,t){return Object(o.c)(function(e,t){var n=-1,r=44;do{switch(Object(o.o)(r)){case 0:38===r&&12===Object(o.i)()&&(t[n]=1),e[n]+=Object(o.f)(o.j-1);break;case 2:e[n]+=Object(o.d)(r);break;case 4:if(44===r){e[++n]=58===Object(o.i)()?"&\f":"",t[n]=e[n].length;break}default:e[n]+=Object(o.e)(r)}}while(r=Object(o.h)());return e}(Object(o.a)(e),t))}),a=new WeakMap,s=function(e){if("rule"===e.type&&e.parent&&e.length){for(var t=e.value,n=e.parent,r=e.column===n.column&&e.line===n.line;"rule"!==n.type;)if(!(n=n.parent))return;if((1!==e.props.length||58===t.charCodeAt(0)||a.get(n))&&!r){a.set(e,!0);for(var o=[],s=i(t,o),l=n.props,u=0,c=0;ue.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?n-1:0),o=1;oc))return!1;var d=l.get(e),p=l.get(t);if(d&&p)return d==t&&p==e;var h=-1,m=!0,g=2&n?new r:void 0;for(l.set(e,t),l.set(t,e);++h-1&&e%1==0&&e<=9007199254740991}},,,function(e,t){!function(){e.exports=this.wp.plugins}()},function(e,t,n){"use strict";(function(e){function r(){return(r=Object.assign||function(e){for(var t=1;t1;)if(t(n.date(r)))return!1;return!0}},{key:"getMonthText",value:function(e){var t,n=this.props.viewDate;return(t=n.localeData().monthsShort(n.month(e)).substring(0,3)).charAt(0).toUpperCase()+t.slice(1)}}])&&O(t.prototype,n),o}(l.a.Component);function A(e,t){return t<4?e[0]:t<8?e[1]:e[2]}function q(e){return(q="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function T(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function P(e,t){for(var n=0;n1;)if(n(r.dayOfYear(o)))return t[e]=!1,!1;return t[e]=!0,!0}}])&&P(t.prototype,n),o}(l.a.Component);function B(e,t){return t<3?e[0]:t<7?e[1]:e[2]}function U(e){return(U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function V(e,t){for(var n=0;n=12?e-=12:e+=12,this.props.setTime("hours",e)}},{key:"increase",value:function(e){var t=this.constraints[e],n=parseInt(this.state[e],10)+t.step;return n>t.max&&(n=t.min+(n-(t.max+1))),Z(e,n)}},{key:"decrease",value:function(e){var t=this.constraints[e],n=parseInt(this.state[e],10)-t.step;return n0?r.props.onNavigateForward(e,t):r.props.onNavigateBack(-e,t),r.setState({viewDate:n})})),be(ge(r),"_setTime",(function(e,t){var n=(r.getSelectedDate()||r.state.viewDate).clone();n[e](t),r.props.value||r.setState({selectedDate:n,viewDate:n.clone(),inputValue:n.format(r.getFormat("datetime"))}),r.props.onChange(n)})),be(ge(r),"_openCalendar",(function(){r.isOpen()||r.setState({open:!0},r.props.onOpen)})),be(ge(r),"_closeCalendar",(function(){r.isOpen()&&r.setState({open:!1},(function(){r.props.onClose(r.state.selectedDate||r.state.inputValue)}))})),be(ge(r),"_handleClickOutside",(function(){var e=r.props;e.input&&r.state.open&&void 0===e.open&&e.closeOnClickOutside&&r._closeCalendar()})),be(ge(r),"_onInputFocus",(function(e){r.callHandler(r.props.inputProps.onFocus,e)&&r._openCalendar()})),be(ge(r),"_onInputChange",(function(e){if(r.callHandler(r.props.inputProps.onChange,e)){var t=e.target?e.target.value:e,n=r.localMoment(t,r.getFormat("datetime")),o={inputValue:t};n.isValid()?(o.selectedDate=n,o.viewDate=n.clone().startOf("month")):o.selectedDate=null,r.setState(o,(function(){r.props.onChange(n.isValid()?n:r.state.inputValue)}))}})),be(ge(r),"_onInputKeyDown",(function(e){r.callHandler(r.props.inputProps.onKeyDown,e)&&9===e.which&&r.props.closeOnTab&&r._closeCalendar()})),be(ge(r),"_onInputClick",(function(e){r.callHandler(r.props.inputProps.onClick,e)&&r._openCalendar()})),r.state=r.getInitialState(),r}return de(n,[{key:"render",value:function(){return l.a.createElement(Ee,{className:this.getClassName(),onClickOut:this._handleClickOutside},this.renderInput(),l.a.createElement("div",{className:"rdtPicker"},this.renderView()))}},{key:"renderInput",value:function(){if(this.props.input){var e=ue(ue({type:"text",className:"form-control",value:this.getInputValue()},this.props.inputProps),{},{onFocus:this._onInputFocus,onChange:this._onInputChange,onKeyDown:this._onInputKeyDown,onClick:this._onInputClick});return this.props.renderInput?l.a.createElement("div",null,this.props.renderInput(e,this._openCalendar,this._closeCalendar)):l.a.createElement("input",e)}}},{key:"renderView",value:function(){return this.props.renderView(this.state.currentView,this._renderCalendar)}},{key:"getInitialState",value:function(){var e=this.props,t=this.getFormat("datetime"),n=this.parseDate(e.value||e.initialValue,t);return this.checkTZ(),{open:!e.input,currentView:e.initialViewMode||this.getInitialView(),viewDate:this.getInitialViewDate(n),selectedDate:n&&n.isValid()?n:void 0,inputValue:this.getInitialInputValue(n)}}},{key:"getInitialViewDate",value:function(e){var t,n=this.props.initialViewDate;if(n){if((t=this.parseDate(n,this.getFormat("datetime")))&&t.isValid())return t;je('The initialViewDated given "'+n+'" is not valid. Using current date instead.')}else if(e&&e.isValid())return e.clone();return this.getInitialDate()}},{key:"getInitialDate",value:function(){var e=this.localMoment();return e.hour(0).minute(0).second(0).millisecond(0),e}},{key:"getInitialView",value:function(){var e=this.getFormat("date");return e?this.getUpdateOn(e):"time"}},{key:"parseDate",value:function(e,t){var n;return e&&"string"==typeof e?n=this.localMoment(e,t):e&&(n=this.localMoment(e)),n&&!n.isValid()&&(n=null),n}},{key:"getClassName",value:function(){var e="rdt",t=this.props,n=t.className;return Array.isArray(n)?e+=" "+n.join(" "):n&&(e+=" "+n),t.input||(e+=" rdtStatic"),this.isOpen()&&(e+=" rdtOpen"),e}},{key:"isOpen",value:function(){return!this.props.input||(void 0===this.props.open?this.state.open:this.props.open)}},{key:"getUpdateOn",value:function(e){return this.props.updateOnView?this.props.updateOnView:e.match(/[lLD]/)?we:-1!==e.indexOf("M")?_e:-1!==e.indexOf("Y")?ye:we}},{key:"getLocaleData",value:function(){var e=this.props;return this.localMoment(e.value||e.defaultValue||new Date).localeData()}},{key:"getDateFormat",value:function(){var e=this.getLocaleData(),t=this.props.dateFormat;return!0===t?e.longDateFormat("L"):t||""}},{key:"getTimeFormat",value:function(){var e=this.getLocaleData(),t=this.props.timeFormat;return!0===t?e.longDateFormat("LT"):t||""}},{key:"getFormat",value:function(e){if("date"===e)return this.getDateFormat();if("time"===e)return this.getTimeFormat();var t=this.getDateFormat(),n=this.getTimeFormat();return t&&n?t+" "+n:t||n}},{key:"updateTime",value:function(e,t,n,r){var o={},i=r?"selectedDate":"viewDate";o[i]=this.state[i].clone()[e](t,n),this.setState(o)}},{key:"localMoment",value:function(e,t,n){var r=null;return r=(n=n||this.props).utc?a.a.utc(e,t,n.strictParsing):n.displayTimeZone?a.a.tz(e,t,n.displayTimeZone):a()(e,t,n.strictParsing),n.locale&&r.locale(n.locale),r}},{key:"checkTZ",value:function(){var e=this.props.displayTimeZone;!e||this.tzWarning||a.a.tz||(this.tzWarning=!0,je('displayTimeZone prop with value "'+e+'" is used but moment.js timezone is not loaded.',"error"))}},{key:"componentDidUpdate",value:function(e){if(e!==this.props){var t=!1,n=this.props;["locale","utc","displayZone","dateFormat","timeFormat"].forEach((function(r){e[r]!==n[r]&&(t=!0)})),t&&this.regenerateDates(),n.value&&n.value!==e.value&&this.setViewDate(n.value),this.checkTZ()}}},{key:"regenerateDates",value:function(){var e=this.props,t=this.state.viewDate.clone(),n=this.state.selectedDate&&this.state.selectedDate.clone();e.locale&&(t.locale(e.locale),n&&n.locale(e.locale)),e.utc?(t.utc(),n&&n.utc()):e.displayTimeZone?(t.tz(e.displayTimeZone),n&&n.tz(e.displayTimeZone)):(t.locale(),n&&n.locale());var r={viewDate:t,selectedDate:n};n&&n.isValid()&&(r.inputValue=n.format(this.getFormat("datetime"))),this.setState(r)}},{key:"getSelectedDate",value:function(){if(void 0===this.props.value)return this.state.selectedDate;var e=this.parseDate(this.props.value,this.getFormat("datetime"));return!(!e||!e.isValid())&&e}},{key:"getInitialInputValue",value:function(e){var t=this.props;return t.inputProps.value?t.inputProps.value:e&&e.isValid()?e.format(this.getFormat("datetime")):t.value&&"string"==typeof t.value?t.value:t.initialValue&&"string"==typeof t.initialValue?t.initialValue:""}},{key:"getInputValue",value:function(){var e=this.getSelectedDate();return e?e.format(this.getFormat("datetime")):this.state.inputValue}},{key:"setViewDate",value:function(e){var t;return e&&(t="string"==typeof e?this.localMoment(e,this.getFormat("datetime")):this.localMoment(e))&&t.isValid()?void this.setState({viewDate:t}):je("Invalid date passed to the `setViewDate` method: "+e)}},{key:"navigate",value:function(e){this._showView(e)}},{key:"callHandler",value:function(e,t){return!e||!1!==e(t)}}]),n}(l.a.Component);function je(e,t){var n="undefined"!=typeof window&&window.console;n&&(t||(t="warn"),n[t]("***react-datetime:"+e))}be(Se,"propTypes",{value:ke,initialValue:ke,initialViewDate:ke,initialViewMode:xe.oneOf([ye,_e,we,"time"]),onOpen:xe.func,onClose:xe.func,onChange:xe.func,onNavigate:xe.func,onBeforeNavigate:xe.func,onNavigateBack:xe.func,onNavigateForward:xe.func,updateOnView:xe.string,locale:xe.string,utc:xe.bool,displayTimeZone:xe.string,input:xe.bool,dateFormat:xe.oneOfType([xe.string,xe.bool]),timeFormat:xe.oneOfType([xe.string,xe.bool]),inputProps:xe.object,timeConstraints:xe.object,isValidDate:xe.func,open:xe.bool,strictParsing:xe.bool,closeOnSelect:xe.bool,closeOnTab:xe.bool,renderView:xe.func,renderInput:xe.func,renderDay:xe.func,renderMonth:xe.func,renderYear:xe.func}),be(Se,"defaultProps",{onOpen:Oe,onClose:Oe,onCalendarOpen:Oe,onCalendarClose:Oe,onChange:Oe,onNavigate:Oe,onBeforeNavigate:function(e){return e},onNavigateBack:Oe,onNavigateForward:Oe,dateFormat:!0,timeFormat:!0,utc:!1,className:"",input:!0,inputProps:{},timeConstraints:{},isValidDate:function(){return!0},strictParsing:!0,closeOnSelect:!1,closeOnTab:!0,closeOnClickOutside:!0,renderView:function(e,t){return t()}}),be(Se,"moment",a.a);var Ee=function(e,t){var n,r,o=e.displayName||e.name||"Component";return r=n=function(n){var r,i;function a(e){var r;return(r=n.call(this,e)||this).__outsideClickHandler=function(e){if("function"!=typeof r.__clickOutsideHandlerProp){var t=r.getInstance();if("function"!=typeof t.props.handleClickOutside){if("function"!=typeof t.handleClickOutside)throw new Error("WrappedComponent: "+o+" lacks a handleClickOutside(event) function for processing outside click events.");t.handleClickOutside(e)}else t.props.handleClickOutside(e)}else r.__clickOutsideHandlerProp(e)},r.__getComponentNode=function(){var e=r.getInstance();return t&&"function"==typeof t.setClickOutsideRef?t.setClickOutsideRef()(e):"function"==typeof e.setClickOutsideRef?e.setClickOutsideRef():Object(J.findDOMNode)(e)},r.enableOnClickOutside=function(){if("undefined"!=typeof document&&!oe[r._uid]){void 0===te&&(te=function(){if("undefined"!=typeof window&&"function"==typeof window.addEventListener){var e=!1,t=Object.defineProperty({},"passive",{get:function(){e=!0}}),n=function(){};return window.addEventListener("testPassiveEventSupport",n,t),window.removeEventListener("testPassiveEventSupport",n,t),e}}()),oe[r._uid]=!0;var e=r.props.eventTypes;e.forEach||(e=[e]),re[r._uid]=function(e){var t;null!==r.componentNode&&(r.props.preventDefault&&e.preventDefault(),r.props.stopPropagation&&e.stopPropagation(),r.props.excludeScrollbar&&(t=e,document.documentElement.clientWidth<=t.clientX||document.documentElement.clientHeight<=t.clientY)||function(e,t,n){if(e===t)return!0;for(;e.parentNode;){if(Q(e,t,n))return!0;e=e.parentNode}return e}(e.target,r.componentNode,r.props.outsideClickIgnoreClass)===document&&r.__outsideClickHandler(e))},e.forEach((function(e){document.addEventListener(e,re[r._uid],ae(r,e))}))}},r.disableOnClickOutside=function(){delete oe[r._uid];var e=re[r._uid];if(e&&"undefined"!=typeof document){var t=r.props.eventTypes;t.forEach||(t=[t]),t.forEach((function(t){return document.removeEventListener(t,e,ae(r,t))})),delete re[r._uid]}},r.getRef=function(e){return r.instanceRef=e},r._uid=ne(),r}i=n,(r=a).prototype=Object.create(i.prototype),r.prototype.constructor=r,r.__proto__=i;var l=a.prototype;return l.getInstance=function(){if(!e.prototype.isReactComponent)return this;var t=this.instanceRef;return t.getInstance?t.getInstance():t},l.componentDidMount=function(){if("undefined"!=typeof document&&document.createElement){var e=this.getInstance();if(t&&"function"==typeof t.handleClickOutside&&(this.__clickOutsideHandlerProp=t.handleClickOutside(e),"function"!=typeof this.__clickOutsideHandlerProp))throw new Error("WrappedComponent: "+o+" lacks a function for processing outside click events specified by the handleClickOutside config option.");this.componentNode=this.__getComponentNode(),this.props.disableOnClickOutside||this.enableOnClickOutside()}},l.componentDidUpdate=function(){this.componentNode=this.__getComponentNode()},l.componentWillUnmount=function(){this.disableOnClickOutside()},l.render=function(){var t=this.props,n=(t.excludeScrollbar,function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(t,["excludeScrollbar"]));return e.prototype.isReactComponent?n.ref=this.getRef:n.wrappedRef=this.getRef,n.disableOnClickOutside=this.disableOnClickOutside,n.enableOnClickOutside=this.enableOnClickOutside,Object(s.createElement)(e,n)},a}(s.Component),n.displayName="OnClickOutside("+o+")",n.defaultProps={eventTypes:["mousedown","touchstart"],excludeScrollbar:t&&t.excludeScrollbar||!1,outsideClickIgnoreClass:"ignore-react-onclickoutside",preventDefault:!1,stopPropagation:!1},n.getClass=function(){return e.getClass?e.getClass():e},r}(function(e){pe(n,e);var t=he(n);function n(){var e;ce(this,n);for(var r=arguments.length,o=new Array(r),i=0;i1)throw new Error("The Quill editing area can only be composed of a single React element.");if(l.default.Children.count(e.children)&&"textarea"===(null===(t=l.default.Children.only(e.children))||void 0===t?void 0:t.type))throw new Error("Quill does not support editing on a + ); +}; + +Paragraph.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Paragraph; diff --git a/ui/js/dfv/src/fields/paragraph/paragraph.scss b/ui/js/dfv/src/fields/paragraph/paragraph.scss new file mode 100644 index 0000000000..8ca8ed2ff5 --- /dev/null +++ b/ui/js/dfv/src/fields/paragraph/paragraph.scss @@ -0,0 +1,4 @@ +.pods-form-ui-field-type-paragraph { + min-height: 200px; + width: 100%; +} diff --git a/ui/js/dfv/src/fields/password/index.js b/ui/js/dfv/src/fields/password/index.js new file mode 100644 index 0000000000..a2d64d4b20 --- /dev/null +++ b/ui/js/dfv/src/fields/password/index.js @@ -0,0 +1,33 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import BaseInput from 'dfv/src/fields/base-input'; + +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +const Password = ( props ) => { + const { fieldConfig = {} } = props; + + const { + password_max_length: maxLength, + password_placeholder: placeholder, + } = fieldConfig; + + return ( + + ); +}; + +Password.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Password; diff --git a/ui/js/dfv/src/fields/password/test/index.js b/ui/js/dfv/src/fields/password/test/index.js new file mode 100644 index 0000000000..45bf5f2aec --- /dev/null +++ b/ui/js/dfv/src/fields/password/test/index.js @@ -0,0 +1,61 @@ +/** + * External dependencies + */ +import { mount } from 'enzyme'; + +/** + * Internal dependencies + */ +import Password from '..'; + +const BASE_PROPS = { + value: '', + setValue: jest.fn(), + addValidationRules: jest.fn(), + setHasBlurred: jest.fn(), + fieldConfig: { + group: 'group/pod/_pods_pod/dfv-demo', + id: 'some_id', + label: 'Test Password Field', + name: 'test_password_field', + object_type: 'field', + parent: 'pod/_pods_pod', + type: 'password', + }, +}; + +describe( 'Email field component', () => { + it( 'applies the relevant attributes to the password input field', () => { + const props = { + ...BASE_PROPS, + fieldConfig: { + ...BASE_PROPS.fieldConfig, + password_max_length: 20, + password_placeholder: 'Some placeholder for the field', + }, + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ); + + expect( input.props().type ).toBe( 'password' ); + expect( input.props().type ).toEqual( 'password' ); + expect( input.props().maxLength ).toEqual( 20 ); + expect( input.props().placeholder ).toEqual( 'Some placeholder for the field' ); + } ); + + it( 'calls the setValue callback once updated', () => { + const props = { + ...BASE_PROPS, + setValue: jest.fn(), + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ).first(); + input.simulate( 'change', { + target: { value: 'test123' }, + } ); + + expect( props.setValue ).toHaveBeenCalledWith( 'test123' ); + } ); +} ); diff --git a/ui/js/dfv/src/fields/phone/index.js b/ui/js/dfv/src/fields/phone/index.js new file mode 100644 index 0000000000..29e6b7fe99 --- /dev/null +++ b/ui/js/dfv/src/fields/phone/index.js @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import BaseInput from 'dfv/src/fields/base-input'; +import { toBool } from 'dfv/src/helpers/booleans'; + +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +const Phone = ( props ) => { + const { fieldConfig = {} } = props; + + const { + phone_max_length: maxLength, + phone_placeholder: placeholder, + phone_html5: html5, + } = fieldConfig; + + return ( + + ); +}; + +Phone.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Phone; diff --git a/ui/js/dfv/src/fields/phone/test/index.js b/ui/js/dfv/src/fields/phone/test/index.js new file mode 100644 index 0000000000..1087c95b6d --- /dev/null +++ b/ui/js/dfv/src/fields/phone/test/index.js @@ -0,0 +1,71 @@ +/** + * External dependencies + */ +import { mount } from 'enzyme'; + +/** + * Internal dependencies + */ +import Phone from '..'; + +const BASE_PROPS = { + value: '', + setValue: jest.fn(), + addValidationRules: jest.fn(), + setHasBlurred: jest.fn(), + fieldConfig: { + group: 'group/pod/_pods_pod/dfv-demo', + id: 'some_id', + label: 'Test Phone Field', + name: 'test_phone_field', + object_type: 'field', + parent: 'pod/_pods_pod', + type: 'phone', + }, +}; + +describe( 'Phone field component', () => { + it( 'creates a text field if the HTML5 phone option is not set', () => { + const props = { ...BASE_PROPS }; + + const wrapper = mount( ); + + expect( + wrapper.find( 'input' ).props().type + ).toBe( 'text' ); + } ); + + it( 'applies the relevant attributes to the input field', () => { + const props = { + ...BASE_PROPS, + fieldConfig: { + ...BASE_PROPS.fieldConfig, + phone_html5: true, + phone_max_length: 20, + phone_placeholder: 'Some placeholder for the field', + }, + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ); + + expect( input.props().type ).toEqual( 'tel' ); + expect( input.props().maxLength ).toEqual( 20 ); + expect( input.props().placeholder ).toEqual( 'Some placeholder for the field' ); + } ); + + it( 'calls the setValue callback once updated', () => { + const props = { + ...BASE_PROPS, + setValue: jest.fn(), + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ).first(); + input.simulate( 'change', { + target: { value: '123-456-7890' }, + } ); + + expect( props.setValue ).toHaveBeenCalledWith( '123-456-7890' ); + } ); +} ); diff --git a/ui/js/dfv/src/fields/pick/checkbox-select.js b/ui/js/dfv/src/fields/pick/checkbox-select.js new file mode 100644 index 0000000000..5ba895c33a --- /dev/null +++ b/ui/js/dfv/src/fields/pick/checkbox-select.js @@ -0,0 +1,135 @@ +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; + +import { PICK_OPTIONS } from 'dfv/src/config/prop-types'; + +const CheckboxSelect = ( { + htmlAttributes, + name, + value, + options = [], + setValue, + isMulti, + readOnly = false, +} ) => { + const toggleValueOption = ( option ) => { + if ( value.some( ( valueItem ) => valueItem.toString() === option.toString() ) ) { + setValue( + value.filter( ( item ) => item.toString() !== option.toString() ) + ); + } else { + setValue( [ ...value, option ] ); + } + }; + + const totalOptions = options.length; + + return ( +
            + { options.map( ( + { + id: optionValue, + name: optionLabel, + }, + optionIndex, + allOptions + ) => { + const nameBase = htmlAttributes.name || name; + + const nameAttribute = allOptions.length > 1 + ? `${ nameBase }[${ optionIndex }]` + : nameBase; + + let idAttribute = !! htmlAttributes.id ? htmlAttributes.id : `pods-form-ui-${ name }`; + + if ( 1 < totalOptions ) { + idAttribute += `-${ optionValue }`; + } + + return ( +
          • +
            + { /* eslint-disable-next-line jsx-a11y/label-has-for */ } + +
            +
          • + ); + } ) } +
          + ); +}; + +CheckboxSelect.propTypes = { + htmlAttributes: PropTypes.shape( { + id: PropTypes.string, + class: PropTypes.string, + name: PropTypes.string, + } ), + name: PropTypes.string.isRequired, + value: PropTypes.oneOfType( [ + PropTypes.arrayOf( + PropTypes.oneOfType( [ + PropTypes.string, + PropTypes.number, + ] ) + ), + PropTypes.string, + PropTypes.number, + ] ), + setValue: PropTypes.func.isRequired, + options: PICK_OPTIONS.isRequired, + isMulti: PropTypes.bool.isRequired, + readOnly: PropTypes.bool, +}; + +export default CheckboxSelect; diff --git a/ui/js/dfv/src/fields/pick/index.js b/ui/js/dfv/src/fields/pick/index.js new file mode 100644 index 0000000000..a7a58d60ed --- /dev/null +++ b/ui/js/dfv/src/fields/pick/index.js @@ -0,0 +1,479 @@ +/** + * External dependencies + */ +import React, { useState, useEffect } from 'react'; +import AsyncSelect from 'react-select/async'; +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { Button } from '@wordpress/components'; +import { __, sprintf } from '@wordpress/i18n'; + +/** + * Other Pods dependencies + */ +import SimpleSelect from './simple-select'; +import RadioSelect from './radio-select'; +import CheckboxSelect from './checkbox-select'; +import ListSelectValues from './list-select-values'; + +import IframeModal from 'dfv/src/components/iframe-modal'; + +import useBidirectionalFieldData from 'dfv/src/hooks/useBidirectionalFieldData'; +import loadAjaxOptions from '../../helpers/loadAjaxOptions'; + +import { toBool } from 'dfv/src/helpers/booleans'; +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +import './pick.scss'; + +const getFieldItemDataFromDataProp = ( data ) => { + // Skip unless we're handling an object of values. + if ( 'object' !== typeof data || Array.isArray( data ) ) { + return []; + } + + const entries = Object.entries( data ); + + return entries.reduce( ( accumulator, entry ) => { + if ( 'string' === typeof entry[ 1 ] ) { + return [ + ...accumulator, + { + id: entry[ 0 ], + icon: '', + name: entry[ 1 ], + edit_link: '', + link: '', + selected: false, + }, + ]; + } + + const subOptions = Object.entries( entry[ 1 ] ) + .map( ( subEntry ) => ( { name: subEntry[ 1 ], id: subEntry[ 0 ] } ) ); + + return [ + ...accumulator, + { + id: subOptions, + icon: '', + name: entry[ 0 ], + edit_link: '', + link: '', + selected: false, + }, + ]; + }, [] ); +}; + +const formatValuesForReactSelectComponent = ( + value, + fieldItemData = [], + isMulti = false +) => { + if ( ! value ) { + return isMulti ? [] : []; + } + + if ( ! isMulti ) { + const selectedItemData = fieldItemData.find( + ( option ) => option?.id?.toString() === value.toString() + ); + + return [ + { + label: selectedItemData?.name, + value: selectedItemData?.id.toString(), + }, + ]; + } + + const splitValue = Array.isArray( value ) ? value : value.split( ',' ); + + return splitValue.map( + ( currentValue ) => { + const fullFieldItem = fieldItemData.find( + ( option ) => option?.id?.toString() === currentValue.toString() + ); + + if ( fullFieldItem ) { + return { + label: fullFieldItem?.name, + value: fullFieldItem?.id.toString(), + }; + } + + return {}; + } + ); +}; + +const formatValuesForHTMLSelectElement = ( value, isMulti ) => { + if ( ! value ) { + return undefined; + } + + if ( ! isMulti ) { + return value; + } + + return Array.isArray( value ) ? value : value.split( ',' ); +}; + +const Pick = ( props ) => { + const { + fieldConfig: { + ajax_data: ajaxData, + htmlAttr: htmlAttributes = {}, + readonly: readOnly, + fieldItemData, + data = [], + label, + name, + default_icon: defaultIcon, + iframe_src: addNewIframeSrc, + iframe_title_add: addNewIframeTitle, + iframe_title_edit: editIframeTitle, + pick_allow_add_new: allowAddNew, + // pick_custom: pickCustomOptions, + // pick_display, + // pick_display_format_multi, + // pick_display_format_separator, + pick_format_multi: formatMulti = 'autocomplete', + pick_format_single: formatSingle = 'dropdown', + pick_format_type: formatType = 'single', + // pick_groupby, + pick_limit: limit, + // pick_object: pickObject, + // pick_orderby: orderBy, + // pick_post_status: postStatus, + // pick_select_text: selectText = __( '-- Select One --', 'pods' ), + pick_show_edit_link: showEditLink, + pick_show_icon: showIcon, + pick_show_view_link: showViewLink, + // pick_table, + // pick_table_id, + // pick_table_index, + // pick_taggable, + // pick_user_role, + // pick_val: pickValue, + // rest_pick_depth: pickDepth, + // rest_pick_response: pickResponse, + // pick_where, + type: fieldType, + }, + setValue, + value, + setHasBlurred, + podType, + podName, + allPodValues, + } = props; + + const isSingle = 'single' === formatType; + const isMulti = 'multi' === formatType; + + const [ showAddNewIframe, setShowAddNewIframe ] = useState( false ); + + // Most options are set from the field's fieldItemData, but this could get + // modified by the add/edit modals, or by loading ajax options, so we need to track + // this in state, starting with the supplied fieldItemData from the page load. + const [ modifiedFieldItemData, setModifiedFieldItemData ] = useState( + fieldItemData ? fieldItemData : getFieldItemDataFromDataProp( data ) + ); + + const { bidirectionFieldItemData } = useBidirectionalFieldData( + podType, + podName, + name, + fieldType, + allPodValues?.pick_object || '', + ); + + useEffect( () => { + // This is only relevant on the "Bidirectional"/'sister_id' field. + if ( 'sister_id' !== name ) { + return; + } + + if ( bidirectionFieldItemData.length ) { + setModifiedFieldItemData( bidirectionFieldItemData ); + } + }, [ bidirectionFieldItemData ] ); + + const setValueWithLimit = ( newValue ) => { + // We don't need to worry about limits if this isn't a multi-select field. + if ( isSingle ) { + setValue( newValue ); + setHasBlurred( true ); + + return; + } + + // Filter out empty values that could have gotten passed in. + const filteredNewValues = newValue.filter( ( item ) => !! item ); + + // If no limit is set, set the value. + const numericLimit = parseInt( limit, 10 ) || 0; + + if ( isNaN( numericLimit ) || 0 === numericLimit || -1 === numericLimit ) { + setHasBlurred( true ); + setValue( filteredNewValues ); + return; + } + + // If we're trying to set more items than the limit allows, just return. + if ( filteredNewValues.length > numericLimit ) { + return; + } + + setValue( filteredNewValues ); + setHasBlurred( true ); + }; + + useEffect( () => { + const listenForIframeMessages = ( event ) => { + if ( + event.origin !== window.location.origin || + 'PODS_MESSAGE' !== event.data.type || + ! event.data.data + ) { + return; + } + + setShowAddNewIframe( false ); + + const { data: newData = {} } = event.data; + + setModifiedFieldItemData( ( prevData ) => [ + ...prevData, + newData, + ] ); + + setValueWithLimit( [ + ...( value || [] ), + newData?.id.toString(), + ] ); + }; + + if ( showAddNewIframe ) { + window.addEventListener( 'message', listenForIframeMessages, false ); + } else { + window.removeEventListener( 'message', listenForIframeMessages, false ); + } + + return () => { + window.removeEventListener( 'message', listenForIframeMessages, false ); + }; + }, [ showAddNewIframe ] ); + + // There are a variety of different "select" components, this + // chooses the right one based on the options. + const renderSelectComponent = () => { + if ( ! isMulti && 'radio' === formatSingle ) { + return ( + + ); + } + + if ( + ( isSingle && 'checkbox' === formatSingle ) || + ( isMulti && 'checkbox' === formatMulti ) + ) { + let formattedValue = value; + + if ( isMulti ) { + formattedValue = Array.isArray( value ) + ? value + : ( value || '' ).split( ',' ); + } + + return ( + + ); + } + + if ( + ( isSingle && 'list' === formatSingle ) || + ( isMulti && 'list' === formatMulti ) || + ( isSingle && 'autocomplete' === formatSingle ) || + ( isMulti && 'autocomplete' === formatMulti ) + ) { + const isListSelect = ( isSingle && 'list' === formatSingle ) || ( isMulti && 'list' === formatMulti ); + + const formattedValue = formatValuesForReactSelectComponent( + value, + modifiedFieldItemData, + isMulti, + ); + + const formattedOptions = modifiedFieldItemData.map( ( item ) => ( { + label: item.name, + value: item.id, + } ) ); + + return ( + <> + { + // The new value(s) may have been loaded by ajax, if it was, then it wasn't + // in our array of dataOptions, and we should add it, so we can keep track of + // the label. + setModifiedFieldItemData( ( prevData ) => { + const prevDataValues = prevData.map( ( option ) => option.id ); + const updatedData = [ ...prevData ]; + const newOptions = isMulti ? newOption : [ newOption ]; + + newOptions.forEach( ( option ) => { + if ( prevDataValues.includes( option.value ) ) { + return; + } + + updatedData.push( { + id: option.value, + name: option.label, + } ); + } ); + + return updatedData; + } ); + + if ( isMulti ) { + setValueWithLimit( newOption.map( + ( selection ) => selection.value ) + ); + } else { + setValueWithLimit( newOption.value ); + } + } } + readOnly={ !! readOnly } + /> + + { isListSelect ? ( + + ) : null } + + { formattedValue.map( ( selectedValue, index ) => ( + + ) ) } + + ); + } + + return ( + setValueWithLimit( newValue ) } + options={ modifiedFieldItemData } + isMulti={ isMulti } + readOnly={ !! readOnly } + /> + ); + }; + + return ( + <> + { renderSelectComponent() } + + { ( allowAddNew && addNewIframeSrc ) ? ( + + ) : null } + + { showAddNewIframe ? ( + setShowAddNewIframe( false ) } + /> + ) : null } + + ); +}; + +Pick.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + + /** + * Pod type being edited. + */ + podType: PropTypes.string, + + /** + * Pod slug being edited. + */ + podName: PropTypes.string, + + /** + * All field values for the Pod to use for + * validating dependencies. + */ + allPodValues: PropTypes.object, + + /** + * Field value. + */ + value: PropTypes.oneOfType( [ + PropTypes.arrayOf( + PropTypes.oneOfType( [ + PropTypes.string, + PropTypes.number, + ] ) + ), + PropTypes.string, + PropTypes.number, + ] ), +}; + +export default Pick; diff --git a/ui/js/dfv/src/fields/pick/list-select-values.js b/ui/js/dfv/src/fields/pick/list-select-values.js new file mode 100644 index 0000000000..ab480f6cfe --- /dev/null +++ b/ui/js/dfv/src/fields/pick/list-select-values.js @@ -0,0 +1,324 @@ +/** + * External dependencies + */ +import React, { useState, useEffect } from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; + +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Button } from '@wordpress/components'; +import { + chevronUp, + chevronDown, +} from '@wordpress/icons'; + +/** + * Other Pods dependencies + */ +import IframeModal from 'dfv/src/components/iframe-modal'; + +import './list-select.scss'; + +const ListSelectItem = ( { + fieldName, + value, + editLink, + viewLink, + editIframeTitle, + icon, + isDraggable, + isRemovable, + moveUp, + moveDown, + removeItem, + setFieldItemData, +} ) => { + const isDashIcon = /^dashicons/.test( icon ); + const [ showEditModal, setShowEditModal ] = useState( false ); + + useEffect( () => { + const listenForIframeMessages = ( event ) => { + if ( + event.origin !== window.location.origin || + 'PODS_MESSAGE' !== event.data.type || + ! event.data.data + ) { + return; + } + + setShowEditModal( false ); + + const { data: newData = {} } = event.data; + + setFieldItemData( ( prevData ) => prevData.map( ( item ) => { + return ( newData.id && Number( item?.id ) === Number( newData.id ) ) + ? newData + : item; + } ) ); + }; + + if ( showEditModal ) { + window.addEventListener( 'message', listenForIframeMessages, false ); + } else { + window.removeEventListener( 'message', listenForIframeMessages, false ); + } + + return () => { + window.removeEventListener( 'message', listenForIframeMessages, false ); + }; + }, [ showEditModal ] ); + + return ( +
        • + + + { showEditModal ? ( + setShowEditModal( false ) } + /> + ) : null } +
        • + ); +}; + +ListSelectItem.propTypes = { + fieldName: PropTypes.string.isRequired, + value: PropTypes.shape( { + label: PropTypes.string.isRequired, + value: PropTypes.string.isRequired, + } ), + editLink: PropTypes.string, + editIframeTitle: PropTypes.string, + viewLink: PropTypes.string, + icon: PropTypes.string, + isDraggable: PropTypes.bool.isRequired, + isRemovable: PropTypes.bool.isRequired, + moveUp: PropTypes.func, + moveDown: PropTypes.func, + removeItem: PropTypes.func.isRequired, + setFieldItemData: PropTypes.func.isRequired, +}; + +const ListSelectValues = ( { + fieldName, + value: arrayOfValues, + fieldItemData, + setFieldItemData, + setValue, + isMulti, + limit, + defaultIcon, + showIcon, + showViewLink, + showEditLink, + editIframeTitle, + readOnly = false, +} ) => { + const removeValueAtIndex = ( index = 0 ) => { + if ( isMulti ) { + setValue( + [ + ...arrayOfValues.slice( 0, index ), + ...arrayOfValues.slice( index + 1 ), + ].map( ( item ) => item.value ) + ); + } else { + setValue( undefined ); + } + }; + + const swapItems = ( oldIndex, newIndex ) => { + if ( ! isMulti ) { + throw 'Swap items shouldn\'nt be called on a single ListSelect'; + } + + const newValues = [ ...arrayOfValues ]; + const tempValue = newValues[ newIndex ]; + + newValues[ newIndex ] = newValues[ oldIndex ]; + newValues[ oldIndex ] = tempValue; + + setValue( + newValues.map( ( item ) => item.value ), + ); + }; + + return ( +
          + { !! arrayOfValues.length && ( +
            + { arrayOfValues.map( ( valueItem, index ) => { + // There may be additional data in an object from the fieldItemData + // array. + const moreData = fieldItemData.find( + ( item ) => item?.id === valueItem.value + ); + + const icon = showIcon ? ( moreData?.icon || defaultIcon ) : undefined; + + // May need to change the label, if it differs from the provided value. + const displayValue = valueItem; + + const matchingFieldItemData = fieldItemData.find( + ( item ) => Number( item.id ) === Number( valueItem.value ) + ); + + if ( matchingFieldItemData && matchingFieldItemData.name ) { + displayValue.label = matchingFieldItemData.name; + } + + return ( + removeValueAtIndex( index ) } + setFieldItemData={ setFieldItemData } + moveUp={ + ( ! readOnly && index !== 0 ) + ? () => swapItems( index, index - 1 ) + : undefined + } + moveDown={ + ( ! readOnly && index !== ( arrayOfValues.length - 1 ) ) + ? () => swapItems( index, index + 1 ) + : undefined + } + /> + ); + } ) } +
          + ) } +
          + ); +}; + +ListSelectValues.propTypes = { + fieldName: PropTypes.string.isRequired, + value: PropTypes.arrayOf( + PropTypes.shape( { + label: PropTypes.string.isRequired, + value: PropTypes.string.isRequired, + } ) + ), + setValue: PropTypes.func.isRequired, + fieldItemData: PropTypes.arrayOf( + PropTypes.any, + ), + setFieldItemData: PropTypes.func.isRequired, + isMulti: PropTypes.bool.isRequired, + limit: PropTypes.number.isRequired, + defaultIcon: PropTypes.string, + showIcon: PropTypes.bool.isRequired, + showViewLink: PropTypes.bool.isRequired, + showEditLink: PropTypes.bool.isRequired, + editIframeTitle: PropTypes.string, + readOnly: PropTypes.bool, +}; + +export default ListSelectValues; diff --git a/ui/js/dfv/src/fields/pick/list-select.scss b/ui/js/dfv/src/fields/pick/list-select.scss new file mode 100644 index 0000000000..ea9aca92cd --- /dev/null +++ b/ui/js/dfv/src/fields/pick/list-select.scss @@ -0,0 +1,21 @@ +.pods-list-select-move-buttons { + display: flex; + flex-flow: column nowrap; + // 1px padding fixes WP outline on buttons from being cut off + padding-left: 1px; + + .pods-list-select-move-buttons__button { + background: transparent; + border: none; + height: 16px; + padding: 0; + } + + .pods-list-select-move-buttons__button--disabled { + opacity: 0.3; + } +} + +.pods-dfv-list-meta .pods-dfv-list-name { + border-bottom: none; +} diff --git a/ui/js/dfv/src/fields/pick/pick.scss b/ui/js/dfv/src/fields/pick/pick.scss new file mode 100644 index 0000000000..fded142de1 --- /dev/null +++ b/ui/js/dfv/src/fields/pick/pick.scss @@ -0,0 +1,60 @@ +// +// Select fields +// +.pods-form-ui-field-select { + width: 100%; + margin: 0; + max-width: 100%; +} + +.pods-form-ui-field-select[readonly] { + font-style: italic; + color: grey; +} + +// +// Radio and Checkbox fields +// +.pods-radio-pick, +.pods-checkbox-pick { + background: #fff; + margin: 0 0 5px 0; + padding: 0; + border-radius: 0; + border: 1px solid #dfdfdf; + overflow: hidden; + max-height: 220px; + overflow-y: auto; +} + +.pods-radio-pick__option, +.pods-checkbox-pick__option { + background-color: #fff; + border-bottom: 1px solid #f4f4f4; + margin: 0; + padding: 0.5em; + + &:nth-child(even) { + background: #fcfcfc; + } +} + +.pods-checkbox-pick__option__label, +.pods-radio-pick__option__label { + display: inline-block; + float: none !important; + margin: 0 !important; + padding: 0 !important; +} + +.pods-checkbox-pick--single { + border: none; +} + +.pods-checkbox-pick__option--single { + border-bottom: none; +} + +.pods-checkbox-pick__option--single .pods-checkbox-pick__option__label { + margin-left: 0; +} diff --git a/ui/js/dfv/src/fields/pick/radio-select.js b/ui/js/dfv/src/fields/pick/radio-select.js new file mode 100644 index 0000000000..c42ba793d8 --- /dev/null +++ b/ui/js/dfv/src/fields/pick/radio-select.js @@ -0,0 +1,75 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { PICK_OPTIONS } from 'dfv/src/config/prop-types'; + +const RadioSelect = ( { + htmlAttributes, + name, + value, + options, + setValue, + readOnly = false, +} ) => { + return ( +
            + { options.map( ( { + id: optionValue, + name: optionLabel, + } ) => { + const idAttribute = !! htmlAttributes.id + ? `${ htmlAttributes.id }-${ optionValue }` + : `${ name }-${ optionValue }`; + + return ( +
          • +
            + { /* eslint-disable-next-line jsx-a11y/label-has-for */ } + +
            +
          • + ); + } ) } +
          + ); +}; + +RadioSelect.propTypes = { + htmlAttributes: PropTypes.shape( { + id: PropTypes.string, + class: PropTypes.string, + name: PropTypes.string, + } ), + name: PropTypes.string.isRequired, + value: PropTypes.oneOfType( [ + PropTypes.string, + PropTypes.number, + ] ), + setValue: PropTypes.func.isRequired, + options: PICK_OPTIONS.isRequired, + readOnly: PropTypes.bool, +}; + +export default RadioSelect; diff --git a/ui/js/dfv/src/fields/pick/simple-select.js b/ui/js/dfv/src/fields/pick/simple-select.js new file mode 100644 index 0000000000..4df8a9b26f --- /dev/null +++ b/ui/js/dfv/src/fields/pick/simple-select.js @@ -0,0 +1,119 @@ +import React from 'react'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; + +import { PICK_OPTIONS } from 'dfv/src/config/prop-types'; + +const SimpleSelect = ( { + htmlAttributes, + name, + value, + options, + setValue, + isMulti = false, + readOnly = false, +} ) => { + const classes = classnames( + 'pods-form-ui-field pods-form-ui-field-type-pick pods-form-ui-field-select', + htmlAttributes.class + ); + + let htmlName = htmlAttributes.name || name; + + // Maybe add [] to the multiple select field. + if ( isMulti ) { + htmlName += '[]'; + } + + return ( + /* eslint-disable-next-line jsx-a11y/no-onchange */ + + ); +}; + +SimpleSelect.propTypes = { + htmlAttributes: PropTypes.shape( { + id: PropTypes.string, + class: PropTypes.string, + name: PropTypes.string, + } ), + name: PropTypes.string.isRequired, + value: PropTypes.oneOfType( [ + PropTypes.arrayOf( + PropTypes.oneOfType( [ + PropTypes.string, + PropTypes.number, + ] ) + ), + PropTypes.string, + PropTypes.number, + ] ), + setValue: PropTypes.func.isRequired, + options: PICK_OPTIONS.isRequired, + isMulti: PropTypes.bool, + readOnly: PropTypes.bool, +}; + +export default SimpleSelect; diff --git a/ui/js/dfv/src/fields/slug/index.js b/ui/js/dfv/src/fields/slug/index.js new file mode 100644 index 0000000000..d67620bed3 --- /dev/null +++ b/ui/js/dfv/src/fields/slug/index.js @@ -0,0 +1,39 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import BaseInput from 'dfv/src/fields/base-input'; +import sanitizeSlug from 'dfv/src/helpers/sanitizeSlug'; +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +const Slug = ( props ) => { + const { + fieldConfig = {}, + setValue, + } = props; + + const { + slug_placeholder: placeholder, + slug_separator: separator, + } = fieldConfig; + + // Intercept the setValue call to force the slug formatting. + const forceSlugFormatting = ( newValue ) => { + setValue( sanitizeSlug( newValue, separator ) ); + }; + + return ( + + ); +}; + +Slug.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Slug; diff --git a/ui/js/dfv/src/fields/slug/test/index.js b/ui/js/dfv/src/fields/slug/test/index.js new file mode 100644 index 0000000000..7a380d1eab --- /dev/null +++ b/ui/js/dfv/src/fields/slug/test/index.js @@ -0,0 +1,99 @@ +/** + * External dependencies + */ +import { mount } from 'enzyme'; + +/** + * Internal dependencies + */ +import Slug from '..'; + +const BASE_PROPS = { + value: '', + setValue: jest.fn(), + addValidationRules: jest.fn(), + setHasBlurred: jest.fn(), + fieldConfig: { + group: 'group/pod/_pods_pod/dfv-demo', + id: 'some_id', + label: 'Test Slug Field', + name: 'test_slug_field', + object_type: 'field', + parent: 'pod/_pods_pod', + type: 'slug', + }, +}; + +describe( 'Slug field component', () => { + it( 'creates a field with the relevant attributes', () => { + const props = { + ...BASE_PROPS, + fieldConfig: { + ...BASE_PROPS.fieldConfig, + slug_placeholder: 'Some placeholder for the field', + }, + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ); + + expect( input.props().type ).toBe( 'text' ); + expect( input.props().placeholder ).toEqual( 'Some placeholder for the field' ); + } ); + + it( 'calls the setValue callback once updated', () => { + const props = { + ...BASE_PROPS, + setValue: jest.fn(), + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ).first(); + + input.simulate( 'change', { + target: { value: 'test-123' }, + } ); + + input.simulate( 'change', { + target: { value: 'Something that needs to be formatted' }, + } ); + + input.simulate( 'change', { + target: { value: 'Test )*&^*๐Ÿ˜ฌand*()*)**&^*^# Test' }, + } ); + + expect( props.setValue ).toHaveBeenNthCalledWith( 1, 'test-123' ); + expect( props.setValue ).toHaveBeenNthCalledWith( 2, 'something_that_needs_to_be_formatted' ); + expect( props.setValue ).toHaveBeenNthCalledWith( 3, 'test_and_test' ); + } ); + + it( 'calls the setValue callback once updated with dash fallback', () => { + const props = { + ...BASE_PROPS, + setValue: jest.fn(), + fieldConfig: { + ...BASE_PROPS.fieldConfig, + slug_separator: '-', + }, + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ).first(); + + input.simulate( 'change', { + target: { value: 'test-123' }, + } ); + + input.simulate( 'change', { + target: { value: 'Something that needs to be_formatted' }, + } ); + + input.simulate( 'change', { + target: { value: 'Test )*&^*๐Ÿ˜ฌand*()*)**&^*^# Test' }, + } ); + + expect( props.setValue ).toHaveBeenNthCalledWith( 1, 'test-123' ); + expect( props.setValue ).toHaveBeenNthCalledWith( 2, 'something-that-needs-to-be_formatted' ); + expect( props.setValue ).toHaveBeenNthCalledWith( 3, 'test-and-test' ); + } ); +} ); diff --git a/ui/js/dfv/src/fields/text/index.js b/ui/js/dfv/src/fields/text/index.js new file mode 100644 index 0000000000..957e08b09b --- /dev/null +++ b/ui/js/dfv/src/fields/text/index.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import BaseInput from 'dfv/src/fields/base-input'; +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +const Text = ( props ) => { + const { fieldConfig = {} } = props; + + const { + text_max_length: maxLength, + text_placeholder: placeholder, + } = fieldConfig; + + return ( + + ); +}; + +Text.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Text; diff --git a/ui/js/dfv/src/fields/text/test/index.js b/ui/js/dfv/src/fields/text/test/index.js new file mode 100644 index 0000000000..3d4cf202d1 --- /dev/null +++ b/ui/js/dfv/src/fields/text/test/index.js @@ -0,0 +1,70 @@ +/** + * External dependencies + */ +import { mount } from 'enzyme'; + +/** + * Internal dependencies + */ +import Text from '..'; + +const BASE_PROPS = { + value: '', + setValue: jest.fn(), + addValidationRules: jest.fn(), + setHasBlurred: jest.fn(), + fieldConfig: { + group: 'group/pod/_pods_pod/dfv-demo', + id: 'some_id', + label: 'Test Text Field', + name: 'test_text_field', + object_type: 'field', + parent: 'pod/_pods_pod', + type: 'text', + }, +}; + +describe( 'Text field component', () => { + it( 'creates a text field', () => { + const props = { ...BASE_PROPS }; + + const wrapper = mount( ); + + expect( + wrapper.find( 'input' ).props().type + ).toBe( 'text' ); + } ); + + it( 'applies the relevant attributes to the input field', () => { + const props = { + ...BASE_PROPS, + fieldConfig: { + ...BASE_PROPS.fieldConfig, + text_max_length: 20, + text_placeholder: 'Some placeholder for the field', + }, + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ); + + expect( input.props().type ).toEqual( 'text' ); + expect( input.props().maxLength ).toEqual( 20 ); + expect( input.props().placeholder ).toEqual( 'Some placeholder for the field' ); + } ); + + it( 'calls the setValue callback once updated', () => { + const props = { + ...BASE_PROPS, + setValue: jest.fn(), + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ).first(); + input.simulate( 'change', { + target: { value: 'test@example.com' }, + } ); + + expect( props.setValue ).toHaveBeenCalledWith( 'test@example.com' ); + } ); +} ); diff --git a/ui/js/dfv/src/fields/time/index.js b/ui/js/dfv/src/fields/time/index.js new file mode 100644 index 0000000000..62cffa591c --- /dev/null +++ b/ui/js/dfv/src/fields/time/index.js @@ -0,0 +1,44 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import DateTime from '../datetime'; +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +const Time = ( props ) => { + const { + fieldConfig = {}, + } = props; + + // Process the field config so that properties prefixed with "date_" + // are changed to "datetime_". + const fieldConfigEntries = Object.entries( fieldConfig ).filter( + ( entry ) => ! entry[ 0 ].startsWith( 'time_' ) + ); + + const newConfig = { + ...Object.fromEntries( fieldConfigEntries ), + datetime_allow_empty: fieldConfig.time_allow_empty, + datetime_html5: fieldConfig.time_html5, + datetime_repeatable: fieldConfig.time_repeatable, + datetime_time_format: fieldConfig.time_format, + datetime_time_format_24: fieldConfig.time_format_24, + datetime_time_format_custom: fieldConfig.time_format_custom, + datetime_time_format_custom_js: fieldConfig.time_format_custom_js, + datetime_time_type: fieldConfig.time_type, + datetime_type: 'time', + }; + + return ( + + ); +}; + +Time.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Time; diff --git a/ui/js/dfv/src/fields/website/index.js b/ui/js/dfv/src/fields/website/index.js new file mode 100644 index 0000000000..0113560f3b --- /dev/null +++ b/ui/js/dfv/src/fields/website/index.js @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import BaseInput from 'dfv/src/fields/base-input'; +import { toBool } from 'dfv/src/helpers/booleans'; + +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +const Website = ( props ) => { + const { fieldConfig = {} } = props; + + const { + website_max_length: maxLength, + website_placeholder: placeholder, + website_html5: html5, + } = fieldConfig; + + return ( + + ); +}; + +Website.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Website; diff --git a/ui/js/dfv/src/fields/website/test/index.js b/ui/js/dfv/src/fields/website/test/index.js new file mode 100644 index 0000000000..5d5305671b --- /dev/null +++ b/ui/js/dfv/src/fields/website/test/index.js @@ -0,0 +1,71 @@ +/** + * External dependencies + */ +import { mount } from 'enzyme'; + +/** + * Internal dependencies + */ +import Website from '..'; + +const BASE_PROPS = { + value: '', + setValue: jest.fn(), + addValidationRules: jest.fn(), + setHasBlurred: jest.fn(), + fieldConfig: { + group: 'group/pod/_pods_pod/dfv-demo', + id: 'some_id', + label: 'Test Website Field', + name: 'test_website_field', + object_type: 'field', + parent: 'pod/_pods_pod', + type: 'website', + }, +}; + +describe( 'Website field component', () => { + it( 'creates a text field if the HTML5 website option is not set', () => { + const props = { ...BASE_PROPS }; + + const wrapper = mount( ); + + expect( + wrapper.find( 'input' ).props().type + ).toBe( 'text' ); + } ); + + it( 'applies the relevant attributes to the input field', () => { + const props = { + ...BASE_PROPS, + fieldConfig: { + ...BASE_PROPS.fieldConfig, + website_html5: true, + website_max_length: 20, + website_placeholder: 'Some placeholder for the field', + }, + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ); + + expect( input.props().type ).toEqual( 'url' ); + expect( input.props().maxLength ).toEqual( 20 ); + expect( input.props().placeholder ).toEqual( 'Some placeholder for the field' ); + } ); + + it( 'calls the setValue callback once updated', () => { + const props = { + ...BASE_PROPS, + setValue: jest.fn(), + }; + + const wrapper = mount( ); + const input = wrapper.find( 'input' ).first(); + input.simulate( 'change', { + target: { value: 'https://pods.io' }, + } ); + + expect( props.setValue ).toHaveBeenCalledWith( 'https://pods.io' ); + } ); +} ); diff --git a/ui/js/dfv/src/fields/wysiwyg/index.js b/ui/js/dfv/src/fields/wysiwyg/index.js new file mode 100644 index 0000000000..df93392fe8 --- /dev/null +++ b/ui/js/dfv/src/fields/wysiwyg/index.js @@ -0,0 +1,86 @@ +import React from 'react'; +import ReactQuill from 'react-quill'; +import PropTypes from 'prop-types'; + +import TinyMCE from './tinymce'; + +import { toBool } from 'dfv/src/helpers/booleans'; +import { FIELD_COMPONENT_BASE_PROPS } from 'dfv/src/config/prop-types'; + +import 'react-quill/dist/quill.snow.css'; +import './wysiwyg.scss'; + +const QUILL_TOOLBAR_OPTIONS = [ + [ 'bold', 'italic', 'underline', 'strike' ], + [ 'blockquote', 'code-block' ], + + [ { header: 1 }, { header: 2 } ], + [ { list: 'ordered' }, { list: 'bullet' } ], + [ { script: 'sub' }, { script: 'super' } ], + [ { indent: '-1' }, { indent: '+1' } ], + + [ { header: [ 1, 2, 3, 4, 5, 6, false ] } ], + + [ { color: [] }, { background: [] } ], + [ { align: [] } ], + + [ 'clean' ], +]; + +const Wysiwyg = ( props ) => { + const { + fieldConfig = {}, + setValue, + value, + setHasBlurred, + } = props; + + const { + htmlAttr: htmlAttributes = {}, + name, + wysiwyg_editor: editor = 'tinymce', + wysiwyg_editor_height: editorHeight = 400, + wysiwyg_media_buttons: mediaButtons, + } = fieldConfig; + + if ( 'quill' === editor || 'cleditor' === editor ) { + // The "theme" option supports: snow (CLEditor-like) | bubble (simple barebones WYSIWYG). + return ( + <> + setHasBlurred() } + onChange={ setValue } + theme="snow" + modules={ { + toolbar: QUILL_TOOLBAR_OPTIONS, + } } + /> + + + + ); + } + + return ( + setHasBlurred() } + /> + ); +}; + +Wysiwyg.propTypes = { + ...FIELD_COMPONENT_BASE_PROPS, + value: PropTypes.string, +}; + +export default Wysiwyg; diff --git a/ui/js/dfv/src/fields/wysiwyg/tinymce.js b/ui/js/dfv/src/fields/wysiwyg/tinymce.js new file mode 100644 index 0000000000..daeb634b6a --- /dev/null +++ b/ui/js/dfv/src/fields/wysiwyg/tinymce.js @@ -0,0 +1,160 @@ +import React, { useEffect, useRef } from 'react'; +import { debounce } from 'lodash'; +import PropTypes from 'prop-types'; + +import { F10, isKeyboardEvent } from '@wordpress/keycodes'; + +// Based on the core Freeform block's edit component, see: +// https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/freeform/edit.js +const TinyMCE = ( { + name, + value, + setValue, + editorHeight, + mediaButtons, + onBlur, +} ) => { + const fieldId = `pods-form-ui-${ name }`; + + const didMount = useRef( false ); + + useEffect( () => { + if ( ! didMount.current ) { + return; + } + + const editor = window.tinymce.get( fieldId ); + const currentContent = editor?.getContent(); + + if ( currentContent !== value ) { + editor.setContent( value || '' ); + } + }, [ value ] ); + + useEffect( () => { + const { baseURL, suffix } = window.wpEditorL10n.tinymce; + + window.tinymce.EditorManager.overrideDefaults( { + base_url: baseURL, + suffix, + } ); + + function onSetup( editor ) { + if ( ! didMount.current ) { + return; + } + + if ( value ) { + editor.on( 'loadContent', () => editor.setContent( value ) ); + } + + editor.on( 'blur', () => { + setValue( editor.getContent() ); + + onBlur(); + } ); + + const debouncedOnChange = debounce( () => { + const newValue = editor.getContent(); + + if ( newValue !== editor._lastChange ) { + editor._lastChange = value; + setValue( newValue ); + } + }, 250 ); + editor.on( 'Paste Change input Undo Redo', debouncedOnChange ); + + // We need to cancel the debounce call because when we remove + // the editor (onUnmount) this callback is executed in + // another tick. This results in setting the content to empty. + editor.on( 'remove', debouncedOnChange.cancel ); + + editor.on( 'keydown', ( event ) => { + if ( isKeyboardEvent.primary( event, 'z' ) ) { + // Prevent the gutenberg undo kicking in so TinyMCE undo stack works as expected + event.stopPropagation(); + } + + const { altKey } = event; + /* + * Prevent Mousetrap from kicking in: TinyMCE already uses its own + * `alt+f10` shortcut to focus its toolbar. + */ + if ( altKey && event.keyCode === F10 ) { + event.stopPropagation(); + } + } ); + + didMount.current = true; + } + + function initialize() { + const { settings } = window.wpEditorL10n.tinymce; + + // Remove the media button from the TinyMCE toolbars if found. + if ( ! mediaButtons ) { + settings.toolbar1 = settings.toolbar1.replace( 'wp_add_media,', '' ).replace( ',wp_add_media', '' ).replace( 'wp_add_media', '' ); + settings.toolbar2 = settings.toolbar2.replace( 'wp_add_media,', '' ).replace( ',wp_add_media', '' ).replace( 'wp_add_media', '' ); + settings.toolbar3 = settings.toolbar3.replace( 'wp_add_media,', '' ).replace( ',wp_add_media', '' ).replace( 'wp_add_media', '' ); + settings.toolbar4 = settings.toolbar4.replace( 'wp_add_media,', '' ).replace( ',wp_add_media', '' ).replace( 'wp_add_media', '' ); + } + + window.wp.oldEditor.initialize( fieldId, { + tinymce: { + ...settings, + content_css: false, + setup: onSetup, + height: editorHeight, + }, + mediaButtons, + quicktags: true, + } ); + } + + function onReadyStateChange() { + if ( document.readyState === 'complete' ) { + initialize(); + } + } + + if ( document.readyState === 'complete' ) { + initialize(); + } else { + document.addEventListener( 'readystatechange', onReadyStateChange ); + } + + return () => { + document.removeEventListener( + 'readystatechange', + onReadyStateChange + ); + wp.oldEditor.remove( fieldId ); + }; + }, [ mediaButtons ] ); + + return ( +
          + - -

          - -
          -
          - - - -

          - -
          - -
          - - -
          - - -
          - - - - - -
          -
          -
          -
          - - -
          - 'affiliation', - 'module_id' => $module_id, - 'module_slug' => $slug, - 'module_version' => $fs->get_plugin_version(), - ); - fs_require_template( 'powered-by.php', $params ); -?> \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/data-debug-mode.php b/vendor/freemius/wordpress-sdk/templates/forms/data-debug-mode.php deleted file mode 100644 index 44cb44213d..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/data-debug-mode.php +++ /dev/null @@ -1,213 +0,0 @@ -get_slug(); - $unique_affix = $fs->get_unique_affix(); - $last_license_user_id = $fs->get_last_license_user_id(); - $has_last_license_user_id = FS_User::is_valid_id( $last_license_user_id ); - - $message_above_input_field = ( ! $has_last_license_user_id ) ? - fs_text_inline( 'Please enter the license key to enable the debug mode:', 'submit-developer-license-key-message', $slug ) : - sprintf( - fs_text_inline( 'To enter the debug mode, please enter the secret key of the license owner (UserID = %d), which you can find in your "My Profile" section of your User Dashboard:', 'submit-addon-developer-key-message', $slug ), - $last_license_user_id - ); - - $processing_text = ( fs_esc_js_inline( 'Processing', 'processing', $slug ) . '...' ); - $submit_button_text = fs_text_inline( 'Submit', 'submit', $slug ); - $debug_license_link_text = fs_esc_html_inline( 'Start Debug', 'start-debug-license', $slug ); - $license_or_user_key_text = ( ! $has_last_license_user_id ) ? - fs_text_inline( 'License key', 'license-key' , $slug ) : - fs_text_inline( 'User key', 'user-key' , $slug ); - $input_html = ""; - - $modal_content_html = <<< HTML -

          -

          {$message_above_input_field}

          - {$input_html} -HTML; - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/deactivation/contact.php b/vendor/freemius/wordpress-sdk/templates/forms/deactivation/contact.php deleted file mode 100644 index 24d67e723b..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/deactivation/contact.php +++ /dev/null @@ -1,23 +0,0 @@ -get_slug(); - - echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug ) - . sprintf(" %s", - $fs->contact_url( 'technical_support' ), - fs_text_inline( 'Contact Support', 'contact-support', $slug ) - ); diff --git a/vendor/freemius/wordpress-sdk/templates/forms/deactivation/form.php b/vendor/freemius/wordpress-sdk/templates/forms/deactivation/form.php deleted file mode 100755 index 0bdcae01f1..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/deactivation/form.php +++ /dev/null @@ -1,543 +0,0 @@ -get_slug(); - - $subscription_cancellation_dialog_box_template_params = $VARS['subscription_cancellation_dialog_box_template_params']; - $show_deactivation_feedback_form = $VARS['show_deactivation_feedback_form']; - $confirmation_message = $VARS['uninstall_confirmation_message']; - - $is_anonymous = ( ! $fs->is_registered() ); - $anonymous_feedback_checkbox_html = ''; - - $reasons_list_items_html = ''; - - if ( $show_deactivation_feedback_form ) { - $reasons = $VARS['reasons']; - - foreach ( $reasons as $reason ) { - $list_item_classes = 'reason' . ( ! empty( $reason['input_type'] ) ? ' has-input' : '' ); - - if ( isset( $reason['internal_message'] ) && ! empty( $reason['internal_message'] ) ) { - $list_item_classes .= ' has-internal-message'; - $reason_internal_message = $reason['internal_message']; - } else { - $reason_internal_message = ''; - } - - $reason_input_type = ( ! empty( $reason['input_type'] ) ? $reason['input_type'] : '' ); - $reason_input_placeholder = ( ! empty( $reason['input_placeholder'] ) ? $reason['input_placeholder'] : '' ); - - $reason_list_item_html = <<< HTML -
        • - -
          {$reason_internal_message}
          -
        • -HTML; - - $reasons_list_items_html .= $reason_list_item_html; - } - - if ( $is_anonymous ) { - $anonymous_feedback_checkbox_html = sprintf( - '', - fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug ) - ); - } - } - - // Aliases. - $deactivate_text = fs_text_inline( 'Deactivate', 'deactivate', $slug ); - $theme_text = fs_text_inline( 'Theme', 'theme', $slug ); - $activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug ); - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); - - if ( ! empty( $subscription_cancellation_dialog_box_template_params ) ) { - fs_require_template( 'forms/subscription-cancellation.php', $subscription_cancellation_dialog_box_template_params ); - } -?> - diff --git a/vendor/freemius/wordpress-sdk/templates/forms/deactivation/index.php b/vendor/freemius/wordpress-sdk/templates/forms/deactivation/index.php deleted file mode 100644 index 0316c6a618..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/deactivation/index.php +++ /dev/null @@ -1,3 +0,0 @@ -get_slug(); - - $skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' ); - $skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) ); - $use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug ); - - echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "{$skip_text}" ) - . " {$use_plugin_anonymously_text}"; \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/index.php b/vendor/freemius/wordpress-sdk/templates/forms/index.php deleted file mode 100644 index 0316c6a618..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/index.php +++ /dev/null @@ -1,3 +0,0 @@ -get_slug(); - $unique_affix = $fs->get_unique_affix(); - - $cant_find_license_key_text = fs_text_inline( "Can't find your license key?", 'cant-find-license-key', $slug ); - $message_above_input_field = fs_text_inline( 'Please enter the license key that you received in the email right after the purchase:', 'activate-license-message', $slug ); - $message_below_input_field = ''; - - $header_title = $fs->is_free_plan() ? - fs_text_inline( 'Activate License', 'activate-license', $slug ) : - fs_text_inline( 'Update License', 'update-license', $slug ); - - if ( $fs->is_registered() ) { - $activate_button_text = $header_title; - } else { - $freemius_site_url = $fs->has_paid_plan() ? - 'https://freemius.com/' : - // Insights platform information. - $fs->get_usage_tracking_terms_url(); - - $freemius_link = 'freemius.com'; - - $message_below_input_field = sprintf( - fs_text_inline( 'The %1$s will be periodically sending data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ), - $fs->get_module_label( true ), - $freemius_link - ); - - $activate_button_text = fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug ); - } - - $license_key_text = fs_text_inline( 'License key', 'license-key' , $slug ); - - $is_network_activation = ( - $fs->is_network_active() && - fs_is_network_admin() && - ! $fs->is_delegated_connection() - ); - $network_activation_html = ''; - - $sites_details = array(); - if ( $is_network_activation ) { - $all_sites = Freemius::get_sites(); - - foreach ( $all_sites as $site ) { - $site_details = $fs->get_site_info( $site ); - - $blog_id = Freemius::get_site_blog_id( $site ); - $install = $fs->get_install_by_blog_id($blog_id); - - if ( is_object( $install ) && FS_Plugin_License::is_valid_id( $install->license_id ) ) { - $site_details['license_id'] = $install->license_id; - } - - $sites_details[] = $site_details; - } - - if ( $is_network_activation ) { - $vars = array( - 'id' => $fs->get_id(), - 'sites' => $sites_details, - 'require_license_key' => true - ); - - $network_activation_html = fs_get_template( 'partials/network-activation.php', $vars ); - } - } - - $premium_licenses = $fs->get_available_premium_licenses(); - $available_licenses = array(); - foreach ( $premium_licenses as $premium_license ) { - $activations_left = $premium_license->left(); - if ( ! ( $activations_left > 0 ) ) { - continue; - } - - $available_licenses[ $activations_left . '_' . $premium_license->id ] = $premium_license; - } - - $total_available_licenses = count( $available_licenses ); - if ( $total_available_licenses > 0 ) { - $license_input_html = <<< HTML -
          - - - - - - - - - - - -
          -HTML; - - if ( $total_available_licenses > 1 ) { - // Sort the licenses by number of activations left in descending order. - krsort( $available_licenses ); - - $license_input_html .= ''; - } else { - $available_licenses = array_values( $available_licenses ); - - /** - * @var FS_Plugin_License $available_license - */ - $available_license = $available_licenses[0]; - $value = sprintf( - "%s-Site %s License - %s", - ( 1 == $available_license->quota ? - 'Single' : - ( $available_license->is_unlimited() ? 'Unlimited' : $available_license->quota ) - ), - $fs->_get_plan_by_id( $available_license->plan_id )->title, - $available_license->get_html_escaped_masked_secret_key() - ); - - $license_input_html .= <<< HTML - -HTML; - } - - $license_input_html .= <<< HTML -
          - -
          - -
          -
          -
          -HTML; - } else { - $license_input_html = ""; - } - - $ownership_change_option_text = fs_text_inline( "Associate with the license owner's account.", 'associate-account-with-license-owner', $slug ); - $ownership_change_option_html = ""; - - /** - * IMPORTANT: - * DO NOT ADD MAXLENGTH OR LIMIT THE LICENSE KEY LENGTH SINCE - * WE DO WANT TO ALLOW INPUT OF LONGER KEYS (E.G. WooCommerce Keys) - * FOR MIGRATED MODULES. - */ - $modal_content_html = <<< HTML -

          -

          {$message_above_input_field}

          - {$license_input_html} - {$cant_find_license_key_text} - {$network_activation_html} -

          {$message_below_input_field}

          - {$ownership_change_option_html} -HTML; - - /** - * Handle the ownership change option if not an add-on or if no license yet is activated for the - * parent product in case of an add-on. - * - * @author Leo Fajardo (@leorw) - * @since 2.3.2 - */ - $is_user_change_supported = ( ! $fs->is_addon() || ! $fs->get_parent_instance()->has_active_valid_license() ); - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/optout.php b/vendor/freemius/wordpress-sdk/templates/forms/optout.php deleted file mode 100644 index 4867a8a73a..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/optout.php +++ /dev/null @@ -1,336 +0,0 @@ -get_slug(); - - $action = $fs->is_tracking_allowed() ? - 'stop_tracking' : - 'allow_tracking'; - - $reconnect_url = $fs->get_activation_url( array( - 'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ), - 'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ), - ) ); - - $plugin_title = "{$fs->get_plugin()->title}"; - $opt_out_text = fs_text_x_inline( 'Opt Out', 'verb', 'opt-out', $slug ); - $opt_in_text = fs_text_x_inline( 'Opt In', 'verb', 'opt-in', $slug ); - - if ( $fs->is_premium() ) { - $opt_in_message_appreciation = fs_text_inline( 'Connectivity to the licensing engine was successfully re-established. Automatic security & feature updates are now available through the WP Admin Dashboard.', 'premium-opt-in-message-appreciation', $slug ); - - $opt_out_message_subtitle = sprintf( fs_text_inline( 'Warning: Opting out will block automatic updates', 'premium-opt-out-message-appreciation', $slug ), $fs->get_module_type() ); - $opt_out_message_usage_tracking = sprintf( fs_text_inline( 'Ongoing connectivity with the licensing engine is essential for receiving automatic security & feature updates of the paid product. To receive these updates, data like your license key, %1$s version, and WordPress version, is periodically sent to the server to check for updates. By opting out, you understand that your site won\'t receive automatic updates for %2$s from within the WP Admin Dashboard. This can put your site at risk, and we highly recommend to keep this connection active. If you do choose to opt-out, you\'ll need to check for %1$s updates and install them manually.', 'premium-opt-out-message-usage-tracking', $slug ), $fs->get_module_type(), $plugin_title ); - - $primary_cta_label = fs_text_inline( 'I\'d like to keep automatic updates', 'premium-opt-out-cancel', $slug ); - } else { - $opt_in_message_appreciation = sprintf( fs_text_inline( 'We appreciate your help in making the %s better by letting us track some usage data.', 'opt-in-message-appreciation', $slug ), $fs->get_module_type() ); - - $opt_out_message_subtitle = $opt_in_message_appreciation; - $opt_out_message_usage_tracking = sprintf( fs_text_inline( "Usage tracking is done in the name of making %s better. Making a better user experience, prioritizing new features, and more good things. We'd really appreciate if you'll reconsider letting us continue with the tracking.", 'opt-out-message-usage-tracking', $slug ), $plugin_title ); - $primary_cta_label = fs_text_inline( 'On second thought - I want to continue helping', 'opt-out-cancel', $slug ); - } - - $opt_out_message_clicking_opt_out = sprintf( - fs_text_inline( 'By clicking "Opt Out", we will no longer be sending any data from %s to %s.', 'opt-out-message-clicking-opt-out', $slug ), - $plugin_title, - sprintf( - '%s', - 'https://freemius.com', - 'freemius.com' - ) - ); - - $admin_notice_params = array( - 'id' => '', - 'slug' => $fs->get_id(), - 'type' => 'success', - 'sticky' => false, - 'plugin' => $fs->get_plugin()->title, - 'message' => $opt_in_message_appreciation - ); - - $admin_notice_html = fs_get_template( 'admin-notice.php', $admin_notice_params ); - - $modal_content_html = " - is_premium() ? ' style="color: red"' : '' ) . ">{$opt_out_message_subtitle} -

          -

          {$opt_out_message_usage_tracking}

          -

          {$opt_out_message_clicking_opt_out}

          - "; - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); - fs_enqueue_local_style( 'fs_common', '/admin/common.css' ); -?> - diff --git a/vendor/freemius/wordpress-sdk/templates/forms/premium-versions-upgrade-handler.php b/vendor/freemius/wordpress-sdk/templates/forms/premium-versions-upgrade-handler.php deleted file mode 100644 index f30639bfa9..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/premium-versions-upgrade-handler.php +++ /dev/null @@ -1,205 +0,0 @@ -get_slug(); - - $plugin_data = $fs->get_plugin_data(); - $plugin_name = $plugin_data['Name']; - $plugin_basename = $fs->get_plugin_basename(); - - $license = $fs->_get_license(); - - if ( ! is_object( $license ) ) { - $purchase_url = $fs->pricing_url(); - } else { - $subscription = $fs->_get_subscription( $license->id ); - - $purchase_url = $fs->checkout_url( - is_object( $subscription ) ? - ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) : - WP_FS__PERIOD_LIFETIME, - false, - array( 'licenses' => $license->quota ) - ); - } - - $message = sprintf( - fs_text_inline( 'There is a new version of %s available.', 'new-version-available-message', $slug ) . - fs_text_inline( ' %s to access version %s security & feature updates, and support.', 'x-for-updates-and-support', $slug ), - '', - sprintf( - '%s', - is_object( $license ) ? - fs_text_inline( 'Renew your license now', 'renew-license-now', $slug ) : - fs_text_inline( 'Buy a license now', 'buy-license-now', $slug ) - ), - '' - ); - - $modal_content_html = "

          {$message}

          "; - - $header_title = fs_text_inline( 'New Version Available', 'new-version-available', $slug ); - - $renew_license_button_text = is_object( $license ) ? - fs_text_inline( 'Renew license', 'renew-license', $slug ) : - fs_text_inline( 'Buy license', 'buy-license', $slug ); - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/premium-versions-upgrade-metadata.php b/vendor/freemius/wordpress-sdk/templates/forms/premium-versions-upgrade-metadata.php deleted file mode 100644 index 5f9fddd9dd..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/premium-versions-upgrade-metadata.php +++ /dev/null @@ -1,47 +0,0 @@ -_get_license(); - - if ( ! is_object( $license ) ) { - $purchase_url = $fs->pricing_url(); - } else { - $subscription = $fs->_get_subscription( $license->id ); - - $purchase_url = $fs->checkout_url( - is_object( $subscription ) ? - ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) : - WP_FS__PERIOD_LIFETIME, - false, - array( 'licenses' => $license->quota ) - ); - } - - $plugin_data = $fs->get_plugin_data(); -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/resend-key.php b/vendor/freemius/wordpress-sdk/templates/forms/resend-key.php deleted file mode 100644 index f8cafb99d2..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/resend-key.php +++ /dev/null @@ -1,247 +0,0 @@ -get_slug(); - - $send_button_text = fs_text_inline( 'Send License Key', 'send-license-key', $slug ); - $cancel_button_text = fs_text_inline( 'Cancel', 'cancel', $slug ); - $email_address_placeholder = fs_esc_attr_inline( 'Email address', 'email-address', $slug ); - $other_text = fs_text_inline( 'Other', 'other', $slug ); - - $is_freemium = $fs->is_freemium(); - - $send_button_text_html = esc_html($send_button_text); - - $button_html = <<< HTML - -HTML; - - if ( $is_freemium ) { - $current_user = Freemius::_get_current_wp_user(); - $email = $current_user->user_email; - $esc_email = esc_attr( $email ); - $form_html = <<< HTML - -{$button_html} -HTML; - } else { - $email = ''; - $form_html = <<< HTML -{$button_html} - -HTML; - } - - $message_above_input_field = fs_esc_html_inline( "Enter the email address you've used for the upgrade below and we will resend you the license key.", 'ask-for-upgrade-email-address', $slug ); - $modal_content_html = <<< HTML -

          -

          {$message_above_input_field}

          -
          - {$form_html} -
          -HTML; - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - diff --git a/vendor/freemius/wordpress-sdk/templates/forms/subscription-cancellation.php b/vendor/freemius/wordpress-sdk/templates/forms/subscription-cancellation.php deleted file mode 100644 index 2a1d591107..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/subscription-cancellation.php +++ /dev/null @@ -1,277 +0,0 @@ -get_slug(); - -/** - * @var FS_Plugin_License $license - */ -$license = $VARS['license']; - -$has_trial = $VARS['has_trial']; - -$subscription_cancellation_context = $has_trial ? - fs_text_inline( 'trial', 'trial', $slug ) : - fs_text_inline( 'subscription', 'subscription', $slug ); - -$plan = $fs->get_plan(); -$module_label = $fs->get_module_label( true ); - -if ( $VARS['is_license_deactivation'] ) { - $subscription_cancellation_text = ''; -} else { - $subscription_cancellation_text = sprintf( - fs_text_inline( - "Deactivating or uninstalling the %s will automatically disable the license, which you'll be able to use on another site.", - 'deactivation-or-uninstall-message', - $slug - ), - $module_label - ) . ' '; -} - - $subscription_cancellation_text .= sprintf( - fs_text_inline( - 'In case you are NOT planning on using this %s on this site (or any other site) - would you like to cancel the %s as well?', - 'cancel-subscription-message', - $slug - ), - ( $VARS['is_license_deactivation'] ? fs_text_inline( 'license', 'license', $slug ) : $module_label ), - $subscription_cancellation_context -); - -$cancel_subscription_action_label = sprintf( - fs_esc_html_inline( - "Cancel %s - I no longer need any security & feature updates, nor support for %s because I'm not planning to use the %s on this, or any other site.", - 'cancel-x', - $slug - ), - esc_html( $subscription_cancellation_context ), - sprintf( '%s', esc_html( $fs->get_plugin_title() ) ), - esc_html( $module_label ) -); - -$keep_subscription_active_action_label = esc_html( sprintf( - fs_text_inline( - "Don't cancel %s - I'm still interested in getting security & feature updates, as well as be able to contact support.", - 'dont-cancel-x', - $slug - ), - $subscription_cancellation_context -) ); - -$subscription_cancellation_text = esc_html( $subscription_cancellation_text ); - -$subscription_cancellation_html = <<< HTML -

          {$subscription_cancellation_text}

          -
            -
          • - -
          • -
          • - -
          • -
          -HTML; - -$downgrading_plan_text = fs_text_inline( 'Downgrading your plan', 'downgrading-plan', $slug ); -$cancelling_subscription_text = fs_text_inline( 'Cancelling the subscription', 'cancelling-subscription', $slug ); -/* translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription' */ -$downgrade_x_confirm_text = fs_text_inline( '%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s.', 'downgrade-x-confirm', $slug ); -$prices_increase_text = fs_text_inline( 'Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price.', 'pricing-increase-warning', $slug ); -$after_downgrade_non_blocking_text = fs_text_inline( 'You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support.', 'after-downgrade-non-blocking', $slug ); -$after_downgrade_blocking_text = fs_text_inline( 'Once your license expires you can still use the Free version but you will NOT have access to the %s features.', 'after-downgrade-blocking', $slug ); -$after_downgrade_blocking_text_premium_only = fs_text_inline( 'Once your license expires you will no longer be able to use the %s, unless you activate it again with a valid premium license.', 'after-downgrade-blocking-premium-only', $slug ); - -$subscription_cancellation_confirmation_message = $has_trial ? - fs_text_inline( 'Cancelling the trial will immediately block access to all premium features. Are you sure?', 'cancel-trial-confirm', $slug ) : - sprintf( - '%s %s %s %s', - sprintf( - $downgrade_x_confirm_text, - ($fs->is_only_premium() ? $cancelling_subscription_text : $downgrading_plan_text ), - $plan->title, - human_time_diff( time(), strtotime( $license->expiration ) ) - ), - ( - $license->is_block_features ? - ( - $fs->is_only_premium() ? - sprintf( $after_downgrade_blocking_text_premium_only, $module_label ) : - sprintf( $after_downgrade_blocking_text, $plan->title ) - ) : - sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs->get_module_label( true ) ) - ), - $prices_increase_text, - fs_esc_attr_inline( 'Are you sure you want to proceed?', 'proceed-confirmation', $slug ) - ); - -fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/forms/trial-start.php b/vendor/freemius/wordpress-sdk/templates/forms/trial-start.php deleted file mode 100644 index b66e72724b..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/trial-start.php +++ /dev/null @@ -1,181 +0,0 @@ -get_slug(); - - $message_header = sprintf( - /* translators: %1$s: Number of trial days; %2$s: Plan name; */ - fs_text_inline( 'You are 1-click away from starting your %1$s-day free trial of the %2$s plan.', 'start-trial-prompt-header', $slug ), - '', - '' - ); - $message_content = sprintf( - /* translators: %s: Link to freemius.com */ - fs_text_inline( 'For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial.', 'start-trial-prompt-message', $slug ), - $fs->get_module_type(), - sprintf( - '%s', - 'https://freemius.com', - 'freemius.com' - ) - ); - - $modal_content_html = <<< HTML -

          -

          {$message_header}

          -

          {$message_content}

          -HTML; - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - diff --git a/vendor/freemius/wordpress-sdk/templates/forms/user-change.php b/vendor/freemius/wordpress-sdk/templates/forms/user-change.php deleted file mode 100644 index 3571b838d5..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/forms/user-change.php +++ /dev/null @@ -1,296 +0,0 @@ -get_slug(); - - /** - * @var object[] $license_owners - */ - $license_owners = $VARS['license_owners']; - - $change_user_message = fs_text_inline( 'By changing the user, you agree to transfer the account ownership to:', 'change-user--message', $slug ); - $header_title = fs_text_inline( 'Change User', 'change-user', $slug ); - $user_change_button_text = fs_text_inline( 'I Agree - Change User', 'agree-change-user', $slug ); - $other_text = fs_text_inline( 'Other', 'other', $slug ); - $enter_email_address_placeholder_text = fs_text_inline( 'Enter email address', 'enter-email-address', $slug ); - - $user_change_options_html = <<< HTML -
          - - -HTML; - - foreach ( $license_owners as $license_owner ) { - $user_change_options_html .= <<< HTML - - - - -HTML; - } - - $user_change_options_html .= <<< HTML - - - - - -
          -
          - -
          - -
          -
          -
          -
          -HTML; - - $modal_content_html = <<< HTML -

          -

          {$change_user_message}

          - {$user_change_options_html} -HTML; - - fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); -?> - diff --git a/vendor/freemius/wordpress-sdk/templates/gdpr-optin-js.php b/vendor/freemius/wordpress-sdk/templates/gdpr-optin-js.php deleted file mode 100644 index 4fdc5e38a2..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/gdpr-optin-js.php +++ /dev/null @@ -1,66 +0,0 @@ - - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/index.php b/vendor/freemius/wordpress-sdk/templates/index.php deleted file mode 100644 index 0316c6a618..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/index.php +++ /dev/null @@ -1,3 +0,0 @@ - - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/js/open-license-activation.php b/vendor/freemius/wordpress-sdk/templates/js/open-license-activation.php deleted file mode 100644 index a88e6f9eb2..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/js/open-license-activation.php +++ /dev/null @@ -1,37 +0,0 @@ - - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/js/style-premium-theme.php b/vendor/freemius/wordpress-sdk/templates/js/style-premium-theme.php deleted file mode 100644 index 942da64fec..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/js/style-premium-theme.php +++ /dev/null @@ -1,53 +0,0 @@ -get_slug(); - -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/partials/index.php b/vendor/freemius/wordpress-sdk/templates/partials/index.php deleted file mode 100644 index cd6990e245..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/partials/index.php +++ /dev/null @@ -1,2 +0,0 @@ -get_slug(); - - $sites = $VARS['sites']; - $require_license_key = $VARS['require_license_key']; - - $show_delegation_option = $fs->apply_filters( 'show_delegation_option', true ); - $enable_per_site_activation = $fs->apply_filters( 'enable_per_site_activation', true ); -?> -|' ?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/plugin-icon.php b/vendor/freemius/wordpress-sdk/templates/plugin-icon.php deleted file mode 100644 index ab0fb54e5d..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/plugin-icon.php +++ /dev/null @@ -1,20 +0,0 @@ - -
          - -
          \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/plugin-info/description.php b/vendor/freemius/wordpress-sdk/templates/plugin-info/description.php deleted file mode 100644 index 26bc67b47a..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/plugin-info/description.php +++ /dev/null @@ -1,78 +0,0 @@ -info->selling_point_0 ) || - ! empty( $plugin->info->selling_point_1 ) || - ! empty( $plugin->info->selling_point_2 ) - ) : ?> -
          -
            - - info->{'selling_point_' . $i} ) ) : ?> -
          • - -

            info->{'selling_point_' . $i} ) ?>

          • - - -
          -
          - -
          - info->description, array( - 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ), - 'b' => array(), - 'i' => array(), - 'p' => array(), - 'blockquote' => array(), - 'h2' => array(), - 'h3' => array(), - 'ul' => array(), - 'ol' => array(), - 'li' => array() - ) ); - ?> -
          -info->screenshots ) ) : ?> - info->screenshots ?> -
          -

          slug ) ?>

          -
            - $url ) : ?> - -
          • - - -
          • - -
          -
          - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/plugin-info/features.php b/vendor/freemius/wordpress-sdk/templates/plugin-info/features.php deleted file mode 100644 index b3d0fc8b3e..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/plugin-info/features.php +++ /dev/null @@ -1,114 +0,0 @@ -features) && is_array($plan->features)) { - foreach ( $plan->features as $feature ) { - if ( ! isset( $features_plan_map[ $feature->id ] ) ) { - $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); - } - - $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; - } - } - - // Add support as a feature. - if ( ! empty( $plan->support_email ) || - ! empty( $plan->support_skype ) || - ! empty( $plan->support_phone ) || - true === $plan->is_success_manager - ) { - if ( ! isset( $features_plan_map['support'] ) ) { - $support_feature = new stdClass(); - $support_feature->id = 'support'; - $support_feature->title = fs_text_inline( 'Support', $plugin->slug ); - $features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() ); - } else { - $support_feature = $features_plan_map['support']; - } - - $features_plan_map[ $support_feature->id ]['plans'][ $plan->id ] = $support_feature; - } - } - - // Add updates as a feature for all plans. - $updates_feature = new stdClass(); - $updates_feature->id = 'updates'; - $updates_feature->title = fs_text_inline( 'Unlimited Updates', 'unlimited-updates', $plugin->slug ); - $features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() ); - foreach ( $plans as $plan ) { - $features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature; - } -?> -
          - - - - - - - - - - - $data ) : ?> - - - - - - - - -
          - title ?> - pricing ) ) { - fs_esc_html_echo_inline( 'Free', 'free', $plugin->slug ); - } else { - foreach ( $plan->pricing as $pricing ) { - /** - * @var FS_Pricing $pricing - */ - if ( 1 == $pricing->licenses ) { - if ( $pricing->has_annual() ) { - echo "\${$pricing->annual_price} / " . fs_esc_html_x_inline( 'year', 'as annual period', 'year', $plugin->slug ); - } else if ( $pricing->has_monthly() ) { - echo "\${$pricing->monthly_price} / " . fs_esc_html_x_inline( 'mo', 'as monthly period', 'mo', $plugin->slug ); - } else { - echo "\${$pricing->lifetime_price}"; - } - } - } - } - ?> -
          title ) ) ?> - id ] ) ) : ?> - id ]->value ) ) : ?> - id ]->value ) ?> - - - - -
          -
          \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/plugin-info/index.php b/vendor/freemius/wordpress-sdk/templates/plugin-info/index.php deleted file mode 100644 index 0316c6a618..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/plugin-info/index.php +++ /dev/null @@ -1,3 +0,0 @@ - -
            - $url ) : ?> - -
          1. - -
          2. - -
          diff --git a/vendor/freemius/wordpress-sdk/templates/powered-by.php b/vendor/freemius/wordpress-sdk/templates/powered-by.php deleted file mode 100755 index bb6e081c1a..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/powered-by.php +++ /dev/null @@ -1,61 +0,0 @@ - -is_whitelabeled() ) : ?> -
          - - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/pricing.php b/vendor/freemius/wordpress-sdk/templates/pricing.php deleted file mode 100644 index 469f300594..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/pricing.php +++ /dev/null @@ -1,209 +0,0 @@ -get_slug(); - $timestamp = time(); - - $context_params = array( - 'plugin_id' => $fs->get_id(), - 'plugin_public_key' => $fs->get_public_key(), - 'plugin_version' => $fs->get_plugin_version(), - ); - - $bundle_id = $fs->get_bundle_id(); - if ( ! is_null( $bundle_id ) ) { - $context_params['bundle_id'] = $bundle_id; - } - - // Get site context secure params. - if ( $fs->is_registered() ) { - $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( - $fs->get_site(), - $timestamp, - 'upgrade' - ) ); - } else { - $context_params['home_url'] = home_url(); - } - - if ( $fs->is_payments_sandbox() ) // Append plugin secure token for sandbox mode authentication.) - { - $context_params['sandbox'] = FS_Security::instance()->get_secure_token( - $fs->get_plugin(), - $timestamp, - 'checkout' - ); - } - - $query_params = array_merge( $context_params, $_GET, array( - 'next' => $fs->_get_sync_license_url( false, false ), - 'plugin_version' => $fs->get_plugin_version(), - // Billing cycle. - 'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ), - 'is_network_admin' => fs_is_network_admin() ? 'true' : 'false', - 'currency' => $fs->apply_filters( 'default_currency', 'usd' ), - ) ); - - $use_external_pricing = $fs->should_use_external_pricing(); - - if ( ! $use_external_pricing ) { - $pricing_js_url = fs_asset_url( $fs->get_pricing_js_path() ); - wp_enqueue_script( 'freemius-pricing', $pricing_js_url ); - } else { - if ( ! $fs->is_registered() ) { - $template_data = array( - 'id' => $fs->get_id(), - ); - fs_require_template( 'forms/trial-start.php', $template_data); - } - - $view_params = array( - 'id' => $VARS['id'], - 'page' => strtolower( $fs->get_text_x_inline( 'Pricing', 'noun', 'pricing' ) ), - ); - fs_require_once_template('secure-https-header.php', $view_params); - } - - $has_tabs = $fs->_add_tabs_before_content(); - - if ( $has_tabs ) { - $query_params['tabs'] = 'true'; - } -?> -
          - -
          - $fs->contact_url(), - 'is_network_admin' => fs_is_network_admin(), - 'is_production' => ( defined( 'WP_FS__IS_PRODUCTION_MODE' ) ? WP_FS__IS_PRODUCTION_MODE : null ), - 'menu_slug' => $fs->get_menu_slug(), - 'mode' => 'dashboard', - 'fs_wp_endpoint_url' => WP_FS__ADDRESS, - 'request_handler_url' => admin_url( - 'admin-ajax.php?' . http_build_query( array( - 'module_id' => $fs->get_id(), - 'action' => $fs->get_ajax_action( 'pricing_ajax_action' ), - 'security' => $fs->get_ajax_security( 'pricing_ajax_action' ) - ) ) - ), - 'selector' => '#fs_pricing_wrapper', - 'unique_affix' => $fs->get_unique_affix(), - ), $query_params ); - - wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' ); - ?> - -
          -
          - - - - - - -
          - - - -
          -_add_tabs_after_content(); - } - - $params = array( - 'page' => 'pricing', - 'module_id' => $fs->get_id(), - 'module_type' => $fs->get_module_type(), - 'module_slug' => $slug, - 'module_version' => $fs->get_plugin_version(), - ); - fs_require_template( 'powered-by.php', $params ); \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/secure-https-header.php b/vendor/freemius/wordpress-sdk/templates/secure-https-header.php deleted file mode 100644 index 3d0a81eb45..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/secure-https-header.php +++ /dev/null @@ -1,39 +0,0 @@ - -
          - - get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ), - $VARS['page'] - ) ) . - ' - ' . - sprintf( - '%s', - 'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION, - 'Freemius Inc. [US]' - ); - } - ?> -
          \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/sticky-admin-notice-js.php b/vendor/freemius/wordpress-sdk/templates/sticky-admin-notice-js.php deleted file mode 100755 index 028a9661ce..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/sticky-admin-notice-js.php +++ /dev/null @@ -1,39 +0,0 @@ - - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/tabs-capture-js.php b/vendor/freemius/wordpress-sdk/templates/tabs-capture-js.php deleted file mode 100644 index 236be3b9e7..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/tabs-capture-js.php +++ /dev/null @@ -1,63 +0,0 @@ -get_slug(); -?> - \ No newline at end of file diff --git a/vendor/freemius/wordpress-sdk/templates/tabs.php b/vendor/freemius/wordpress-sdk/templates/tabs.php deleted file mode 100644 index 2a20b70b57..0000000000 --- a/vendor/freemius/wordpress-sdk/templates/tabs.php +++ /dev/null @@ -1,190 +0,0 @@ -get_slug(); - - $menu_items = $fs->get_menu_items(); - - $show_settings_with_tabs = $fs->show_settings_with_tabs(); - - $tabs = array(); - foreach ( $menu_items as $priority => $items ) { - foreach ( $items as $item ) { - if ( ! $item['show_submenu'] ) { - $submenu_name = ('wp-support-forum' === $item['menu_slug']) ? - 'support' : - $item['menu_slug']; - - if ( 'pricing' === $submenu_name && ! $fs->is_pricing_page_visible() ) { - continue; - } - - if ( ! $show_settings_with_tabs || ! $fs->is_submenu_item_visible( $submenu_name, true ) ) { - continue; - } - } - - $url = $fs->_get_admin_page_url( $item['menu_slug'] ); - $title = $item['menu_title']; - - $tab = array( - 'label' => $title, - 'href' => $url, - 'slug' => $item['menu_slug'], - ); - - if ( 'pricing' === $item['menu_slug'] && $fs->is_in_trial_promotion() ) { - $tab['href'] .= '&trial=true'; - } - - $tabs[] = $tab; - } - } -?> - \ No newline at end of file diff --git a/webpack.common.js b/webpack.common.js new file mode 100644 index 0000000000..661805c5d3 --- /dev/null +++ b/webpack.common.js @@ -0,0 +1,69 @@ +const DependencyExtractionWebpackPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' ); + +const path = require( 'path' ); + +module.exports = { + entry: { + 'dfv/pods-dfv': './ui/js/dfv/src/pods-dfv.js', + 'blocks/pods-blocks-api': './ui/js/blocks/src/index.js', + }, + output: { + path: path.resolve( __dirname, 'ui/js' ), + filename: '[name].min.js', + }, + + externals: { + 'jquery': 'jQuery', + 'underscore': '_', + 'backbone': 'Backbone', + 'backbone.marionette': 'Marionette', + 'react': 'React', + 'react-dom': 'ReactDOM', + 'lodash': 'lodash', + }, + + resolve: { + extensions: [ '*', '.js', '.jsx' ], + modules: [ + 'node_modules', + path.resolve( __dirname, 'ui/js' ) + ], + }, + + module: { + rules: [ + { + test: /\.(js|jsx)$/, + exclude: /node_modules/, + use: [ 'babel-loader' ], + }, + { + test: /\.scss$/, + exclude: /node_modules/, + use: [ + // creates style nodes from JS strings + { loader: 'style-loader' }, + // translates CSS into CommonJS + { loader: 'css-loader' }, + // compiles Sass to CSS + { loader: 'sass-loader' }, + ], + }, + { + test: /\.css$/, + use: [ + // creates style nodes from JS strings + { loader: 'style-loader' }, + // translates CSS into CommonJS + { loader: 'css-loader' }, + ], + }, + ], + }, + + plugins: [ + new DependencyExtractionWebpackPlugin( { + outputFormat: 'json', + } ), + ], +}; diff --git a/webpack.dev.js b/webpack.dev.js new file mode 100644 index 0000000000..df440cbfee --- /dev/null +++ b/webpack.dev.js @@ -0,0 +1,9 @@ +const webpack = require( 'webpack' ); +const merge = require( 'webpack-merge' ); + +const common = require( './webpack.common.js' ); + +module.exports = merge( common, { + mode: 'development', + devtool: 'cheap-module-eval-source-map', +} ); diff --git a/webpack.prod.js b/webpack.prod.js new file mode 100644 index 0000000000..a86c3a9c29 --- /dev/null +++ b/webpack.prod.js @@ -0,0 +1,24 @@ +const webpack = require( 'webpack' ); +const merge = require( 'webpack-merge' ); +const Terser = require( 'terser-webpack-plugin' ); + +const common = require( './webpack.common.js' ); + +module.exports = merge( common, { + mode: 'production', + + optimization: { + minimizer: [ + new Terser( { + cache: true, + parallel: true, + sourceMap: false, // Must be set to true if using source-maps in production + terserOptions: { + output: { + comments: false, + } + } + } ), + ] + }, +} );